Jump to content

Search the Community

Showing results for 'make server ubuntu'.

  • Search By Author

Content Type


Forums

  • Announcements
    • Rules & Guidelines
    • Community News
    • Development News
    • Ragnarok News
    • Community Crowdfunding
  • Support & Releases
    • General
    • Scripting
    • Database
    • Source
    • Graphic Enhancements
    • Web
    • Client-side
    • Third Party
    • Projects
  • Discussion & Suggestions
    • Database Discussion
    • Script Discussion
    • Source Discussion
    • Renewal Discussion
    • Archives
  • Community
    • rAthena General
    • Arts & Writings
    • Off Topic
  • International Forums
    • Filipino Support
    • German Support
    • Indonesian/Malaysian Support
    • Portuguese Support
    • Russian Support (Русский)
    • Spanish Support

Categories

  • Server Resources
    • Server Managers/Editors
    • Scripts
    • Source Modifications
  • Web Resources
    • General Website Templates
    • Forum Templates
    • FluxCP Themes
    • FluxCP Addons
    • Other Web/CP Scripts
  • Graphics Resources
    • Sprites & Palettes
    • Maps & 3D Resources
    • Other Graphics
  • Client Resources
    • GRF Files
    • Client Tools
    • Spriting & Paletting Tools
    • Texture & Mapping Tools
    • Editors
    • Patchers

Categories

  • Low Rate
  • Mid Rate
  • High Rate
  • Super High Rate

Categories

  • Records Test
  • Complete Installation Guides
  • Client Guides
    • Data Folder
  • MySQL Guides
  • Database Guides
  • Map Guides

Categories

  • rAthena Forums
  • rAthena Development
  • FluxCP Development

Find results in...

Find results that contain...


Date Created

  • Start

    End


Last Updated

  • Start

    End


Filter by number of...

Joined

  • Start

    End


Group


Location


Server


Github


Discord


Interests


Website URL


Yahoo


