B Tutorial Other Webserver as database for warband

Users who are viewing this thread

What does this mean? What is the purpose of this?

We all know that after closing the warband server, all variables are lost, because they are not stored/saved. To solve this problem, we can use a webserver for storing the values/restoring the values.(You can use WSE too, but it is not updated for latest version of warband).

Here are the steps that I will cover in this tutorial:
A.Setup a webserver (I will use usb webserver, because it is compact and easy to use, but any other webservers will work)
B.Making a mysql database
C.Making php pages that will handle warband's requests
D.Making warband codes in module system

(This tutorial will cover a simple example, how to store player's gold and restore it when the player joins the server)

So...let get started:

A. Setup a webserver

1.Download usbwebserver from here (click on the big blue "Download USBWebserver V8.6")
2.Save it into your computer
3.Unzip it
4.Go into 'settings' folder, and open up 'usbwebserver.ini'.
5.Change the port from '8080' to '80'
You done the settings. Now double click on 'usbwebserver.exe' from the main folder and select your language.
Now you should see this screen:
4JQAQ8e.png

If you have a red circle with an exclamation mark inside it near 'Apache' tab in right side, that means that apache could not start, and this is mostly caused by skype. To resolve this open skype->tools->options...->Advanced->Connection-> untick 'Use port 80 and 443 as alternatives for incoming connections' ->hit save and you are done.Now just restart the webserver and all should be good.

To see if the webserver is working, open up your favorite browser (internet explorer in my case(loltrain)) and type in the adress bar: 127.0.0.1. You should see a page with the title Usbwebserver.

B.Making a database

Once the server is working, we need to make a database in wich we will store our values. To do that, follow these steps:
1.Open your browser and type in 127.0.0.1/phpmyadmin/
2.Now type in the username 'root', and the password 'usbw'; hit Go
3.Now hit 'Databases' tab
wGfyRQO.png
4.Type in the name of the database (in our case will be 'example') and hit 'Create'
5.Now click on the left side, on 'example'. Now type in the name of the table ('players' in our case) and the number of rows (4 in our case: player unique id, username, gold, id) 
oeWlbhP.png
6.Now you should see the columns.
    The first column will be named as 'Unique_Id', type int, attributes 'Unsigned', index:'Unique'
    The second column: name:'Username', type text
    The third column: name:'Id', type int, attributes: 'unsigned', autoincrement on
    The fourth column: name:'Gold', type int, attributes: 'unsigned'
   
mq7TdkS.png
    Now hit the save button and we are done! Our database will contain the username , the unique id and the gold of the player. The column 'Id' is just for easy administration.


C.Making php pages that will handle warband's requests


1.Go into webserver's folder, then open up the folder 'root'. This is the folder from wich the server will get it's files (the one's that are requested by clients)
2.Create a file called 'example.php' (the extension NEEDS to be .php)
3.Open it up with your preferable text editor (notepad++ best)

We want the entire thing to work like this: warband will make a request on this php page, and will pass a variable called 'event' (using the GET method). If 'event' is 1, then we will request the player 's gold. If 'event' is 2, then we will save the player's gold. As we can see, we will need another 4 variables to pass: 'unique_id', 'local_id' (for feedback, for warband) , 'username' and 'gold'. In both cases, we will want to connect to mysql server, and select the database that we will work with. From here we will make a mysql query that will save/ get the player's gold. 

Inside 'example.php' we will put:
<?php
header_remove();
function set_content_length($output)
{
header("Content-Length: ".strlen($output));
return $output;
}
ob_start("set_content_length");
//the above part is for fixing a warband reading headers error
  if(isset($_GET['event']) && isset($_GET['unique_id']) && isset($_GET['local_id'])&& isset($_GET['username']))
    {
      $unique_id=$_GET["unique_id"];
$local_id=$_GET["local_id"];//for feedback only
$username=$_GET["username"];
     
      $db_handle = mysqli_connect("127.0.0.1", "root", "usbw", "example") or die("|-1");
      if($db_handle)
        if($_GET['event'] == 1)//get player gold
        {
          $sql_result = mysqli_query($db_handle, "SELECT Gold FROM players WHERE Unique_Id = '$unique_id'" );
          $result = mysqli_fetch_row($sql_result);
         
          if (!$result)
          {//the player is not in the database, so we will insert it
            mysqli_query($db_handle, "INSERT INTO players (Unique_Id,Username,Gold) VALUES($unique_id, '$username', 0)");
            echo "1|$unique_id|$local_id|0";//and we will echo gold as 0
          }else{
            echo "1|$unique_id|$local_id|1|".$result[0];
          }
        }else if($_GET['event'] == 2)//set player gold
        {
          if(isset($_GET['gold']))//if the gold is set
          {
            $gold = $_GET['gold'];
            mysqli_query($db_handle, "UPDATE players SET Gold='$gold' WHERE Unique_Id = '$unique_id'");
          }
        }
      mysqli_close($db_handle);
    }
   
?>

Now the php part is pretty much done! You can test it out with your browser: just type this http://127.0.0.1/example.php?unique_id=10&local_id=3&event=1&username=simple_example and the page should show '1|10|3|0' . Now if you type in this http://127.0.0.1/example.php?unique_id=10&local_id=3&event=2&username=simple_example&gold=40, the page will show blank, but in the database the player's gold changed to 40. You can type in again the first link ^^ and you should see that the page will show 40 instead of 0 .

D. Making warband codes in module system

I will make a native server side modification. You can download my native server side module system (it compiles much faster than the regular module system, because I removed almost all sp scripts and features, and all client side related things) from here.

How do we get the response of php page into warband module system?
The output of php scripts (echoed stuffs) will arrive into 'script_game_receive_url_response' under the form of integers and strings, stored into game registers. Basically if we echo '1|test|2|asd|3|user', the game will split the echo by '|', result in individual values: 1, test, 2, asd, 3, user. There resulting values are then compared to see if they are integers or strings. If the values is an integer, it will go into an integer register, if it is a string, it will go into a string register. So in the final, we will have
reg0 = 1
reg1 = 2
reg2 = 3
s0 = test
s1 = asd
s2 = user

We made the convention that the php echo will have this format 'event|unique_id|local_id|gold', so in the script_game_receive_url_response, reg0 will be the event, reg1 will be the unique id, reg2 will be the local id and finnaly reg3 will be the gold.

After setting up module system (module_info), open up module_scripts, and inside 'game_receive_url_response' paste this
(store_script_param, ":num_integers", 1),
    (store_script_param, ":num_strings", 2),
   
    (try_begin),
      (eq, ":num_integers", 0),
      (eq, ":num_strings", 1),
        (display_message, s0),#error will display in console window
    (else_try),
      (gt, ":num_integers", 0),#just in case
        (assign, ":event", reg0),
        (try_begin),
          (eq, ":event", -1),#could not connect to mysql server
            (display_message, "@Could not connect to the database!"),
        (else_try),
          (assign, ":unique_id", reg1),
          (assign, ":local_id", reg2),
         
          (eq, ":event", 1),#get player's gold
            (try_begin),
              (assign, ":gold", reg3),
           
              (player_is_active, ":local_id"),
              (player_get_unique_id, ":uid", ":local_id"),
             
              (eq, ":unique_id", ":uid"),
                (player_set_gold, ":local_id", ":gold"),
            (try_end),         
        (try_end),
    (try_end),

Now paste these 2 scripts at the bottom of module_scripts (before the last ']')
("save_player_gold",[
        (store_script_param_1, reg0),#must be active
       
        (player_get_unique_id, reg1, reg0),
        (player_get_gold, reg2, reg0),
        (str_store_player_username, s0, reg0),
        (send_message_to_url, "@http://127.0.0.1/example.php?unique_id={reg1}&local_id={reg0}&event=2&username={s0}&gold={reg2}"),
    ]),
   
    ("load_player_gold",[
        (store_script_param_1, reg0),#must be active
       
        (player_get_unique_id, reg1, reg0),
        (str_store_player_username, s0, reg0),
        (send_message_to_url, "@http://127.0.0.1/example.php?unique_id={reg1}&local_id={reg0}&event=1&username={s0}"),
    ]),

And this is pretty much all! If you call the script 'load_player_gold', with 1 parameter, player_id, the player's gold will be load from database. If you call the script 'save_player_gold' with player's id parameter, the player's gold will be save into database.

Ok ok if you really want to see it working, open up 'module_mission_templates', and search for 'multiplayer_dm'. You will finnaly find the missiont template for deathmach. Scrool down a little bit, and you will find the trigger 'ti_server_player_joined' . Inside it(at the end of it) put this:
        (call_script, "script_load_player_gold", ":player_no"),
Now right after 'ti_server_player_joined' trigger, put this trigger:
(ti_on_player_exit, 0, 0, [],
      [
          (store_trigger_param_1, ":player_no"),
          (call_script, "script_save_player_gold", ":player_no"),
      ]),
And you are done! Now if you will host the server with the gamemode deathmach, when you will enter the server for the first time you will have 0 gold. Kill some bots(or other players) and then rejoin the server. You will see that your gold will be the same as before you exit the server.(Note: restarting the server or changing the map or round end will not save the player's gold. For that you will need to add try_for_ players, that will call the script 'save_player_gold', where the map restart or change)

Quick note:
  For security only, you can send an extra value from warband to webserver that will act as a key/password (the value should be very big; like awkdhga2e878adiu32t) and in php script you should make something like:
      if(isset($_GET['rand']) && $_GET['rand'] == 'awkdhga2e878adiu32t')
            //do all the other ifs
 
i made the webserver thing and typed in the address thing and it just said webpage not available, what have i done wrong or need to do, i am using chrome if that is the problem

also i made the database but it gives me the error of '#1063 you have an error in your SQL syntax'
 
1. Is apache running? (in usbwebserver window there is a tab called 'Apache'. In it's right there should be a green circle)
2. How/where/when do you get that error? (from a quick google search, that error is a PHP related error and it should appear when you type in the browser the ip + file path)
 
i get the error when i went on the demo so that was probably the problem but the apache tab has a green circle and has a tick, even when i go through the tabs it says online but it just says when im on the internet search webpage unavailable
 
So if we're hosting game on a dedicated server do we run this webserver on the server we are renting?  Or do we run the webserver on our own pc?  I dont think the server provider will let me upload applications or exe files and I dont want to have my pc on 24/7.  Or is it hosted on an actual website?  I'm sorry I dont know anything about web servers yet...
 
Ok I guess that makes sense being PHP lol.  Hey thanks for posting this tutorial dude.  I'm sure many mod developers will appreciate this guide you've created.  I hope to be using it soon for the mod I am working on.
 
Ikaguia said:
This is very usefull indeed, I hope more people find this out cause I could see it being used for many things
I agree.
 
Back
Top Bottom