Skype

  1. upack

    GW

    Please tell me how to make it GW version 1.0, not 2.0
  2. Deposit System Do your server has so many headgear? Usually after new headgear is released especially when the new one has better benefit, Previous Headgear used by Player is now useles right? This System is inspired on the ROM Adventure Book, Where Player can Deposit un-used Item, but Player will be still has benefited from it, instead lying around somewhere uselessly. Video Deposit System.mp4
  3. Hello. client 4Cram i have already run start server. set char_name_option: 2 and in sclientinfo.xml already set to thai. can typing other language. i can create other language. but when i creating other language ragexe seem to be stuck. i have to exit and login again. so i can play in other char name language. how ever in english char name. it normal create. but in other no. Thanks in advance.
  4. Speak my dears! Today I'll be making available a very requested script. It's about the "CTF" That CTF from the xyler PK that I've seen several asking HAHA. There's only one but the script doesn't work. It could be because XileRO is eathena and eamod. If someone manages to make it work it will be a great achievement for all of us. I have all the other scripts.
  5. Hello, I didn't make any changes to your script, I use a 2017 emulator, your script only works on current (?)
  6. i've already start server.bat (map,login,char) in online. everything good. can play can do the same in localhost server. but. if i haven't play around 1 day. ( Server It seem to be sleep. ) i can login ID,password and client show the name of server that i seted ...but can't show something more ...can't show charactor it's seem connection failed. in server login show ([Info]: Closed connection from....my ip address) in server map show (Pinging SQL server to keep connection alive... in server char not show anything....... (if normal it'll show request connect ID........2000010) Everything will normal if i close all server.bat and start again. but if no one login or no one play in 1 day it's still as it was.
  7. In this section we are going to go through the steps to getting you set up with your very own server computer to run Ragnarok Online (and other games). Requirements : A Computer with at least 128 GB of space & 4 GB of RAM (8GB Recommended). Latest rAthena (Download here) Your own pre-made private client. (Not covered in this topic) Stable Internet connection. Ubuntu Bootable drive. (This guide was made using UBUNTU 22.04 LTS) Download Rufus if you don't have a bootable drive made. (Not Portable) Some time to process all of this information. Replace 127.0.0.1 with your Public IPv4 address. Wired Internet connection Optional Requirements : A Domain name SSL Certificates 32 GB Free Space (we will format it) Windows 10 ISO (x64) PRE-GAME SETUP Very Minimum system requirements : Operating System : Windows 95 to 11 CPU : Pentium II, 400MHz (or better) Memory (RAM) : 128 MB (or higher) Hard Disk Space : 7.2 GB (after system installation) Monitor Resolution : 640 x 480 (or higher) Video Card : Any with 3D Acceleration & at least 16MB on-board RAM Sound Card : DirectSound (or compatible with 3D Sound Effect Support) Internet Connection : 56 kbps (or faster) DirectX : 8.1 (or newer) Recommended System specifications : Operating System : Windows 10 CPU : Intel® Core™ i3-1305U Processor - 10M Cache, up to 4.50 GHz (or better) Memory (RAM) : 2 GB (or higher) Hard Disk Space : 128 GB (after system installation) Monitor Resolution : 1080x 720 (or higher) Video Card : Any with 3D Acceleration & at least 16MB on-board RAM Sound Card : DirectSound (or compatible with 3D Sound Effect Support) Internet Connection : 10 MB/ps (or faster) DirectX : 8.1 (or newer) ...... Now that we got a few things to get us moving let's get started... Section 1 - Installation STEP ONE: Making the Bootable (Rufus booter) i1.1.0 Once you've downloaded Rufus (here if still need) you will run it. You will a simple window with a basic user interface. Simple click "Boot selection" and make sure "Disk or ISO image" is selected. We will continue by clicking "SELECT" and choosing the Ubuntu disk image we downloaded earlier. The "Device" will be the USB drive we're making bootable: The default "cluster size" we'll leave as default. The "Volume Label" is what we will name the USB (optional). With that we're ready to click "START"! Here is what mine looks like at the end of it. STEP TWO: Setting up the OS (Ubuntu 22.04) i1.2.0 Upon booting up, you'll want to select "Try or Install Ubuntu". After this it will load up the start up interface. Follow the linear steps to install your new operating system. (NOTE: Ubuntu Pro is optional) We will do a normal installation for our example. After selecting the driver and location, you will need to create your user account. This is very important as it will contain information used further into the guide. Make sure you can remember your credentials. Getting used to the system will be beneficial for you. For this guide, we will navigate to your app menu located by default in the bottom left corner. STEP THREE: Preparing the Server (Adding Utilities & Libraries) i1.3.0 Here we are going to download a few necessary packages and then we will be able to simply update them whenever we need to using our update and upgrade commands. First thing's first. Let's update & upgrade our system. Type inside your terminal the following command: sudo apt update && sudo apt upgrade -y This will update and upgrade the system. Next we will need to install some packaged to run the server. Still inside the terminal, we will enter the following commands: sudo apt update && sudo apt upgrade -y sudo apt install build-essential zlib1g-dev libpcre3-dev -y sudo apt install libmariadb-dev libmariadb-dev-compat -y sudo apt install software-properties-common apt-transport-https -y sudo add-apt-repository ppa:ondrej/php -y sudo apt-get install php phpmyadmin mysql-server mysql-client git make gcc libmysqlclient-dev zlib1g-dev libpcre3-dev -y sudo apt-get install g++ From here we are ready to download rAthena. (If you have it downloaded manually and have a custom directory already ready for it, go ahead and upload it now. If not, follow these next couple steps to download and set the directory.) In this example, we are going to make the rAthena folder inside our Documents folder so we can find it easily. In your terminal enter in the following command to change to your documents directory: (replace the name with your user.) cd /home/raguser/Documents The terminal should now read something along the lines of: raguser@RagServer:~/Documents$ This is where we will create the rAthena directory. We will pull the rAthena trunk to a custom location we will name using the terminal. To do this we must enter in: git clone https://github.com/rathena/rathena.git ~/rAthena This will now clone the rAthena repository to the directory we specified as rAthena inside the Documents folder. Now we need to update the repo to make sure we have the latest files. Change directory using the cd command and entering in the new folder we just created: cd rAthena And pull the latest updates from the repository to ensure we have the correct version: git pull We now have a fully functional rAthena that is ready to be set up with our packet information, SQL database, our website, and more. In the next section we will cover how to set up the SQL server using PMA (phpmyadmin) right from the desktop browser! STEP FOUR: PMA & SQL (Setting up the database) i1.4.0 Now that we have a fresh rAthena installed, it's time to check MySQL to see if it installed correctly at the start. This may not be installed by default so follow the commands if you don't have it. To check the status of MySQL enter in your terminal the following command: service mysql status This will tell you what the status of your MySQL is. If this fails, install MySQL using: sudo apt-get install php phpmyadmin mysql-server mysql-client git make gcc You will want to select apache2 to install. Now we will have full access to MySQL! We need to start our first launch of SQL to get thigns started. To access SQL enter in: sudo mysql -u root -p This will access MySQL as the root user after you enter the password. (The password is the one you set up earlier when initially installing MySQL) Once authenticated and inside we can create a database and populate it with our server account. Creating the database is done using a few simple inputs. Enter in & modify the following details: CREATE DATABASE ragserver; CREATE USER 'raguser'@'localhost' IDENTIFIED BY 'StrongPassword'; CREATE USER 'raguser'@'%' IDENTIFIED BY 'StrongPassword'; GRANT ALL PRIVILEGES ON ragserver. * TO 'raguser'@'localhost' WITH GRANT OPTION; GRANT ALL PRIVILEGES ON * . * TO 'raguser'@'%' WITH GRANT OPTION; GRANT ALL PRIVILEGES ON * . * TO 'raguser'@'localhost' WITH GRANT OPTION; This created the database 'ragserver' and added 'raguser' to the database with full access. Next we need to make the logs and grant privileges to raguser on it. To do this enter in: CREATE DATABASE log; GRANT ALL ON log.* TO raguser@localhost; Now we can leave by entering in: quit This next part of this step is a little more complicated, but very simple to do. rAthena has a database in their files that we are going to pull the columns and rows from so we don't have to manually construct it ourselves piece by piece. Thankfully we can execute it all in two simple commands: mysql -u raguser -p ragserver < /home/raguser/rAthena/sql-files/main.sql mysql -u raguser -p log < /home/raguser/rAthena/sql-files/logs.sql And finally we are going to insert the first player account of our database. To do so we much enter & modify the following details. (This can always be changed later.) sudo mysql -u raguser -p Inside MySQL enter the following lines: INSERT INTO `ragserver`.`login` (`account_id`, `userid`, `user_pass`, `sex`, `email`, `group_id`, `state`, `unban_time`, `expiration_time`, `logincount`, `lastlogin`, `last_ip`, `birthdate`, `character_slots`, `pincode`, `pincode_change`, `vip_time`, `old_group`) VALUES ('20000000', 'admin', 'adminPassword', 'M', '[email protected]', '99', '0', '0', '0', '0', '2022-02-20 00:00:00', '', '2022-02-20', '9', '', '0', '0', '0'); (You can always change this later in the PMA window in the next steps.) It's time to check our SQL to make sure it looks as good as we think. To do this we are going to need to go to your favourite web browser and enter in the following website ( your website! ) http://127.0.0.1/phpmyadmin/ And we're in! Here inside PMA you will find all the accounts and database information. You can load item and mob databases directly to here and read from here instead of the traditional rAthena directory. There are many things to control inside here, especially if you're troubleshooting. (You also have an App icon in your menu.) STEP FOUR-2: PMA (Restricted Access) i1.4.1 Now that we've got PMA up and running we're going to want to restrict access to any users other than the host. To do this we will use our host address and only allow access to PMA using that address. Else, it will throw a forbidden page to the user. Start by editing the following file: sudo nano /etc/apache2/conf-available/phpmyadmin.conf And at the very bottom we will enter a new line for it to read: <Directory /usr/share/phpmyadmin> Order deny,allow Deny from all Allow from 111.222.33.444 </Directory> Be sure to change the address to your machine's IP address. Restart apache2 and you're ready to go! sudo systemctl restart apache2 STEP FIVE: Getting Green (Online) i1.5.0 Great! You're this far. Not much more to do from here. We're going to now navigate to your rAthena directory and edit the "char_athena.conf" script located in: /home/raguser/rAthena/conf/char_athena.conf Open the file with any text editor, the default one will work. Inside this file, near the top, will be the lines that show your Name & Password. These are for your Login database we set up earlier for phpMyAdmin (PMA). Search for and change the values to a random name and password: // Server Communication username and password. userid: s1 passwd: p1 For this step it is recommended to use random password generator of some sort. This never needs to be entered in manually anywhere. You can copy-paste it everywhere in this guide. In this example we are changing it to: userid: 4Xy3NAKxnl3sk6Aj passwd: 79y59S3m8lWmMDMS Now the Server's username and password are set, we can change the "inter_athena.conf" file so that the server can read our database we set up. Navigate to: /home/raguser/rAthena/conf/inter_athena.conf This is where we are going to change some access information so the server can read through our MySQL login we made earlier. Find and change: // MySQL Login server login_server_ip: 127.0.0.1 login_server_port: 3306 login_server_id: raguser login_server_pw: StrongPassword login_server_db: ragserver login_codepage: login_case_sensitive: yes ipban_db_ip: 127.0.0.1 ipban_db_port: 3306 ipban_db_id: raguser ipban_db_pw: StrongPassword ipban_db_db: ragserver ipban_codepage: // MySQL Character server char_server_ip: 127.0.0.1 char_server_port: 3306 char_server_id: raguser char_server_pw: StrongPassword char_server_db: ragserver // MySQL Map Server map_server_ip: 127.0.0.1 map_server_port: 3306 map_server_id: raguser map_server_pw: StrongPassword map_server_db: ragserver // MySQL Web Server web_server_ip: 127.0.0.1 web_server_port: 3306 web_server_id: raguser web_server_pw: StrongPassword web_server_db: ragserver // MySQL Log Database log_db_ip: 127.0.0.1 log_db_port: 3306 log_db_id: raguser log_db_pw: StrongPassword log_db_db: log log_codepage: log_login_db: loginlog The last location we need to navigate to are our map server configurations. For this we will navigate to: /home/raguser/rAthena/conf/map_athena.txt Change the username and password for the server. It's the same as earlier: userid: 4Xy3NAKxnl3sk6Aj passwd: 79y59S3m8lWmMDMS Now add (or uncomment) the following lines: char_ip: 127.0.0.1 char_port: 6121 map_ip: 127.0.0.1 map_port: 5121 In this part of the step we will configure the client to match your packet version. First we need to ensure "make" is installed. Enter in: sudo apt install make We'll need to give execution access to the configure file. Enter inside the rAthena directory (cd /home/raguser/rAthena) : sudo chmod a+x ./configure Then we are going to configure the server packet to match the client we downloaded. ./configure --enable-packetver=YYYYMMDD The YYYMMDD is your client version for your server.exe. Our example is going to be 20211103: ./configure --enable-packetver=20211103 Once you've done that we're all ready to get the green light. Let's test it out! Let's make a clean slate! Enter in the command while still inside your rAthena directory: make clean Now let's start constructing the server: make server After that's done loading, let's give execution access to the start files & servers: sudo chmod a+x login-server && sudo chmod a+x char-server && sudo chmod a+x map-server Time to start it up! (Make sure you're inside the rAthena directory) To start the server: sudo ./athena-start start To stop the server: sudo ./athena-start stop To restart the server: sudo ./athena-start restart To check the status: sudo ./athena-start status We're online! EXTRA STEPS (OPTIONAL) STEP SIX: DNS. (Mask your IP) i1.6.0 So many of you, like myself, would like to mask your IP address and the best way to do this is to use a domain name service to mask our IP. But does this mean you can't find my IP? No. This does not mean your IP is hidden completely. It just means people have an easier way of accessing your website on a more reliable and trusted connection. In this part of the guide we will go through the process of obtaining and setting up the DNS on your personal dedicated server. Let's start by understanding what DNS means. I'll be quick. What this is telling is, is that we can now take one thing (our IP) and mask it with another thing (domain name). That's short enough. Now some might be wondering... "Don't I need a website and a host for all of that?" The answer is Yes. We set that all up in the previous steps of this guide. You're all ready good to go. The first step is to navigate to your favourite (and trusted) domain name service provider. There are many out there that a simple google search can discover. In this example we are going to use Domain.com. It's affordable, takes Paypal, and has everything we need neatly displayed. Right in the middle of the landing page, you'll notice a search bar. It's large and ahrd to miss. This is where you will type your domain name you want to look for. Don't worry about attaching the endings onto it (.com, .net, etc) as it will give you a list of all the available ones. Purchasing a domain will create an account for you using the details entered in during the billing process. The basic domain I purchased costs slightly more because it's a ".net", which holds a premium standard these days. You don't need to worry about protection and SSL either. We will be managing that all from the server computer as well. For free. Once you find a domain name that fits what you want to achieve and your account was successfully created, it's time to navigate to your email and verify the website. This process is necessary to get the site online. We are now authenticated and ready to move onto the next part of this step. Now that we have a domain, what do we do now? How do we ge this domain name we now own onto mask your personal address? Keep following along. We're almost there! To confirm we have everything, in case there was an issue before, we're going run, in the terminal, the command: sudo apt update && sudo apt upgrade -y && sudo apt install apache2 -y Next we'll need a couple library files for the server to read the data. The following command will give us those libraries: sudo apt install php libapache2-mod-php php-mysql -y Now that we made some changes, it's always good to verify things are still where we left them. Let's verify PHP again to make sure it's the same version as before (8.2.2) php -v Earlier we made a web server. Now it is time to configure it! Enter in and customise the name: sudo mkdir /var/www/customName sudo chown -R raguser /var/www/customName This creates a folder and gives us full ownership of it inside the webserver directory. The custom name is for security measures. This is where we will upload our website and all the web files later. First we need to make a configuration file to run it properly. To do that we must enter in and adjust the name of: sudo nano /etc/apache2/sites-available/customName.conf An empty screen will appear. This is what we want. Now we can populate it with all the information necessary to maintain the web server. I recommend pasting this into a notepad and changing the values as needed. You will need your web site name, user name,custom folder name we made moments ago and your public IP address (v4). Change the values and paste it in to the blank page: <VirtualHost *:80> ServerName localhost ServerAlias kingsman-gaming.net ServerAdmin [email protected] DocumentRoot /var/www/customName ErrorLog ${APACHE_LOG_DIR}/error.log CustomLog ${APACHE_LOG_DIR}/access.log combined </VirtualHost> Now the website is almost ready. We've given it instructions where to go. All we have to do now is verify it and enable scripts for the site to operate. Let's start by reloading our web server. sudo systemctl reload apache2 You may have to reload the apache2 service. If this appears simply run the command again: sudo systemctl reload apache2 This will appear a couple times through this part. Next we need to enable the default script. To do this we will run a command called "a2dissite". What this does is uses system links to run the website and disaables them when needed. Once enabled, we can set and forget even after reboots. sudo a2dissite 000-default Now we're going to do the same thing, except for the config file we just created above. The name must be exact: sudo a2ensite customName Let's test the config to see if it throws any errors: sudo apache2ctl configtest It looks like we got an error! It reads: If you encounter this, it's a simple fix! Enter the command to edit the following file: sudo nano /etc/apache2/apache2.conf Now we need to go to the bottom of the page and insert (at the very bottom) : ServerName localhost And now we want to reload the apache2 service one more time: sudo systemctl reload apache2 Finally, we must route our public IP to the domain name. This is done in that DNS menu on our domain host website. Let's navigate back to Domain.com and set this up. Here we want to edit (or add if it's not here) the "A record" that points to the host configured IP address. We will simply click edit to change the existing record and have it reflect (and edit to match your public IP) the values below: A @ 127.0.1.1 And to prepare things for the next steps, we are going to navigate to back to our basic domain settings and make sure the settings reflect the following: (Auto-renew optional) This is telling us all the options are disabled. We won't be needing any of them supplied by the host. That's it for this part! Our web server is ready for a website to be added and for the DNS to be redirected in our network settings. In the next step we will go through securing the website with a security certificate. It's free and easy to set up. STEP SEVEN: Getting SSL Certified (HTTPS) i1.7.0 In this step we're going to get that SSL set up. Currently when we access our website it says HTTP. We are going to make it say HTTPS. Start by registering to SSL For Web. It's free and easy to set up. After registering, we're going to go right to the top right and click the create button. You will be given two options. DNS & HTTP. We are going to select DNS to continue. You'll also need to enter your domain name to continue. This is where it gets a little more complicated, so follow closly. You will be given two codes to enter into your DNS register. To find this, you will navigate to where you purchased the domain name and modify the existing DNS service to include these values. Simple, right? In our example we used Domain.com. So we will continue using them. Log in and navigate to your domain. On the left side panel you will have some options. Select the one that says DNS & Nameservers. You will get a window like this: We are going to click DNS Records. This is where we will enter those values SSL generated for us. Go back to the SSL page and copy the first value on the left. This is a challenge domain for your domain name. Go back to your DNS records and enter in a new record. The record type we want is TXT. Paste inside the "Name" box the value we just copied. Go back to SSL and copy the value on the left. This is going to be pasted in the "Content" box. Set the value to 1/2 hour and hit confirm. Finally go back and verify that it worked. (It can take up to 30 minutes to fully work, but is usually quicker dependingon the service.) There is a status checker so you don't need to submit every time. Use the scroll bar to go to the right and check the status. Now that we have the green light and a security certificate is added to the domain, we can download the certificates and add them to the server. There are two main types of certificate for use and a bundled version. All we need in this example is the Certificate and Private Key. Now that we have them, how do we add them? Leave this page open for now, as we will need it shortly, and navigate back to your terminal. We're going to enter a few commands to get things set up on our dedicate server. Enter in to edit your certificate file: (rename to your website) sudo nano /etc/ssl/certs/kingsman-gaming.net.crt Then paste your certificate value that was given to you. We're looking for the Certificate. It now looks good to save! (CTRL-X, then enter Y to confirm) Now we must give it the key to the certificate. Enter in and edit the file: sudo nano /etc/ssl/private/kingsman-gaming.net.key We want to populate it with the key that SSLForWeb gave us. Go ahead and paste that in, then save the file. The last certificate we're going to add is the CA bundle. This will be used in the later steps, but let's add it now since we're here. Create a new file and give it adifferent name. In this example we just added ca. to it: sudo nano /etc/ssl/certs/kingsman-gaming.net.ca.crt Certificates are added and ready to go. Here we will go back to our server config file we made earlier and set it up for SSL encryption. Open: sudo nano /etc/apache2/sites-available/customName.conf We want to change the values to reflect: <VirtualHost *:443> SSLEngine on SSLCertificateKeyFile /etc/ssl/private/kingsman-gaming.net.key SSLCertificateFile /etc/ssl/certs/kingsman-gaming.net.crt ServerName localhost ServerAlias kingsman-gaming.net ServerAdmin [email protected] DocumentRoot /var/www/customName ErrorLog ${APACHE_LOG_DIR}/kingsman-gaming.net_error.log CustomLog ${APACHE_LOG_DIR}/kingsman-gaming.net_access.log combined <Directory /var/www/customName> Options FollowSymlinks AllowOverride All Require all granted </Directory> </VirtualHost> Then enable SSL to run scripts: sudo a2enmod ssl Let's break that down.... <VirtualHost *:80> is set to a standard, non-secured, port. We updated this to a secure port to allow the security certificates through. We added three lines to the top. These lines will be read first and indicate we are turning the SSL Engine ON, setting the Certificate Key file to our private ssl folder, and setting the Standard Certificate file to our certificate folder. And at the bottom we added some additional options for some System Links, Overrides, and Permission granting. Now the server can read all the security changes we made! Once we save that file we are going to enable the SSL scripts in the server. This was done simply with one command. With all this done, we have only one more step left to complete before we can fully set up SSL on the server. We need to allow our SSL access through the firewall. We can do this very easily with the following commands: sudo ufw allow 443 Your firewall should now appear with these ports for all of default Ragnarok services: (Check out open allowed services with sudo ufw status) 443 ALLOW Anywhere 5121 ALLOW Anywhere 6121 ALLOW Anywhere 6900 ALLOW Anywhere 80 ALLOW Anywhere 22 ALLOW Anywhere If you don't ahve an active firewall you can enable it with: sudo ufw enable With all this added, we are now going to check the syntax for the apache2 configuration to make sure it's still "OK" and restart the apache2 service: sudo apache2ctl -t sudo systemctl restart apache2 Common issue after this step: This is caused because the SSL scripts have to be passed through the system still. To do this we can enter in two commands to set this up: sudo a2enmod ssl sudo systemctl restart apache2 That's it for this step! We now have an SSL connection for our webserver. In the next section we will go through various methods of setting up the File Transfer Protocol (FTP) for our webserver. This is great for setting up files from your server for others to download. Users can download files directly from the web server. STEP EIGHT: File Trasnfer Protocol (FTP) i1.8.0 We're going to enable this on our server to allow users to download various files we set up in the download folder. Let's start by making that folder. Change directory to your web directory. We modified it earlier above: cd /var/www/kingsman/ Now create a directory: mkdir download We now have a folder where we will be adding out downloadable files. Let's get the libraries ready for the web server. Enter in: sudo apt-get update && sudo apt-get install openssh-server It will be a linear installation. Once it completes we can check the status of it: sudo systemctl status ssh If it failed to start load it again with: sudo systemctl start ssh Once we set the configs we're all ready to go. Edit the file: sudo nano /etc/ssh/sshd_config These settings will be added at the very bottom of this document. Scroll to the bottom, add & edit the following values: Match User raguser ForceCommand internal-sftp PasswordAuthentication yes ChrootDirectory /var/www/kingsman/download PermitTunnel no AllowAgentForwarding no AllowTcpForwarding no X11Forwarding no Save the document and exit. (CTRL + X then Y & Enter) Restart SSH with: sudo systemctl restart ssh We now have a fully functional FTP server attached to the web server. Now to get links for your files, you'll need to understand how the folders work in the web server. This part is completely ignored in the link you will generate: /var/www/kingsman/ Your link will be the default web address, so let's start with that: https://kingsman-gaming.net/ That's the start. Now we need to add our download folder. We know the default location is /var/www/kingsman/ directory, so this means kingsman-gaming.net is that location. To add the downloads folder we simply just separate it with a " / " and add the download directoy, exactly how it's spelt,in the file hierarchy: So /var/www/kingsman/download becomes: https://kingsman-gaming.net/download/ You can add as many directories as you can fit into the web address search bar and break off from the download folder to download other parts of the site. You'll add the file name to the link for which ever file you want to download. For example, I want to download VLRO.zip: https://kingsman-gaming.net/download/vlro.zip Now we have a place players can download our server from. Simply upload your files inside this download folder and send the link to your players to download. In the next step we will go through how to create a launchable version of Windows 10 wil your Ragnarok Online server set up on it. We will also go through various tools that will be useful to development. STEP NINE: Emulating Windows 10, Ragnarok & RO Tools (QEMU/KVM) i1.9.0 In this step we will be going through how to build and run a virtual machine based on Windows 10 operating system with our Ragnarok Online server installed onto it. Make sure to download Windows 10 ISO while we work. This will save some time later. You may also want to consider moving it to a new directory inside your Documents folder. We'll be doing this for our example moving forward, as well. Start by check that your system is Virtualization Ready. Enter in the terminal: egrep -c '(vmx|svm)' /proc/cpuinfo If your system is Virtualization Ready it will appear with a number greater than 0. My number came out as 16, so we're good to check if the system is supported. To do this enter in: kvm-ok If the system does not have the checker, you can enter this command to enable it: sudo apt install cpu-checker -y Now that we found out we can support virtualization it's time to install it, along with the librarfies neeeded to run it. Enter the following command to run all of this in one go: sudo apt install qemu-kvm virt-manager virtinst libvirt-clients bridge-utils libvirt-daemon-system -y We're going to run two more commands to make sure we have the virtualization daemon. Enter in: sudo systemctl enable --now libvirtd sudo systemctl start libvirtd Now check the status of to make sure it's online and everything is green:\ sudo systemctl status libvirtd Everything looks good so far! Before we can run the program we need to give our user specific permissions to access the daemon. To do this we will enter in: sudo usermod -aG kvm $USER sudo usermod -aG libvirt $USER We are now ready to launch! You can start the application in the application menu using the icon it supplies. (It can take a minute to populate) If you can't find it, or it hasn't appeared yet, you can manually run it with the command: sudo virt-manager You should now have a window that looks like this: If you experience an error trying to connect after finishing up to this part of the step and it reads something along the lines of: Unable to connect to libvirt qemu:///system.Verify that the 'libvirtd' daemon is running. Error: Failed to connect socket to '/var/run/libvirt/libvirt-sock': Permission denied It is recommended to restart your computer and try connecting. Sometimes after the installation it won't have all permissions set properly. A full restart of the system can resolve this. Now that we are set up, it's time to create a virtual machine! Go ahead and click the New Machine button at the top left. We're going to select Local install media from the list and select the ISO file we downloaded at the start of this step. (If you didn't donwload it before, now is a good time to. While you're waiting you can reflect over the steps you've went through to get this far. It is good to understand the system and how you got here.) We'll want to click "Browse..." and a new window will appear. Here we have our default filesystem directory. This is a default directory that is given with the application. We don't have files in this folder so we won't focus on this. At the bottom left, there's green " + ". Click it. Now we are presented with options for renaming the pool, changing the type of file it is, and setting the target path for where to read and write data. We are only going to focus on two of these options in this step. Name & Target Path. We'll give it the name "DiskImages", though you can name it anything you want, and we want to select the path to be the folder we created inside our Documents which holds the Windows 10 ISO. We now have a link to this folder inside the KVM. If we select it, we can now see the Windows 10 64 bit ISO is there. We will click it and Choose Volume. The applicatiion will likely guess that it is Windows 11, so we need to uncheck that box and change it from an 11 to a 10. Change to Press Forward and agree to the promt. You can click the Don't Ask button for future changes. Now we must set the amount of RAM and Cores to use. We can change this any time after shutting the virtual machine down. For now, we will use the default 8G and 4 Cores. (Recommend: 3G RAM or more, 2 cores or more for this setup) The next part of this step is to create the virtuale machine's hard drive. To do this we need to let the VMM do a rather long process to the 32 GB of space that will add a system file to a size we pre-determine, and it will allow us to boot Windows 10 off that space and dedicate it a hard drive to store files. It sounds complicated, but it's really simple to do. It just takes some time if you have larger spaces to work with. Moving forward, we much select "Enable Storage for this virtual machine" and we will then go to the bottom and select "Create a dusk image for the virtual machine" and click "Forward". If we get asked to grant search permissions for the path. Click YES. Now we are ready to create the Windows 10 disk space. Double check the information is correct, mainly the Windows 10 operating system doesn't say Windows 11. It will launch automatically for the first time on Finish. You will now be able to set up your emulated Windows 10. (If you encounter...) ERROR: If you experience an error, roughly like the one I created above, it's possible that the QEMU user does not have access to this directory still. You can manuall add this access very easily. Enter in the command to check the permissions, first: The output should look close to this: This is showing us that our QEMU is not here on the list. Let's add it: sudo setfacl -m u:libvirt-qemu:rx /home/raguser/RagDisk Now if we run the command to check it again: sudo getfacl -e /home/raguser/RagDisk We can see that the user is added successfully. Finally, Restart the Virtualization library and you're ready to continue on to the next parts of this step: sudo systemctl restart libvirtd You should be ready to launch now! We've got Windows 10 running and Updated as much as it can get. We're going to install a few necessary applications to run our programs and the game itself. Download the following files from the following (trusted) sources: -Microsoft Direct X Runtime -Visual C++ Redistributable for Visual Studio 2015 -.NET 6.0 or 7.0 -(Optional) RO Tools List With everything installed, and the system fully rebooted for good measure, we're ready to get started with the game installation. STEP TEN: Setting up rAthena Source (Game Files) i1.10.0 Now it's time to get rAthena set up so we can get players connecting to the server. First thing's first! Organise and familiarise yourself with the files. This is where you will be spending lots of your time. This will be an ongoing process once you complete these steps. In this guide, it will give you some organization pointers. Take your time with this and get used to how you lay things out. You will navigate back and forth a lot during a maintenance. If you have not already downloaded rAthena we will go ahead and do that now. The following commands will change your directory to the root for your profile, next it will make a "Server" folder for you to operate in, and finally it will download the rAthena trunk to that directory. Finally we will enter that directory to process the remaining steps. cd sudo mkdir Server git clone https://github.com/rathena/rathena.git ~/rAthena cd rAthena To update rAthena to the latest verison we need to process a git-pull while inside the rAthena diretory. git pull Now we've got rAthena's latest trunk and all the updates! It is important to get a good, or at least an okay, understanding of how rAthena has all their files organized. Things are in a specific place and named specific things for a reason. If you move or rename a file or folder it will cause you many problems. Source files are where you will make changes that will affect the entire game and the way it functions. Be very careful when editing these files and stay within the lines of the cave if you don't know what you're doing. Config files are where you will make the majority of changes to your server. This is where things like Drop rates, EXP rates, and all your Server settings will be located. In the continued steps below, we will go through how to set up the remainder of the server. It's time to create a database for all the player accounts to be saved to. To get started be sure you've followed the previous steps for setting up PMA (phpMyAdmin). Now that we have access to MySQL we can start by entering in some commands to give us access to the databases involved. Open the terminal and enter in the following: (Note: You set the username and password earlier) CREATE DATABASE ragserver; CREATE USER 'raguser'@'localhost' IDENTIFIED BY 'StrongPassword'; CREATE USER 'raguser'@'%' IDENTIFIED BY 'StrongPassword'; GRANT ALL PRIVILEGES ON ragserver. * TO 'raguser'@'localhost' WITH GRANT OPTION; GRANT ALL PRIVILEGES ON * . * TO 'raguser'@'%' WITH GRANT OPTION; GRANT ALL PRIVILEGES ON * . * TO 'raguser'@'localhost' WITH GRANT OPTION; This created the database 'ragserver' and added 'raguser' to the database with full access. Next we need to make the logs and grant privileges to raguser on it. Enter in: CREATE DATABASE log; GRANT ALL ON log.* TO raguser@localhost; Now we can leave by entering in: quit Majoirty of the database is set up now! This next step is a little more complicated, but very simple to do. rAthena has a database in the server files that we are going to pull the columns and rows from so we don't have to manually construct it ourselves piece by piece. Thankfully we can execute it all in two simple commands: mysql -u raguser -p ragserver < /home/raguser/rAthena/sql-files/main.sql mysql -u raguser -p log < /home/raguser/rAthena/sql-files/logs.sql Now we have an almost-fully functional database for the server. It's time to create the first account! Back to the terminal, we are going to enter and log in to MySQL again: sudo mysql In MySQL enter in: (Before submitting this to the database, we are going to change the Login Name, User Name, Password, & Email) INSERT INTO `ragserver `.`login` (`account_id`, `userid`, `user_pass`, `sex`, `email`, `group_id`, `state`, `unban_time`, `expiration_time`, `logincount`, `lastlogin`, `last_ip`, `birthdate`, `character_slots`, `pincode`, `pincode_change`, `vip_time`, `old_group`) VALUES ('20000000', 'admin', 'adminPassword', 'M', '[email protected]', '99', '0', '0', '0', '0', '2022-02-20 00:00:00', '', '2022-02-20', '9', '', '0', '0', '0'); Great! You're this far. Not much more to do from here. Navigate in WinSCP/FileZilla (or other FTP access app) and go to your directory: /home/raguser/Server/rAthena/conf/char_athena.conf Inside this, near the top, will be the lines that show your Name and Password. These are for your Login database we set up earlier for PMA. If you haven't changed these yet, do so now. I recommend a random generator for the values. A simple Google search for this will help. Search for and change the values to a random name and password: // Server Communication username and password. userid: s1 passwd: p1 These values must reflect what is inside the login database or the server won't be able to connect. Do not share these values. With anyone. Now the Server's username and password are set, we can navigate to: /home/raguser/rAthena/conf/inter_athena.conf This is where we are going to change some access information so the server can read through our MySQL login we made earlier.Find and change: // MySQL Login server login_server_ip: 127.0.0.1 login_server_port: 3306 login_server_id: raguser login_server_pw: StrongPassword login_server_db: ragserver login_codepage: login_case_sensitive: yes ipban_db_ip: 127.0.0.1 ipban_db_port: 3306 ipban_db_id: raguser ipban_db_pw: StrongPassword ipban_db_db: ragserver ipban_codepage: // MySQL Character server char_server_ip: 127.0.0.1 char_server_port: 3306 char_server_id: raguser char_server_pw: StrongPassword char_server_db: ragserver // MySQL Map Server map_server_ip: 127.0.0.1 map_server_port: 3306 map_server_id: raguser map_server_pw: StrongPassword map_server_db: ragserver // MySQL Web Server web_server_ip: 127.0.0.1 web_server_port: 3306 web_server_id: raguser web_server_pw: StrongPassword web_server_db: ragserver // MySQL Log Database log_db_ip: 127.0.0.1 log_db_port: 3306 log_db_id: raguser log_db_pw: StrongPassword log_db_db: log log_codepage: log_login_db: loginlog The last locations we need to navigate to are our map server & subnet configurations. Navigate to: /home/raguser/rAthena/conf/map_athena.txt Change the username and password for the server. It's the same as earlier: userid: 4Xy3NAKxnl3sk6Aj passwd: 79y59S3m8lWmMDMS Now add (or uncomment) the following lines: char_ip: 127.0.0.1 char_port: 6121 map_ip: 127.0.0.1 map_port: 5121 And finally adjust the subnet to match your server's IP address. This step can be a little tricky if you don't understand how a subnet works. So simply follow below and replace x.x.x.x with your server's IP address: subnet: 255.0.0.0:127.0.0.1:127.0.0.1 subnet: 255.0.0.0:x.x.x.x:x.x.x.x Excellent! You're near the end. It's time to configure the client to your packet version. Let's give execution access to the configure file: sudo chmod a+x ./configure Then we are going to configure the server: ./configure --enable-packetver=YYYYMMDD The YYYMMDD is your client version for your server.exe. An example of how this looks is: ./configure --enable-packetver=20211103 Congratulations on making it to the end of setting up your server. It's time to start it up now! Let's make a clean slate! Enter in: make clean Then let's start constructing that server. Enter in: make server After that's done loading, let's give execution access to the start files & servers: sudo chmod a+x login-server && sudo chmod a+x char-server && sudo chmod a+x map-server Time to start it up! (Make sure you're inside the rAthena directory) To start the server: ./athena-start start To stop the server: ./athena-start stop To restart the server: ./athena-start restart To check the status: ./athena-start status That's it for this step. If you followed up to here you'll have a all server files downloaded and ready on the server side with a database ready to accept logs and registrations. In this next step we will go through the systemd.service files to get your server running automatically when the system restart or if it crashes. STEP ELEVEN: Setting up UFW (Firewall) i1.11.0 When setting up the firewall, we want to make sure we know exactly what ports we are adding in before we add them. This will save us from having to deny thema ccess later. Let's gather the ports we know of for all the services we've set up thus far. We know of our Web ports, which should be automatically added when installed, but sometimes this isn't the case. We've also got the FTP ports for the download servers, if we want to use them. There's also the PMA & SSH ports. Are you writing this down? sudo ufw allow 443 sudo ufw allow 80 sudo ufw allow 20/tcp sudo ufw allow 21 sudo ufw allow 22 sudo ufw allow 3306 sudo ufw allow 6900 sudo ufw allow 5121 sudo ufw allow 6121 sudo ufw allow 8888 Sometimes you might still get some issues with the firewall blocking you. You may be required to let the firewall know what type of conneciton to allow, either TCP or UDP; but what is TCP/UDP you might ask? Very simply put... TCP means Transmission Control Protocol which runs a more reliable connection, however, it can lack in transfer speed. UDP means User Datagram Protocol and it has a much faster transfer rate of data, but can be unreliable in sending said data. What does this mean for you? You can choose to do UDP all accross the board since Ragnarok uses small packets of data compared to a much larger scale game. Just my recommendation. However, if you want absolute data transfer at the highest success rate to avoid lost packets and data, then do TCP. Still confused? Do both in the firewall. An example of what the command will look like for adding TCP/UDP: sudo ufw allow 5121/udp sudo ufw allow 5121/tcp Now that we've got an understanding of the firewall and the ports we have added we can now relax knowing the firewall will protect us from majority of threats. STEP TWELVE: Setting & Forgetting (Auto-Start scripts) i1.12.0 I hate when the server crashes. But you know what's worse? When it doesn't come back up until an admin turns it on. In this step we will go through the simple setup process to get your server ready to start when you load your system and reboot if it crashes. Start by opening up the terminal and entering in the following command to create a new system.service file: sudo nano /etc/systemd/system/ro-login.service This will create a system service file which we will enable later to start automatically. Inside these service files will be a series of commands that will allow the server to boot up automatically when it experiences an outage for a speificied amount of time & when starts the system after a reboot. Populate the file and edit the values to match your rAthena directory and User Login name: [Unit] Description=Ragnarok Login-Server After=syslog.target network.target mysqld.service [Service] WorkingDirectory=/home/raguser/rAthena User=raguser ExecStart=/home/raguser/rAthena/login-server ExecReload=/bin/kill -HUP $MAINPID KillMode=process Restart=on-failure RestartSec=15s [Install] WantedBy=multi-user.target We are going to do this two more times. Once for Character Server & another for the Map Server. sudo nano /etc/systemd/system/ro-char.service Populate with: [Unit] Description=Ragnarok Character-Server After=syslog.target network.target mysqld.service [Service] WorkingDirectory=/home/raguser/rAthena User=raguser ExecStart=/home/raguser/Server/rAthena/char-server ExecReload=/bin/kill -HUP $MAINPID KillMode=process Restart=on-failure RestartSec=15s [Install] WantedBy=multi-user.target And now: sudo nano /etc/systemd/system/ro-map.service Populate with: [Unit] Description=Ragnarok Map-Server After=syslog.target network.target mysqld.service [Service] WorkingDirectory=/home/raguser/rAthena User=raguser ExecStart=/home/raguser/Server/rAthena/map-server ExecReload=/bin/kill -HUP $MAINPID KillMode=process Restart=on-failure RestartSec=15s [Install] WantedBy=multi-user.target We will now start them all and check their status: sudo systemctl start ro-char sudo systemctl start ro-map sudo systemctl start ro-login sudo systemctl status ro-char sudo systemctl status ro-map sudo systemctl status ro-login Once we have the Green light on the status we can go ahead and enable the scripts to automatically start on boot. Enter in: sudo systemctl enable ro-char sudo systemctl enable ro-map sudo systemctl enable ro-login That's it! You're set to boot up automatically after a crash and upon system restart. Well done! Section 2 - After-Installation Now that we've got everything set up this far, we can continue maintaining & updating what we've started. Continue below to learn more on how to maintain the server after you've set it up. Requirements : Latest NEMO release An executable update from NEMO's website Latest FluxCP from rAthena STEP ONE: FluxCP (Registration & Logins) i2.1.0 Everyone needs to register somehow, right? We're mostly all aware of the high risks with enabling registration via "_M/_F", if you're not... In short: Don't use it if you're opening the server to the public. It can enable botters, spammers, & hackers the ability to just create infinite accounts and continue their schemes easier. With FluxCP we can help avoid this by limiting the amount of registrations allowed per person. Let's dive into it now. Gather your resources! You'll need to download the latest FluxCP by clicking that link. If you missed it, here's the link again: https://github.com/rathena/FluxCP This is where we will manage all the registrations to the game as well as many other fun functions we will get into later. For now download & extract this entire directory into your webserver. I put mine in the primary (root) directory of my webserver. That's the folder we created earlier with the custom name we provided. In this example we used "kingsman" as the custom name. The folder path is: /var/www/customName Our final output will look like not include the folder. This means we must drag all the contents into the root directory of the webserver. Now we should look like this at after extraction: Enter the config folder first. This is where we will be doing all the work for setting up this control panel. Inside the config folder you will have 31 files to select from. We're only going to work in two of these for this step. Open servers.php and you will see a set up similar to earlier where we added some settings for rAthena configs. They are the exact same configs. Go ahead and add that in there exactly as you did in the configs earlier. Now that we have our config looking good, let's scroll down towards the bottom and edit our rates to reflect that of our server's. This will display the rates set up in your databse as well so players can use that to search drop rates on your server. Change accordingly! That's it for the servers.php! Save that & move to the next file. Let's now open up application.php and edit the first few lines we see. We want to change the base URI to be blank. This will set it to the root directory where we hold the control panel. Server Address is going to remain localhost since we are running it on the localhost. And finally we need a storng password to gain access to the administration panel to set it up. 'ServerAddress' => 'localhost', // This value is the hostname:port under which Flux runs. (e.g., example.com or example.com:80) 'BaseURI' => '', // The base URI is the base web root on which your application lies. 'InstallerPassword' => 'superduperstrongpassword,man', // Installer/updater password. Save that and open your website now! You'll likely get several permission errors. Copy waht they say for you to do, it will be a sudo chmod command giving access to the logs. This is necessary to proceed to the next part. Add sudo before each command or it won't work. You'll need to enter your password into the control panel shown after granting permissions to FluxCP. After the password is successfully added it will update your PMA database with all the new information for FluxCP's registration and logins. Your panel should look like this by default now: You now have a palce where you can register and manage accounts! Navigate through the application.php file to change some various settings like your control panel name and what is displayed. You can also adjust the ports if they are different during the previous set up. STEP TWO: My First EXE (Making an Executable) i2.2.0 Now that we've got everything set up on the server-side of things it's time to work on the client-side of things now. Let us start first by making an executable. this will be the CustomRO.exe that players will use to run the game. Launch NEMO and give it a moment to load up. In a compact form, this is waht you'll see. What this is showing us is that we can Load a client, which we downloaded from the "Requirements" section above, we can apply patches, select the recommended patches, select previously loaded patches, load a pre-saved profile, and save an existing setup as a profile to load later. for this example we are going to use the current recommended version in rAthena's trunk. This is version "2021-11-03". We are presented with a file that will launch a terminal to download the latest executable. It will look similar to this: Now we have the executable ready to be patched. Back inside NEMO, we want to browse to that file we just downloaded and select it. You can change the saved outpute file name here or rename it anytime later. Here we will change it now. Click "Load Client" and a list of patches will populate. Now we want to "Select Recommended" patches given for for the executable. To apply these patches simply click the "Apply Selected" button and it will pack it for you. Brose the patches and select any patches that will help you or you might use in the future. For this example we are changing the Client Title name, the ItemInfo.lub or ItemInfo.lua and a majority of other changes that will allow the client to read LUA files over LUB files. Take your time going through the list. It will take a while the first time around. With all the patches applied we now have en executable in our output folder. But it came with other files, what do I do with those? You only need the custom executable we made (CustomRO.exe). This is going to be sent to the players and the rest will be removed from the client folder You're now ready to send this to other players! STEP THREE: My First Patcher (Making a Patcher) i2.3.0 We've got a client executable and it's fully patched the way we like. This is a great start! Now it's tie to send players an update. Through the patcher. But we don't have one yet! In this example we will go through the steps to creating a patcher using Thor Patcher from rAthena download section. Your extracted package should reflect similar to this: We want to enter the Configuration folder and edit the config.ini file located inside. Inside this config file are the lines necessary to connect the client to the server and send files from the server to the client. In the first few mines we'll edit the values to reflect our server values: The IP can be our website, this example is just a localhost address. Remote config file we will leave as default. Status file we can name server.dat. This can be anything, however. The custom GRF we have for our server, listed as number 0= in the data.ini. Finally our custom client executable we made earlier. Further down the page we have the title of the patcher. This can be anything. And lastly our notice page which will have a brief text description for the updates on the patcher front page. Save that and we're ready to launch the config generator. Drag the config into your .../Thor_Patcher/Patcher folder and it you're ready to copy them to your CustomRO client files. When compelte you'll have a patcher similar to this: You're made your Patcher now, well done! STEP FOUR: My First Patch (Making a Patch) i2.4.0 Keeping organised is key to staying sane. Let's start off by making a couple folders. A Patches folder & a data folder. It should look like this now: Patches/data This should look familiar. It's the same set up as the GRF. We will now be able to drag all the files we want to patch into this directory. One more folder we want to make is going to be the Output folder. This is where all the patches will be saved. There will be two more options to deal with. We want to set compression to HIGH and in the Options tab we want to set the file type to ACSII. It should reflect the below image. Once that's set we can click "Generate" to make the first patch. It will be create in the Output folder we selected. That's all there is too it! You've created your first patch. STEP FIVE: Sending The Patch (Sending Patches) i2.5.0 We now have it all. The Patcher & The Patch. Things are great. But how do we send it to players withing them having to redownload the entire GRF? Great question! In this next step we will cover how to add the patch to the webserver and get it ready for players to recieve when they load their patchers. In step i2.3.0 we covered how to set the patcher up in the web server. This is the file structure we will continue to follow moving forward. Let's open open up our file browser for accessing the server trunk, if needed, or it you're running your own system you can also navigate to the web server folder. The directories are the same either way. /var/www/custom/patch/ This is the directory we wil be working in regarding the patcher. It should now represent the image below: Let's break this down first... We have: The data folder. This is where we will add the patches into after we name them. The Background image. This will be a back ground image for the patcher to load. You can even leave this transparent if you want. Our main.ini is where we will configure the settings for the patcher. We will go through this soon. The notice page will be need to be updated with each news change. This is a very simple text edit. Keep it short and simple. Our patch list text file is where we will add the patches. The format will be discussed soon. Our Style sheet. This is the style arrangements for the pages. We usually don't need to modify this unless we know what we're doing. First thing to do after we have a patch made is to give it a name. What do you ask? A very specific name. In this example we will follow a date format with a part value in the event of more than one patch in a day. Our name in this example will be the date followed by a version number, or update number. 24012024-1 This well tell me that the patch was set for today and it's the first path released of that day. Now we can edit the plist.txt and add this patch into the list. Inside the patch list we will enter in the exact namme of the patch. Including the ending. Our names will start with an index number first. This is the order at which the patcher will read the patches. The index starts at 0 and is followed by a SPACE and then the item name. 1 24012024-1.thor Save and it's ready to load through the patcher! Finally we need to tell the website to send patches to players. Open up the main.ini file with a text editor. We're going to modify the line that asks for a website address. Search for "file_url=" ad edit that to be your website. Save and it's ready to go! That's pretty much it for uploading patches to the server. You're all set to start updating players with new content! STEP SIX: Adding/Removing Maps (map_cache.dat) i2.6.0 Got a enw map you want to try out or is your current map not up to date with your pathing? In this step we're going to add maps to the map_cache.dat, remove maps if needed and update the list with our new maps. First start by downloading the Map Cache Editor from the trusted rAthena source: HERE You'll be presented with a window that looks like this: What we want to do next is download our map_cache.dat from the server trunk: rAthena/db/map_cache.dat Once downloaded it will be able to drag and drop that file into this window. We now are presented with a list of maps. From here what we want to do is drag and drop all our map's .gat files from our GRFs into this window. this will update the walkable paths for the map. This is especially important when you cannot walk on certain maps due to old GAT configurations, It still thinks there are structures in the way. To delete a map you can select it and click delete. Simple as that. Save the Map Cache and reupload it to your server. That's it! Nice and quick. Section 3 - Optional Options Things are running now, yeah? That's great to hear. Sometimes they may require additional software, maybe another step or two, or maybe you need something else for it all to work. Below are some steps that are completely optional but might just help you out in some situations. STEP ONE: Forwarding a Router (Port Forwarding) o3.1.0 Understanding what port forwarding is will be an important start to not having your network breached. In this step we will go through the basics of forwarding your port through your router. The user interface (menus) will look different for each router brand, however, the concept will remain the same universally. Check your router software for updates before making any changes. Let's begin! Accessing the Router To access the router we want to first ensure we are connected to the internet using it. Next we will open the trouter software through our web-browser. To access that page we will have to enter the local domain IP to gain access to the initial menu. In your address bar enter in: 192.168.1.1 If this DOES NOT work try entering in: 192.168.0.1 My basic Netgear modem has a menu that looks like this. I'm going to want to click into Advanced Settings & open up the Port Forwarding option. We are now presented with a window similar to this. It will give us all options for forwarding our ports. Let's get an understanding of what's here before we continue... We will select between Forwarding and Triggering. Since we don't need to trigger a port we will focus only on Forwarding it. There are many types of services that might be precompiled in your router. For our Ragnarok Online server will be making a custom service. It's not as hard as it sounds, don't worry! The device IP we want to connect is a little different. It has to be exactly what device you have the server under. Let's navigate to the device list on the router. This will be under the "basic" settings, usually. It shows here I have 3 devices listed. An Amazon Fire stick, My cell phone and a PC I built specifcally for this guide. That's exactly what we are looking for, too! It looks like the device I am forwarding resides under the IP ending with 7. Okay, so we now understand where the ports are going to and waht device has them. So it's time to make that custom service we spoke of earlier. This interface has a button, making it very convenient to start. We're going to go ahead and click the "Add Custom Service" button. With the custom port window we can now add our ports for Ragnarok to run. We will need to process this 1 number of times as we have more than one port for Ragnarok Online services. The ports we need to add are: 3306, 6900, 5121, 6121, 8888 Make sure to select the proper device for it to work as we want it to. After they are all applied, it will represent something similar to this: That's it! Your ports are now open & ready for users to connect through to. Make sure firewalls are enabled at all times. STEP TWO: Automatic Server Backups (World Runner) o3.2.0 This script will automatically save your server to your server_backup folder every 24 hours. This time is completely adjustable in time and destination. I originally made this for Minecraft hence the name World Runner. Open the terminal and enter in the command: sudo nano /etc/systemd/system/worldrunner.service This will create a service script we will set to run on start up. Inside this document we are going to add int the following script and change the destination values to match our back up folder destination: [Unit] Description=This will copy the Server folder to a back-up location [Service] Restart=always RuntimeMaxSec=1d User=raguser ExecStart=cp -r /home/raguser/Server/rAthena /var/www/raguser/Documents/server_backups/ RemainAfterExit=yes [Install] WantedBy=multi-user.target Now we want to enable it on start-up: sudo systemctl enable worldrunner If you're having issues with it executing properly we can simply grant permissions to the file to do so: sudo chmod 600 /etc/systemd/system/worldrunner.service We now have the trunk backing up now, but what about the SQL server? For that we need to edit a default file structure in Ubuntu called Cron. Cron can hold automated tasks on a timer, or schedule, just like what we want to do for backing up MySQL. Enter in the terminal: sudo nano /etc/crontab You'll be presented with a window simial to this: As you can see here they are displaying each value for the job. First digits represents Minutes and the second digits represents Hours. These are the two we'll primarily need for daily backups to occur. At the very bottom we are going to add the following line: (NOTE: Include your password after the -p. My password is "69SuperStrongPass69" so the password section will look like -p69SuperStrongPass69 ) 0 0 * * * root mysqldump -u raguser -p69SuperStrongPass69 --all-databases | gzip > /home/raguser/Documents/Rag_SQL/ragserver_`date +%d%m%Y-%H:%M:%S`.sql.gz This will set the back up time to be at Midnight each night using the PMA login we set up earlier, backing up our ragserver database into a zip file at the directory ~/Documents/Rag_SQL. NOTE: Avoid use of these symbols in the password field: ) ( ' ` Finally we need to restart the service for it to take effect: sudo /etc/init.d/cron restart That's all there is to it! Keep up to date with the latest changes & updates to this guide. Want to see something included? Suggest it below!
  8. I am trying to make Swordmans Recovery into an active skill. I added the table to skill_db.yml (the cooldowns and durations seems to work) Added the "activate" effects (the skill is activable, have mana cost, duration, and shows an "duration icon" at the left side of the screen) But i dont know how to edit the status.cpp in order to make the ability only work when it's active. For now, my SM_RECOVERY works ALL THE TIME as a pasive skill (no matter if you have the in-game skill activated or no) I am not sure how to edit this.... any help? if( sd ) { struct regen_data_sub *sregen; if( (skill=pc_checkskill(sd,HP_MEDITATIO)) > 0 ) { val = regen->sp*(100+3*skill)/100; regen->sp = cap_value(val, 1, SHRT_MAX); } /////-------------------THIS----------------------//// if ((skill = pc_checkskill(sd, SM_RECOVERY)) > 0) { val += skill * 50 + skill * status->max_hp / 500; // just skill*50 for testing regen->hp = cap_value(val, 0, SHRT_MAX); } ////---------------------------------------------//// // Only players have skill/sitting skill regen for now. sregen = regen->sregen;
  9. Right so, ive got a wierd issue i cant seem to figure out, all job names are "Poring", I did some changes to Msg_conf & Pcjobname.lub and Msgstringtable to have some custom names, they all turned to Poring, however i changed all of these back (to unedited versions to make sure i didnt make a mistake) AND ITS STILL PORING.. Edit : My client version is 20231104 and Server is the latest rA to provide potentially relevant details. I'd appreciate any advice on how i might solve this issue / where to look, thank you
  10. Thank you both! I want to make it as useful as possible for players - I personally long for a good db when I'm playing p-servers, sometimes we're lucky if the p-server even has one. A more friendly design will eventually come when it's time, butwe're first focusing on content and features. Please feel free to join our discord to keep up with the project
  11. I created servers 12 years ago, could anyone help me change the loadscreen video or a tutorial. pre-re.. thankss! SOU BRASILEIRO, BR #BRAZIL
  12. This is not tested under renewal. I think it should still work, but test it with a GM character first. The default implementation of Homunculi is kind of obnoxious. When you create one, you get one of the homunculi at random, and in order to get another one, you have to completely delete them from existence. Wouldn't it be nice if you could keep the other homunculi to use later? Well, now you can! What it does: - When you use rest, the Homunculus returns to its Embyro. - You can use Call Homunculus to call it back out, just as it was when you rested it. - You can store the Homunculus for later use, allowing you to raise a different Homunculus, which is not normally possible. - Only you can call the Homunculus back out. If another alchemist tries to call it, it doesn't let them. - You can still delete the Homunculi as normal to remove them from existence completely. How it works from a technical perspective: - When you rest the homunculus, it is technically "removed" from you, similar to deleting it, but it returns an embyro with the Homunculus id set to its card[1] slot. - When you call out a Homunculus from an Embyro, if the embyro has a value in its card[1] slot, it restores that Homunculus instead of creating a new one. Some minor limitations: - It's not possible to distinguish embryos from each other, and call homunculus will always try to call the first one it finds in your inventory. You'll need to store the ones you don't want to raise right now, and it may take some trial and error to hatch the right one if you have a bunch. - The name display of the embryo doesn't work with the client I have (it seems like the client will only display the name if the card[1] slot is 0, which it's not if a homunculus is in there). This makes it hard to tell who owns a homunculus embyro. How to implement: Make the following code changes: In homunculus.cpp: Find the method "hom_vaporize": First, add the following variable declarations to the top, under the existing ones: int itemflag; struct item tmp_item; Next, comment out the following line: hd->homunculus.vaporize = flag ? flag : HOM_ST_REST; Then, insert the following at the end of the method, just before the return statement. if (hd->homunculus.intimacy > 0) { memset(&tmp_item, 0, sizeof(tmp_item)); tmp_item.nameid = 7142; tmp_item.amount = 1; tmp_item.identify = 1; tmp_item.card[0] = CARD0_CREATE; tmp_item.card[1] = hd->homunculus.hom_id; tmp_item.card[2] = GetWord(sd->status.char_id, 0); // CharId tmp_item.card[3] = GetWord(sd->status.char_id, 1); if ((itemflag = pc_additem(sd, &tmp_item, tmp_item.amount, LOG_TYPE_PRODUCE))) { clif_additem(sd, 0, 0, itemflag); if (battle_config.skill_drop_items_full) { map_addflooritem(&tmp_item, tmp_item.amount, sd->bl.m, sd->bl.x, sd->bl.y, 0, 0, 0, 0, 0); } } unit_remove_map(&hd->bl, CLR_OUTSIGHT); sd->status.hom_id = 0; unit_free(&hd->bl, CLR_OUTSIGHT); sd->hd = 0; return 1; } Next, find the method "hom_call": Find this code: if (!sd->status.hom_id) //Create a new homun. return hom_create_request(sd, HM_CLASS_BASE + rnd_value(0, 7)) ; Replace it with this: struct item ed; int n; // find the embryo if (!sd->status.hom_id) { //Create or revive a homun. if ((n = pc_search_inventory(sd, 7142)) >= 0) { ed = sd->inventory.u.items_inventory[n]; } else { return false; // no embryo } if (ed.card[1] != 0) { // is it ours? if (sd->status.char_id == MakeDWord(ed.card[2], ed.card[3])) { // revive the homun // delete the embryo pc_delitem(sd, n, 1, 0, 0, LOG_TYPE_CONSUME); sd->status.hom_id = ed.card[1]; // proceed with rest of function } else { // Cannot revive someone else's homunculus return false; } } else { // create a new homun // delete the embryo pc_delitem(sd, n, 1, 0, 0, LOG_TYPE_CONSUME); return hom_create_request(sd, HM_CLASS_BASE + rnd_value(0, 7)); } } Almost done, just one small change to make in skill.cpp. Find this line: if (sd->status.hom_id) //Don't delete items when hom is already out. And comment it out (we never want this method to delete the embyros, since the call method now handles it). Now just recompile your server and you should have the new homunculus behaviour.
  13. But it is something that can affect the server, this warning came now with git, but recently from rAthena.
  14. prontera,164,156,4 script Sortudo::sorte 4_M_LGTMAN,{ Init: mes "[Sortudo]"; if(getgmlevel()>10 && getgmlevel()<99){ mes "GM's não podem participar dos eventos!"; close; } if($SorteFechou==1){ mes "Desculpe estamos fechados"; }else { mes "O que deseja fazer hoje?"; } if(getgmlevel()>98) menu "Ir até o evento",Evento,"Tutorial do NPC",Tutorial,"Ver Drops",Alterar,"Cancelar",bye; menu "Ir até o evento",Evento,"Tutorial do NPC",Tutorial,"Ver Items possíveis de se ganhar",SeeItens,"Sair",bye; Alterar: next; mes "[Painel do GM]"; for(set @i,0; @i<=GetArraySize $DropsSorte-1; set @i,@i+2) mes @i/2+": "+$DropsSorte[@i+1]+" "+GetItemName($DropsSorte[@i]); mes "Prêmio em Zenys: "+$PremioZeny; mes "Deseja mudar algo?"; menu "Mudar um Item",muditem,"Adicionar um Item",aditem,"Mudar Prêmio em Zenys",pzeny,"Cancelar",bye; muditem: next; mes "[Painel do GM]"; for(set @i,0; @i<=GetArraySize($DropsSorte)-1; set @i,@i+2) mes @i/2+": "+$DropsSorte[@i+1]+" "+GetItemName($DropsSorte[@i]); mes "Digite o número do item a ser mudado:"; digit @ID; next; mes "[Painel do GM]"; mes "Deseja mesmo mudar o item "+$DropsSorte[@ID+1]+" "+GetItemName($DropsSorte[@ID])+" ?"; menu "Sim, Mudar o Item",mi,"Sim, Mudar a Quantidade Dropada",md,"Não, quero mudar outro item",muditem,"Não, não quero mudar nenhum item",bye; mi: next; mes "[Painel do GM]"; mes "Digite a ID do novo item:"; digit @newid; next; mes "[Painel do GM]"; mes "Você digitou: "+GetItemName(@newid); mes "Correto?"; menu "Sim",-,"Não!",mi,"Cancelar",bye; SetArray $DropsSorte[@ID],@newid; md: next; mes "[Painel do GM]"; mes "Digite a Quantidade a ser dropada do "+GetItemName($DropsSorte[@ID]); digit @newqnt; next; mes "[Painel do GM]"; mes "Você digitou: "+@newqnt; mes "Correto?"; menu "Sim",-,"Não!",md,"Cancelar",bye; SetArray $DropsSorte[@ID+1],@newqnt; next; goto Init; aditem: next; mes "[Painel do GM]"; mes "Digite a ID do novo item:"; digit @newid; next; mes "[Painel do GM]"; mes "Você digitou: "+GetItemName(@newid); mes "Correto?"; menu "Sim",-,"Não!",aditem,"Cancelar",bye; admd: next; mes "[Painel do GM]"; mes "Digite a Quantidade a ser dropada do "+@newid; digit @newqnt; next; mes "[Painel do GM]"; mes "Você digitou: "+@newqnt; mes "Correto?"; menu "Sim",-,"Não!",admd,"Cancelar",bye; next; mes "[Painel do GM]"; mes "O Item ficou assim: "+@newqnt+" "+GetItemName(@newid); mes "Correto?"; menu "Sim!",-,"Não, Mudar Item",aditem,"Não, Mudar Quantidade a se Dropada",admd,"Cancelar",Init; next; mes "[Painel do GM]"; mes "Item Adicionado com Sucesso!"; SetArray $DropsSorte[GetArraySize($DropsSorte)],@newid,@newqnt; next; goto Init; pzeny: next; mes "[Painel do GM]"; mes "Caso o jogador não drope o item, ele morrerá ou ganhará uma quantia em zeny"; mes "Digite qual será esta quantia"; digit @Zeny; next; mes "[Painel do GM]"; mes "Você digitou "+@Zeny+" está correto?"; menu "Sim, está",-,"Não, quero mudar a quantia",pzeny; next; smes "[Painel do GM]"; mes "Zenys Configurados com Sucesso!"; set $PremioZeny,@Zeny; next; goto Init; bye: mes "[Sortudo]"; mes "Até Mais!"; close; SeeItens: next; mes "[Sortudo]"; mes "Estes são os itens que podem cair dos baús:"; for(set @i,0; @i<=GetArraySize($DropsSorte)-1; set @i,@i+2) mes @i/2+": "+$DropsSorte[@i+1]+" "+GetItemName($DropsSorte[@i]); mes "Prêmio em Zenys: "+$PremioZeny; next; goto Init; Evento: next; if($SorteFechou==1){ mes "[Sortudo]"; mes "Desculpe-me, mas os Warps estão fechados..."; close; } mes "[Sortudo]"; mes "Vamos lá!"; Set @place,Rand(3); if($EventoSorte==2){ if(@place==0) warp "quiz_02",37,52; if(@place==1) warp "quiz_02",49,52; if(@place==2) warp "quiz_02",61,52; if(@place==3) warp "quiz_02",73,52; close; }else if($EventoSorte==3){ if(@place==0) warp "quiz_02",318,34; if(@place==1) warp "quiz_02",330,34; if(@place==2) warp "quiz_02",342,34; if(@place==3) warp "quiz_02",354,34; close; }else if($EventoSorte==4){ warp "quiz_02",304,234; close; } Tutorial: next; mes "[Sortudo]"; mes "O evento se chama ^FF0000Evento da Sorte^000000 pois"; mes "você precisa de muita sorte nele"; next; mes "[Sortudo]"; mes "Você entra em uma sala, onde será pvp!"; mes "Após 2 Minutos, aparecerá um baú que permitirá que você passe para o nível 2, para lutar pelo Prêmio Final"; next; mes "[Sortudo]"; mes "Mas há um modo onde não há nível 2, mas há 2 Baús de Prêmio!!"; next; mes "[Sortudo]"; mes"Os items que serão dropados do baú serão configurados pelos GMs do BeatRO!"; close; OnHour01: OnHour05: OnHour09: OnHour13: OnHour17: OnHour21: set $EventoSorte,Rand(2,4); Set $SorteFechou,0; Announce "[NPC]Sortudo: O Evento da sorte está prestes a começar! Seja rápido e corra! Você tem 5 minutos!",0; initnpctimer; end; OnTimer300000: //set $EventoSorte,1; Set $SorteFechou,1; Announce "[NPC]Sortudo: Os warps fecharam, sinto muito tente da próxima vez!",0; SetMapFlag "quiz_02",mf_pvp; SetMapFlag "quiz_02",mf_pvp_noparty; SetMapFlag "quiz_02",mf_pvp_noguild; MapAnnounce "quiz_02","O Evento da Sorte Começou!",8; end; OnTimer420000: if($EventoSorte==2){ monster "quiz_02",37,73, "Tesouro Passaporte",1732,1,"sorte::OnPassouNivel21"; monster "quiz_02",49,73, "Tesouro Passaporte",1732,1,"sorte::OnPassouNivel22"; monster "quiz_02",61,73, "Tesouro Passaporte",1732,1,"sorte::OnPassouNivel23"; monster "quiz_02",73,73, "Tesouro Passaporte",1732,1,"sorte::OnPassouNivel24"; }else if($EventoSorte==3){ monster "quiz_02",319,57, "Tesouro Passaporte",1732,1,"sorte::OnPassouNivel31"; monster "quiz_02",331,57, "Tesouro Passaporte",1732,1,"sorte::OnPassouNivel32"; monster "quiz_02",343,57, "Tesouro Passaporte",1732,1,"sorte::OnPassouNivel33"; monster "quiz_02",355,57, "Tesouro Passaporte",1732,1,"sorte::OnPassouNivel34"; }else if($EventoSorte==4){ monster "quiz_02",297,267, "Tesouro Final",1732,1,"sorte::OnGanhou"; monster "quiz_02",311,267, "Tesouro Final",1732,1,"sorte::OnGanhou"; } end; //Evento 2 OnPassouNivel21: warp "quiz_02",37,80; MapAnnounce "quiz_02",strcharinfo(0)+" Passou para o Nível 2!!!",8; areawarp "quiz_02",33,52,41,73,"prontera",155,185; end; OnPassouNivel22: warp "quiz_02",49,80; MapAnnounce "quiz_02",strcharinfo(0)+" Passou para o Nível 2!!!",8; areawarp "quiz_02",45,52,53,73,"prontera",155,185; end; OnPassouNivel23: warp "quiz_02",61,80; MapAnnounce "quiz_02",strcharinfo(0)+" Passou para o Nível 2!!!",8; areawarp "quiz_02",57,52,65,73,"prontera",155,185; end; OnPassouNivel24: warp "quiz_02",73,80; MapAnnounce "quiz_02",strcharinfo(0)+" Passou para o Nível 2!!!",8; areawarp "quiz_02",69,52,73,73,"prontera",155,185; end; //Evento 3 OnPassouNivel31: warp "quiz_02",319,60; MapAnnounce "quiz_02",strcharinfo(0)+" Passou para o Nível 2!!!",8; areawarp "quiz_02",314,34,323,57,"prontera",155,185; end; OnPassouNivel32: warp "quiz_02",331,60; MapAnnounce "quiz_02",strcharinfo(0)+" Passou para o Nível 2!!!",8; areawarp "quiz_02",326,34,335,57,"prontera",155,185; end; OnPassouNivel33: warp "quiz_02",343,60; MapAnnounce "quiz_02",strcharinfo(0)+" Passou para o Nível 2!!!",8; areawarp "quiz_02",338,34,347,57,"prontera",155,185; end; OnPassouNivel34: warp "quiz_02",355,60; MapAnnounce "quiz_02",strcharinfo(0)+" Passou para o Nível 2!!!",8; areawarp "quiz_02",350,34,359,57,"prontera",155,185; end; //Continua Evento (Nivel 2 agora!) OnTimer430000: MapAnnounce "quiz_02","Parabéns a Vocês que passaram ao Nível 2, mas o Evento ainda não Acabou!",8; end; OnTimer435000: MapAnnounce "quiz_02","O Tesouro Final aparecerá em 1 minuto e meio!!!",8; end; //O Tesouro Final! OnTimer540000: MapAnnounce "quiz_02","O Tesouro Final apareceu!!!",8; if($EventoSorte==2){ monster "quiz_02",54,95, "Tesouro Final",1732,1,"sorte::OnGanhou"; }else if($EventoSorte==3){ monster "quiz_02",338,83, "Tesouro Final",1732,1,"sorte::OnGanhou"; } end; OnTimer600000: killmonsterall "quiz_02"; RemoveMapFlag "quiz_02",mf_pvp; RemoveMapFlag "quiz_02",mf_pvp_noparty; RemoveMapFlag "quiz_02",mf_pvp_noguild; StopNpcTimer; end; OnGanhou: set .@Prize, rand(2); if(.@Prize == 0){ set @premio,Rand(GetArraySize($DropsSorte)/2); additem $DropsSorte[@premio*2],$DropsSorte[@premio*2+1]; warp "prontera.gat",155,185; Announce "[NPC]Sortudo: O jogador "+strcharinfo(0)+" quebrou um dos baús, seu prêmio foi: "+getitemname($DropsSorte[@premio*2])+"",4; end; } if(.@Prize == 1){ set Zeny,Zeny+$Premiozeny; warp "prontera.gat",155,185; Announce "[NPC]Sortudo: O jogador "+strcharinfo(0)+" quebrou um dos baús, seu prêmio foi "+$Premiozeny+" zenys",4; end; } if(.@Prize == 3){ atcommand "@kill "+strcharinfo(0)+""; Announce "[NPC]Sortudo: Mas que pena, o jogador "+strcharinfo(0)+" quebrou um dos baús e, além de não ganhar nada, morreu!",4; end; } OnInit: waitingroom " Sortudo "+.server$+" ",0,"",0; if(!GetArraySize($DropsSorte)) SetArray $DropsSorte[0],20000,5; end; } //MapFlag quiz_02.gat mapflag nomemo quiz_02.gat mapflag nowarp quiz_02.gat mapflag nowarpto quiz_02.gat mapflag noicewall quiz_02.gat mapflag nosave quiz_02.gat mapflag noteleport quiz_02.gat mapflag nopenalty quiz_02.gat mapflag nobranch
  15. Do you have very old clients or emulators lying around? Maybe that old hard drive with RO stuff? How about those old CD-Rs on the shelf? Or are you simply a RO data hoarder? WE WANT YOU! Hi, I’m vit. I’m developing along with o oldinroplayer a *Ragnarok Online Cross-Episode Database*, called RagnaDB. It’s a db in which you’re able to choose a specific episode and we’ll show you all the info precisely as it was back in the day. The idea is for it to be the “one RO database to rule them all”. For this to exist, there’s a great deal of historical research and digital data scavenging involved. Since we’re committed to historical accuracy, we’re on a journey to finding old files (client and server) to feed the db with, as well as (old) reliable sources for data validation. If you were waiting for the right moment to shine and looking for a group of people who will truly appreciate and see value in those dozens of RO gigabytes collecting dust like no one ever had, this is the moment! We’ll love to have you! If any of the words above piqued your interest, you’re more than welcome here. Join our Discord to hear about the latest updates or just hang around! Our Discord: https://discord.gg/cueAdED64N RagnaDB: https://ragnadb.com/
  16. This only 1-200 base level, how i can make calculation to base 500? BaseExp: - Level: 1 Exp: 600 - Level: 2 Exp: 1080 - Level: 3 Exp: 1800 - Level: 4 Exp: 2640 - Level: 5 Exp: 3840 - Level: 6 Exp: 4560 - Level: 7 Exp: 5040 - Level: 8 Exp: 5460 - Level: 9 Exp: 6000 - Level: 10 Exp: 6600 - Level: 11 Exp: 7200 - Level: 12 Exp: 7320 - Level: 13 Exp: 7620 - Level: 14 Exp: 8040 - Level: 15 Exp: 8820 - Level: 16 Exp: 9600 - Level: 17 Exp: 10080 - Level: 18 Exp: 10560 - Level: 19 Exp: 11040 - Level: 20 Exp: 12610 - Level: 21 Exp: 13390 - Level: 22 Exp: 14300 - Level: 23 Exp: 15340 - Level: 24 Exp: 16900 - Level: 25 Exp: 18460 - Level: 26 Exp: 19500 - Level: 27 Exp: 20800 - Level: 28 Exp: 22100 - Level: 29 Exp: 23400 - Level: 30 Exp: 24700 - Level: 31 Exp: 26000 - Level: 32 Exp: 27300 - Level: 33 Exp: 28600 - Level: 34 Exp: 30160 - Level: 35 Exp: 31200 - Level: 36 Exp: 33800 - Level: 37 Exp: 35750 - Level: 38 Exp: 37700 - Level: 39 Exp: 39000 - Level: 40 Exp: 44100 - Level: 41 Exp: 46200 - Level: 42 Exp: 47600 - Level: 43 Exp: 50400 - Level: 44 Exp: 52500 - Level: 45 Exp: 53200 - Level: 46 Exp: 56000 - Level: 47 Exp: 58800 - Level: 48 Exp: 62300 - Level: 49 Exp: 65800 - Level: 50 Exp: 68600 - Level: 51 Exp: 71400 - Level: 52 Exp: 74200 - Level: 53 Exp: 77000 - Level: 54 Exp: 79800 - Level: 55 Exp: 82600 - Level: 56 Exp: 86100 - Level: 57 Exp: 88200 - Level: 58 Exp: 91000 - Level: 59 Exp: 93800 - Level: 60 Exp: 103500 - Level: 61 Exp: 105000 - Level: 62 Exp: 109500 - Level: 63 Exp: 115500 - Level: 64 Exp: 120000 - Level: 65 Exp: 126000 - Level: 66 Exp: 132000 - Level: 67 Exp: 136500 - Level: 68 Exp: 142500 - Level: 69 Exp: 165000 - Level: 70 Exp: 192000 - Level: 71 Exp: 210000 - Level: 72 Exp: 232500 - Level: 73 Exp: 244500 - Level: 74 Exp: 255000 - Level: 75 Exp: 270000 - Level: 76 Exp: 282000 - Level: 77 Exp: 292500 - Level: 78 Exp: 300000 - Level: 79 Exp: 345000 - Level: 80 Exp: 416000 - Level: 81 Exp: 480000 - Level: 82 Exp: 560000 - Level: 83 Exp: 640000 - Level: 84 Exp: 768000 - Level: 85 Exp: 880000 - Level: 86 Exp: 960000 - Level: 87 Exp: 1088000 - Level: 88 Exp: 1200000 - Level: 89 Exp: 1440000 - Level: 90 Exp: 1700000 - Level: 91 Exp: 2040000 - Level: 92 Exp: 2550000 - Level: 93 Exp: 3060000 - Level: 94 Exp: 3570000 - Level: 95 Exp: 4080000 - Level: 96 Exp: 4760000 - Level: 97 Exp: 5610000 - Level: 98 Exp: 6800000 - Level: 99 Exp: 1272747 - Level: 100 Exp: 1354202 - Level: 101 Exp: 1440870 - Level: 102 Exp: 1533085 - Level: 103 Exp: 1631202 - Level: 104 Exp: 1735598 - Level: 105 Exp: 1846676 - Level: 106 Exp: 1964863 - Level: 107 Exp: 2090614 - Level: 108 Exp: 2224413 - Level: 109 Exp: 2366775 - Level: 110 Exp: 2518248 - Level: 111 Exp: 2679415 - Level: 112 Exp: 2850897 - Level: 113 Exp: 3033354 - Level: 114 Exp: 3227488 - Level: 115 Exp: 3434047 - Level: 116 Exp: 3653826 - Level: 117 Exp: 3887670 - Level: 118 Exp: 4136480 - Level: 119 Exp: 4401214 - Level: 120 Exp: 4755467 - Level: 121 Exp: 5138234 - Level: 122 Exp: 5551810 - Level: 123 Exp: 5998675 - Level: 124 Exp: 6481508 - Level: 125 Exp: 7003204 - Level: 126 Exp: 7566891 - Level: 127 Exp: 8175950 - Level: 128 Exp: 8834032 - Level: 129 Exp: 9545083 - Level: 130 Exp: 10313366 - Level: 131 Exp: 11143488 - Level: 132 Exp: 12040427 - Level: 133 Exp: 13009560 - Level: 134 Exp: 14056699 - Level: 135 Exp: 15188122 - Level: 136 Exp: 16410613 - Level: 137 Exp: 17731503 - Level: 138 Exp: 19158711 - Level: 139 Exp: 20700795 - Level: 140 Exp: 22367001 - Level: 141 Exp: 24167320 - Level: 142 Exp: 26112547 - Level: 143 Exp: 28214345 - Level: 144 Exp: 30485317 - Level: 145 Exp: 32939080 - Level: 146 Exp: 35590346 - Level: 147 Exp: 38455012 - Level: 148 Exp: 41550255 - Level: 149 Exp: 44894635 - Level: 150 Exp: 48508204 - Level: 151 Exp: 52412629 - Level: 152 Exp: 56631321 - Level: 153 Exp: 61189576 - Level: 154 Exp: 66114724 - Level: 155 Exp: 71436298 - Level: 156 Exp: 77186205 - Level: 157 Exp: 83398922 - Level: 158 Exp: 90111701 - Level: 159 Exp: 97364791 - Level: 160 Exp: 105201683 - Level: 161 Exp: 113669366 - Level: 162 Exp: 122818613 - Level: 163 Exp: 132704283 - Level: 164 Exp: 143385650 - Level: 165 Exp: 154926760 - Level: 166 Exp: 167396814 - Level: 167 Exp: 180870583 - Level: 168 Exp: 195428856 - Level: 169 Exp: 211158924 - Level: 170 Exp: 229155105 - Level: 171 Exp: 246519309 - Level: 172 Exp: 266361648 - Level: 173 Exp: 287801097 - Level: 174 Exp: 310966207 - Level: 175 Exp: 352013746 - Level: 176 Exp: 398479560 - Level: 177 Exp: 451078861 - Level: 178 Exp: 510621270 - Level: 179 Exp: 578023277 - Level: 180 Exp: 654322349 - Level: 181 Exp: 740692899 - Level: 182 Exp: 838464361 - Level: 183 Exp: 949141656 - Level: 184 Exp: 1074428354 - Level: 185 Exp: 1216252896 - Level: 186 Exp: 1376798278 - Level: 187 Exp: 1558535650 - Level: 188 Exp: 1764262355 - Level: 189 Exp: 1997144985 - Level: 190 Exp: 2260768123 - Level: 191 Exp: 2559189515 - Level: 192 Exp: 2897002530 - Level: 193 Exp: 3279406863 - Level: 194 Exp: 3712288568 - Level: 195 Exp: 4202310658 - Level: 196 Exp: 4757015664 - Level: 197 Exp: 5384941731 - Level: 198 Exp: 6095754039 - Level: 199 Exp: 6900363572 - Level: 200 Exp: 9999999999
  17. You need to make the skill give a status change (which I assume you did). Then in the regen code you want to check for the status change instead of the skill being learned.
  18. View File Quest Point System [PT-BR] O sistema consiste em da 1 quest/missão ao player, o jogador que a fizer ganhará 1 Ponto de Quest, esses pontos o player porá usar para trocar por custons ou algo de seu interesse, as quest são sorteadas de forma aleatória dentre as dificuldades, e os Admins/GMs podem adicionar itens de quest in-game assim como podem editar também. Obs: Mais em baixo deixarei uns videos relacionado ao sistema, o script tem algumas alterações se comparado com os videos mas nada de mais. Obs2: Caso alguém encontre algum bug ou queira da sugestões fique a vontade, farei assim que puder. [ENG] The system consists of 1 quest to the player, the player who makes it complete earn 1 Quest Point, and these points you can use to exchange for custom or something of interest to you, the quests are random, and the Admins / GMs can add quest items in-game like this you can edit too. Note: Below I will leave some videos related to the system, the script has some changes compared to the videos but nothing major. Note2: The translation is not very good, but I believe can understand it, you can make suggestions for me to make the improvement. Videos: Submitter Hyroshima Submitted 04/11/2021 Category Games, Events, Quests Video Content Author Hyroshima  
  19. Hello everyone, my name is Terran Bear. I'm somewhat new to the world of rAthena publicly. I've been working on some things here and there in the shadows, trying to create a great new server (almost a new game). Using Renewal I've only been running into a few problem lately. So far I've put 3 1/2 months of time into recreating the maps. Moving ALL mvp's to boss rooms inside of new custom dungeons, spread around the world ending with a boss on the bottom floor of each of these new dungeons. With new and old mobs defending the boss' room. (There will be no MVP's running loose on maps) I'm also recreating ALL the quests into a huge story questline and many side quests to follow for plenty of play time. As well as a tutorial to learn how the new system works. The whole job system is going to be turned off and the sprites clothing of other jobs will be available from purchase(Zeny) as a costume from special NPC's throughout the world. I'll also be turning the Novice into what I call "Adventurer"(Has a never before seen sprite). Through questlines and level/stat requirements to learn skills, making all skills available to anyone depending on how you play. I'm also trying to make some new skills. I want this server to be something never seen before. So I'm not going into further details other then, I'm looking for someone's help... honestly saying, I need a bit of guidance from you pro's out there... Also not trying to sound stupid, but if you do have answers to this please go into detail on what to do.... 1. How in the world do I disable ALL except Novice jobs....? (also would it be possible to delete job levels?) 2. How do i create custom skills with renewal? 3. How do I make sprites for armor and garments? (not costumes but the equipment (Valkyrie Armor, etc) Once I get a bit further and finish a majority of whats on my list, I'll create a video or group of Screenshots to present the world to you. I'll also update this post with information on how the story will play out. Thank you, Terran Bear Creator of Project Mayhem
  20. Buenos días! Tengo una duda muy simple, pero su resolución es bastante compleja y realmente no sé exactamente como hacerlo. Asi que les cuento mi proyecto y mis ideas para que me puedan ayudar: Quiero crear un servidor que fundamentalmente será PRE RENEWAL, pero con varias mecánicas RENEWAL. (Solo 2das clases/Rebirth. No 3eras clases) El mayor problema que tengo, es que quiero “el mundo” renewal: mapas, instancias, eden group (además, tener la “ventaja” de ya tener importados todos los skills y objetos RENEWAL para poder editar simplemente la base de datos y ya poder sin utilizarlos, sin tener que cargar sprites, etc…). Pero el sistema de daño/defensa/objetos que quiero es PRE RENEWAL…. (donde la defensa de los objetos es PORCENTUAL, y por eso los objetos tienen números bases muy bajos, lo cual me gusta), agregando algunos pocos RENEWAL (editándolos a modo de objetos custom) Entonces mi dilema es que no se que sería mas fácil de implementar…. Si crear un servidor PRE RENEWAL e ir “importando” (¿pegando?): · los scripts y sources referidos a EDEN GROUP (es posible?) · skills de 3eras clases (solo quiero los skills) · editar las formulas de cálculo de CASTEO/DEX, habilitar los doble ataques críticos · Editar una selección de objetos renewal (de las 3eras y 4tas clases) para hacer custom items · Crear instancias en un servidor pre renewal. O si es mejor crear un servidor RENEWAL e ir “limitando” las mecánicas que quiero que sean PRE RENEWAL · Editar el /src para que el juego calcule la defensa en modo PRE RENEWAL · Editar/Deshabiltiar todos los objetos con sus valores RENEWAL (esto lo veo muy complicado) · Importar los objetos pre-renewal (no lo veo facil) para no cargarlos/editarlos uno por uno Espero sus comentarios y consejos. Mil gracias!
  21. Good night guys, how are you? I don't know if I can post it here... But I believe it can serve both me and the community. I have the scripts 3 vs 3 party, capture the flag. The same as the old Xilero PK. But the problem is that it is not working on my server. Could someone with knowledge in the area be giving me support? If all goes well I'll be making the scripts available to all of you too. I believe that something is missing in the src, but I have no knowledge in the script area.
  22. Hello, as stated in my title. I am currently looking for updated soul link mods for 255/120 highrate server. Example is Rogue's bypass strip
  23. View File GRF Editor Hey everyone, This is a GRF tool I started to develop for my own personnal use, but I thought I'd share it since I've upgraded the UI. Its primary goal is to be easy to use while offering a wide variety of options and customizations. The software is quite stable and can handle large operations easily. How to install Download the zip archive provided from the download link at the bottom of this description or directly from there : http://www.mediafire.com/?aflylbhblrzpz0h Install the application with GRF Editor Installer.exe; if you are missing a .NET Framework you will be prompted to download it. Once you are done, you can start the program from the link on your desktop. Key features Overall speed is faster (or at least equal) than any GRF tool. Common operations : add, delete, merge, extract, preview, save. Undo and redo for any operation. It can open any GRF file. Clean and very interactive interface. Saving formats supported : 0x200, 0x103 and 0x102 (through the Settings page) and conversion to the Thor format. Instant filter and search options (example : "map .gat"). File association and context menus integration for .grf, .gpf, .rgz and .thor (through the Settings page). Can rebuild separated images into one file easily. Drag and drop (with the ALT key, can be modified in the Settings page). This is a big part of the software; most of the items can be moved around within the application itself or from/to Windows Explorer. Tools Sprite editor : a simple sprite editor with powerful features. Semi-transparent images can be added, you can easily change the order or replace images, etc. This tool can convert images in the wrong type by showing you multiple solutions (merging a new palette, dithering the image by using current palette, using the closest color, and a few more). Grf validation : allows you to validate a GRF with multiple settings. It can detect corrupted GRF entries, invalid sprites, empty files, non-GRF files, duplicate files and a lot more. Flat maps maker : generates flat maps from .gat and .rsw files. Useful to generate WoE maps or to fasten up the loading time. Patch maker : generates a GRF patch based on two different GRFs. Hash viewer : shows the hash code (both CRC32 and MD5) for files. Image converter : converts an image to any format requested (BMP, PNG, JPG, TGA). GrfCL : used to create batch files (.bat) which can automate tasks on GRF files. See the content in GrfCL.rar in the download for more information. This tool can be customized from the sources as well. Palette recolorer : creates new sprites by changing their colors (this tool is now deprecated). Client database editor : allows modifications of the database client files (txt and lua) with easy and simple tools. Work in progress. Grf encryption The encryption feature has been enabled again. It's similar to what it used to be and it has been tested on client versions ranging from 2012-08-01 to 2014-02-05. Some error messages will be displayed if necessary. If you have an issue, copy the error message (with the code, if there's one) and send me the client executable with the cps.dll file generated by GRF Editor. There shouldn't be compatibility issues anymore though! Thor files Thor files are patches used by Thor Patcher ( http://thor.aeomin.net/ ). Because of their similarity with the GRF file structure, they have been integrated within GRF Editor. The primary utility of this feature is that it allows you to add encrypted files to a Thor patch. All the other options can be achieved by using Thor Maker. You'll find the necessary steps below, but test your patches before sending them off to players (I've done a lot of testing on my end, but better be safe). If you're using SecureGRF, then make a new GRF, add the files and encrypt it. In GRF Editor, open the encrypted GRF you just made, use "Save as" and name the new file with a .thor extension. That's it, if you want to change the output directory, click on the root node of the project and select the tab "Container options". You can select the output mode and the GRF to merge the patch with. Simply save again if you change these properties. If you're using GRF Editor's encryption, then make a new Thor file (File > New > New Thor) and add the files you want to patch it with. Right-click on the files you want to encrypt and use Encryption > Encrypt. Technical stuff Requires .Net Framework 3.5 (SP1) Client Profile to run (3.5 or more will work as well). Automatically converts file name encoding to their proper values (you can change the encoding). Data virtualization is used as much as possible to preview files, meaning the files aren't completely loaded. Right-clicking an item will bring up the available options with that file. Preview file formats : txt, log, xml, lua, lub, bmp, png, tga, jpp, db, ebm, pal, gnd, rsw, gat, rsm, str, spr, act, imf, fna and wav. Services are "crash ready", meaning that you will be warned about a failed operation and no work will be lost (the application won't close and crash). It tries to continue operating even if it meets unsual conditions. Operations can be cancelled by clicking on the button near the progress bar. The warning level can be changed to avoid messages like "Please select a folder first." When prompted with an error, use Ctrl-C to copy the current dialog's content. Some screenshots! 1) Previewing an act file, while showing the search feature 2) Preview of a model file (rsm) 3) Preview of GrfCL with the MakeGrf command 4) Preview of maps 5) Preview of Grf validation 6) Search feature (press Ctrl-F or Ctrl-H to bring up within a text editor) Got a feedback? I'd gladly hear you out and fix issues you have with the program. Submitter Tokei Submitted 01/11/2013 Category GRF Files Video Content Author Tokeiburu  
  24. That is... a strange issue, I'm not able to reproduce it. If you opened GRF Editor without the "Always reopen latest opened GRF", you will get a template GRF as such: As you can see, the window title is "GRF Editor - new *", with a star at the end, meaning it hasn't been saved yet. It also has a "data" folder in it. In your screenshot, you have neither. That means you've opened an actual GRF, but that also doesn't make sense since an opened GRF will display the full path in the title. As much as I'd like to fix this issue, it doesn't seem possible to reproduce. The error shows that the magic string is empty instead of "Master of Magic". That looks like an empty file...? That also doesn't make much sense. I would need additional information (well, assuming that error is worth fixing since it doesn't seem to trigger normally at all).
  25. View File All In One - Random Options Script The goal in this script is to allow you to create any random option enchantment system by just creating a new copy of this script , change the script name and setting You should be able to create any random option system exist currently in the game DO NOT PM ME FOR ERRORS Use the forum post to report for any bugs and errors the script allow you to create a group of items > you can create as many groups as you want each group has it's own options allow reroll or not put price for first time and price for the reroll after the first time the price can be zeny, cashpoints, custom points, items put random options for all slots or specific slot of the random options slot put exclusive random options groups so they cannot coexist in the same item The script config and example AT LINE 290 in the script file > OnInit: .exv = true;//DO NOT REMOVE THIS. .KeepItemData = true;//if this is 'false , the player will loss the refine+cards from the item when he use this npc. .CustomPointsVariable$ = "#COSTUMPOINTS";//The variable name of the costum points. .CustomPointsName$ = "Server RO Points";//The name of the costum points, this what the player will see. .HardBalance = true;//if this is true , it would be much harder to get high value in the random option. //AddGroup(<Group ID>,<ItemID>,<ItemID>,<ItemID>,<ItemID>,<ItemID>); /* AddGroup Doc <Group ID> = a number between 1 and MAX_INT64 DO NOT REUSE THE GROUP ID IN THE SAME FILE CONFIG! DO NOT REUSE THE SAME ITEM ID IN DIFFERENT GROUP! will create a group id you can add as many as you want items inside a group. */ //AddGroupOption(<Group ID>,<Allow ReRoll?true:false>,<Allow reuse already gotten option?true:false>,<Zeny Cost>,<CashPoint Cost>,<Custom Points Cost>,<Item1 ID Cost>,<Item1 Amount Cost>,<Item2 ID Cost>,<Item2 Amount Cost>,<....ETC>); /* AddGroupOption Doc <Group ID> = A group id that is already created in AddGroup()!. <Allow ReRoll?true:false> = allow reroll an item with random option or not <Allow reuse already gotten option?true:false> = for exammple if you have str in the options and the player gor it , can he get it again in another slot? */ //AddGroupCost(<Group ID>,<Zeny Cost>,<CashPoint Cost>,<Custom Points Cost>,<Item1 ID Cost>,<Item1 Amount Cost>,<Item2 ID Cost>,<Item2 Amount Cost>,<....ETC>); /* AddGroupCost Doc <Group ID> = A group id that is already created in AddGroup()!. <Zeny Cost> = the zeny cost (can be 0) <CashPoint Cost> = the cashpoints cost (can be 0) <Custom Points Cost> = if you are using costum points in the script , check out .CustomPointsVariable$ and .CustomPointsName$ at the start of the script (can be 0) <Item1 ID Cost> = the item cost <Item1 Amount Cost> = the item amount cost You can use as many item,amount cost at the end of the function. */ //AddGroupReRollCost(<Group ID>,<Zeny Cost>,<CashPoint Cost>,<Custom Points Cost>,<Item1 ID Cost>,<Item1 Amount Cost>,<Item2 ID Cost>,<Item2 Amount Cost>,<....ETC>); /* AddGroupReRollCost Doc <Group ID> = A group id that is already created in AddGroup()!. <Zeny Cost> = the zeny cost (can be 0) <CashPoint Cost> = the cashpoints cost (can be 0) <Custom Points Cost> = if you are using costum points in the script , check out .CustomPointsVariable$ and .CustomPointsName$ at the start of the script (can be 0) <Item1 ID Cost> = the item cost <Item1 Amount Cost> = the item amount cost You can use as many item,amount cost at the end of the function. */ //AddGroupChance(<Group ID>,<1st Option Chance>,<2nd Option Chance>,<3rd Option Chance>,<4th Option Chance>,<5th Option Chance>); /* AddGroupChance Doc <Group ID> = A group id that is already created in AddGroup()!. <1st Option Chance> = the Chance to get one of the random options in the slot 1 (can be 0) <2nd Option Chance> = the Chance to get one of the random options in the slot 2 (can be 0) <3rd Option Chance> = the Chance to get one of the random options in the slot 3 (can be 0) <4th Option Chance> = the Chance to get one of the random options in the slot 4 (can be 0) <5th Option Chance> = the Chance to get one of the random options in the slot 5 (can be 0) Keep inmind that if the player didn't get lucky for example at the slot 2 , all the chances after will be ignored you cannot skip a random option slot that would bug the game client. */ //AddOpt(<Group ID>,<Location>,<Random Option ID>,<Minimum Value>,<Maximum Value>); /* AddOpt Doc <Group ID> = A group id that is already created in AddGroup()!. <Location> = you can spisfiy random option to a location from 1 to 5 , but you can use 0 , if you used 0 it will apply to all locations that doesn't have spisfied random options. <Random Option ID> = random option id , you can use the id or the variable , check out the file /rathena/db/re/item_randomopt_db.yml <Minimum Value> = the minimum value <Maximum Value> = the maximum value */ //AddExclusiveOpt(<Random Option ID>,<Random Option ID>,<Random Option ID>,<Random Option ID>,<Random Option ID>); /* AddExclusiveOpt Doc this will help you to prevent a group of random opions typs in the same item in different slots for example RDMOPT_DAMAGE_PROPERTY_NOTHING_TARGET RDMOPT_DAMAGE_PROPERTY_WATER_TARGET RDMOPT_DAMAGE_PROPERTY_GROUND_TARGET RDMOPT_DAMAGE_PROPERTY_FIRE_TARGET RDMOPT_DAMAGE_PROPERTY_WIND_TARGET RDMOPT_DAMAGE_PROPERTY_POISON_TARGET RDMOPT_DAMAGE_PROPERTY_SAINT_TARGET RDMOPT_DAMAGE_PROPERTY_DARKNESS_TARGET RDMOPT_DAMAGE_PROPERTY_TELEKINESIS_TARGET RDMOPT_DAMAGE_PROPERTY_UNDEAD_TARGET if the player got 1 of them in a slot , he wont get another one to another slot */ //Example!!!> //this is just an example , this script allow you to create any random option system you want. //Creating Group id 1 , with Hat items inside. AddGroup(1,2220,2221,2222,2223); //Group id 1 Options AddGroupOption(1,true,false); //Group id 1 Cost AddGroupCost(1,50,0,0,502,1,503,2); //Group id 1 ReRoll Cost AddGroupReRollCost(1,50,0,0,502,5,503,2); //Group id 1 Chances. AddGroupChance(1,100,75,60,40,20);AddGroupChance(1,100,100,100,100,100); //Group id 1 Random Option List. location 0 mean all the slot locations AddOpt(1,0,RDMOPT_VAR_STRAMOUNT,1,100); AddOpt(1,0,RDMOPT_VAR_INTAMOUNT,1,100); AddOpt(1,0,RDMOPT_VAR_VITAMOUNT,1,100); AddOpt(1,0,RDMOPT_VAR_LUKAMOUNT,1,100); AddOpt(1,0,RDMOPT_VAR_AGIAMOUNT,1,100); AddOpt(1,0,RDMOPT_VAR_DEXAMOUNT,1,100); AddOpt(1,0,RDMOPT_VAR_MAXHPPERCENT,1,100); AddOpt(1,0,RDMOPT_VAR_MAXSPPERCENT,1,100); //those enchantment you wont get unless in slot 5 AddOpt(1,5,RDMOPT_DAMAGE_PROPERTY_NOTHING_TARGET,1,100); AddOpt(1,5,RDMOPT_DAMAGE_PROPERTY_WATER_TARGET,1,100); AddOpt(1,5,RDMOPT_DAMAGE_PROPERTY_GROUND_TARGET,1,100); AddOpt(1,5,RDMOPT_DAMAGE_PROPERTY_FIRE_TARGET,1,100); AddOpt(1,5,RDMOPT_DAMAGE_PROPERTY_WIND_TARGET,1,100); AddOpt(1,5,RDMOPT_DAMAGE_PROPERTY_POISON_TARGET,1,100); AddOpt(1,5,RDMOPT_DAMAGE_PROPERTY_SAINT_TARGET,1,100); AddOpt(1,5,RDMOPT_DAMAGE_PROPERTY_DARKNESS_TARGET,1,100); AddOpt(1,5,RDMOPT_DAMAGE_PROPERTY_TELEKINESIS_TARGET,1,100); AddOpt(1,5,RDMOPT_DAMAGE_PROPERTY_UNDEAD_TARGET,1,100); //this mean those random options cannot coexist in the same item!. AddExclusiveOpt(RDMOPT_DAMAGE_PROPERTY_NOTHING_TARGET, RDMOPT_DAMAGE_PROPERTY_WATER_TARGET, RDMOPT_DAMAGE_PROPERTY_GROUND_TARGET, RDMOPT_DAMAGE_PROPERTY_FIRE_TARGET, RDMOPT_DAMAGE_PROPERTY_WIND_TARGET, RDMOPT_DAMAGE_PROPERTY_POISON_TARGET, RDMOPT_DAMAGE_PROPERTY_SAINT_TARGET, RDMOPT_DAMAGE_PROPERTY_DARKNESS_TARGET, RDMOPT_DAMAGE_PROPERTY_TELEKINESIS_TARGET, RDMOPT_DAMAGE_PROPERTY_UNDEAD_TARGET); end; https://sader1992.com/ Submitter sader1992 Submitted 09/09/2021 Category Utilities Video Content Author sader1992  
×
×
  • Create New...