May 312009

Quite a few things to talk about. I’ve been coding quite diligently on the Soldat Client and Server this month, and have greatly improved the ScriptCore, enough to label it as ScriptCore v3. But I am certainly not done yet, still have to recode the threading and test things. I will go into detail further down in this post, click Read More.

EnEsCe needs YOU! As most of you know, Soldat 1.5 is plagued with problems for certain systems which had no problem with Soldat 1.4.2… Due to the nature of these issues, I am unable to test fixes myself; so I need some people to help me test 1.5.1 binaries. If you meet ALL of the following requirements, please contact me ASAP via email and I will give you my IM addresses. I use almost every form of IM client.

* You get Access Violations when starting or exiting Soldat 1.5
* You get a blank screen when starting/joining a game in Soldat 1.5
* You do NOT get the above problems in 1.4.2, only in Soldat 1.5!
* You have any other bug preventing you from playing Soldat 1.5, but you dont get this bug in 1.4.2
* You must be online frequently during daylight times. No school kiddies, sorry.
* Speak and Type very good English. Ppl hu typ liek dis shld di in righteous fire.

The sooner people come forward to help, the sooner Soldat 1.5.1 can be released.

* ScriptCore v3 Progress

MySQL: If you have been following me on Twitter for awhile, you may have seen me mention I was fiddling with MySQL functions. Well, after a week or so of thorough testing, I can safely say that MySQL support is now possible in the ScriptCore. All types of queries are functioning correctly, SELECT, INSERT, DELETE, UPDATE etc. And before you security freaks ask, yes mysql_escape_string is an added function :P. I have modeled the function names and syntax to closely resemble PHP’s MySQL functions; but not exactly the same. These functions will require safe mode disabled.
Here are some examples of whats possible, code is from a login system I wrote for the purpose of testing these functions.

procedure Login(ID: Byte; Username,Password: string);
var
  QueryStr: string;
  _qry: integer;
begin
  Player[ID].Threads.Login := true;
  try
    Password := MD5String(Password); // Password MD5
    QueryStr := 'SELECT * FROM users WHERE `username`='''+mysql_escape_string(Username)+''' AND `password`='''+Password+''';';
    DebugMsg('SQL: '+QueryStr);
    _qry := mysql_query(_sql,QueryStr);
    if mysql_numrows(_qry) > 0 then begin
      if mysql_fetch_valuebyname(_qry,'loggedin') = '1' then begin
        // Account is already logged in! GTFO please >:\
        WriteConsole(ID,'Login failed. That account is already logged in by "'+mysql_fetch_valuebyname(_qry,'lastname')+'"',clRed);
        mysql_free_result(_sql); // Free the result since it has been assigned, but wont be used again.
        Player[ID].Threads.Login := false;
        exit;
      end;
      // Load SQL data into TPlayerInfo type
      Player[ID].Login.ID := strtoint(mysql_fetch_valuebyname(_qry,'id'));
      Player[ID].Login.Username := mysql_fetch_valuebyname(_qry,'username');
      Player[ID].Login.SQLRowID := _qry;
      // Update the last used time(Unix time), IP, and ingame name of the account. And set the status to logged in
      QueryStr := 'UPDATE users SET `lastlogin`='''+inttostr(time())+''', `lastip`='''+GetPlayerStat(ID,'ip')+''', `lastname`='''+mysql_escape_string(GetPlayerStat(ID,'name'))+''', `loggedin`=''1'' WHERE `id`='''+inttostr(Player[ID].Login.ID)+''';'
      mysql_free_result(mysql_query(_sql,QueryStr));
      WriteConsole(ID,'Login success! Welcome '+Player[ID].Login.Username+'!',clGreen);
      Player[ID].Threads.Login := false;
    end else begin
      mysql_free_result(_sql); // No account found, free the result to save memory.
      Player[ID].Login.ID := 0;
      WriteConsole(ID,'Login failed. Incorrect username or password',clRed);
      Player[ID].Threads.Login := false;
    end;
  finally
    Player[ID].Threads.Login := false;
  end;
end;

Pretty simple, eh? Maybe not… heh. So, as you can see, mysql_query() will return an integer; which will be the Result ID for use when fetching values from any selected rows. And most importantly, you must always call mysql_free_result() when you no longer need to access the result of a certain query! Every query remains in memory until you call that function. Which can lead to high memory usage, and eventually access violations and crashes.
Here’s sample code for connecting:

procedure ActivateServer();
var QueryStr: string;i: integer;
begin
  //** Connect to the MySQL server on localhost **//
  _sql := mysql_connect('localhost','root','password','ec_stats',3); // 3 second connect timeout
  if mysql_connected(_sql) = false then begin
    WriteLn(' [*] MySQL connection failed.');
    WriteLn('     '+mysql_error(_sql)); end
  else begin
    WriteLn(' [*] MySQL connection established. IndexID: '+inttostr(_sql));
    // We must set all accounts to logged out, so
    QueryStr := 'UPDATE users SET `loggedin`=''0'' WHERE `loggedin`=''1'';'
    mysql_free_result(mysql_query(_sql,QueryStr));
    for i := 1 to 32 do Logout(i); // Logout all users and tell them, incase script was just recompiled
  end;
end;

procedure AppOnIdle(Ticks: integer);
var i: byte;
begin
  //** Every 10 seconds, check if MySQL is connected. If not, reconnect! **//
  if Ticks mod (60 * 10) = 0 then
    if mysql_connected(_sql) = false then begin
     WriteLn(' [*] MySQL disconnected. Attempting to reconnect...');
      mysql_reconnect(_sql);
    end;
end;

Again, pretty simple. In my testing, I was using the “persistent connection” approach, which means A) Constantly connected to MySQL B) alot of threading… Which also ofcourse means alot of crashes. Bummer, eh? Most of the time queries completed in ~0.03 seconds, so there was no humanly noticeable lag or freezes caused by it. But that may change if selecting from a poorly designed database without indexes or a very large database.
If you have any questions, comments, or suggestions regarding the MySQL implementation so far, please leave a comment. I am eager for feedback!

New Events: There will be some new events available, including:
OnGameEnd()
-- Called before OnMapChange, so player scores and current map etc have not been reset yet.
OnFlagDrop(Thrown: boolean) -- Called when a flag is dropped. I am not 100% sure yet if throwing will be included, as that can be abused by players in a very bad way. I won’t go into details publicly :)
OnSurvivalRoundEnd() -- As the name suggests, event will be called when a survival round ends.
OnSurvivalRoundStart() -- Come on, you can’t possibly need a description for this one aswell…
Thats all so far. I know alot of other events have been requested, but most of them won’t be added because calling any event too frequently will cause a crash. This is specifically why AppOnIdle remains at 1 second call frequency; and why I will not add OnFire.

SetPlayerStat: Well, it wont be as fancy as most people want. But the function will exists nevertheless. I have only created the base for the function so far, but will add some fancy things and publicise them eventually.

GetWeaponStat: Hohoho. I don’t think I will be able to explain the awesomeness of this function with words, so I will just paste a code sample from my login system again.

QueryStr := 'UPDATE wepstats SET `shots`=`shots`+'+inttostr(GetWeaponStat(ID,b,'shots'))+', `hits`=`hits`+'+inttostr(GetWeaponStat(ID,b,'hits'))+', `kills`=`kills`+'+inttostr(GetWeaponStat(ID,b,'kills'))+', `headshots`=`headshots`+'+inttostr(GetWeaponStat(ID,b,'headshots'))+' WHERE `id`='+inttostr(Player[ID].Login.ID)+' AND `wepID`='+inttostr(GetWeaponStat(ID,b,'num'))+' LIMIT 1;';

Drooling yet? The possibilities for stats scripts is absolutely amazing with these functions… Accuracy, anyone? Also, aimbotters beware… I hope I wont have to exclude these functions from release; but at the moment the weapon stats collection code is sometimes causing access violations after running for many hours in the latest dedicated server software (2.6.5).

Thats all I will say for the moment, there are still alot more features I want to add but have not yet planned out a way to implement them.

* Soldat 1.5.1 Release Date

… Will not be announced yet! Muahaha. Sorry, anywho, I’d just like to announce that there will not be any public beta for Soldat 1.5.1. The change log will also not be released until 1.5.1 is finished. Do not bother asking me on IRC for a release date or changes, no exceptions.

* Non-Soldat related junk

I enjoy sharing things that make me laugh/amazed/wtf, so here you go ^-^

Lag in Real Life: *cough* Soldat *cough*

Damien Walters Parkour

… Look at the Quote on the right, then look at the image on the left.
QuoteOfTheDay


Please leave a comment on this article if you enjoyed reading it or have a suggestion. I’d like to know how my posts are being perceived by other people :)

auf Wiedersehen!

8 Responses to “ScriptCore v3, Soldat 1.5.1, and MySQL”

  1. aq says:

    Probably more logical syntax would be OnRoundEnd() and OnRoundStart() instead of OnGameEnd/OnMapChange but I guess backward compatibility is more important than logically designed syntax.

    • EnEsCe says:

      A ’round’ in Soldat is not when a map changes, it is when a round of Survival ends… So using those event names would only confuse people.

  2. ]{ing says:

    The weapon stat function is a welcomed feature no doubt. I’d like to add that an Accuracy script is quite possible already under the current ScriptCore, I’ve been able to achieve this for one. However it’s not 100% accurate(pun non-intentional).

    MySQL support seems intriguing. My biggest problem with it is that you’re adding a massive feature while the rest of the core could still use work. I for one, much rather see the existing scripting framework get fortified and improved before moving on to such a big step. I foresee that this new ‘feature’ will mostly introduce much more new bugs(due to lack of testing/coding or w/e) and draw attention from parts of the core that would provide instant benefits. The AppOnIdle event comes to mind right of the bat. The fact that calling this event at the speed(s) exceeding 1Hz crashes the system is just silly(at this stage of the script cores progress at least). I won’t mention multi-threading because I do realise that this is a non-trivial issue and a REALLY complicated ‘feature’. Which also makes me wonder why its even in a game scripts engine(which one would expect to be much simpler).

    At this point in Soldat development I for one have a problem with what is now and for a while has been considered improvement to the game(and/or scriptcore) and that is a wave of new features that is expected and almost ‘demanded’ from the developer(s). I’d rather much see a much more concrete and well thought out version of the game that is currently out there. Instead of the same buggy game with a few new ‘features’ glued on top of it.

    I call upon you Nick Cooper to snap out of your funk and step back for a second and take a long,hard look where this project is headed. Because it does not look good. Maybe its time to stop trying to please everyone with useless features that will only benefit a small amount of people and concentrate on writing code that YOU could actually be proud of.

  3. xmRipper says:

    Hahah i really like the GetWeaponStat function.

    Thanks for your effort to making those =) Keep it up.

  4. CurryWurst says:

    HELL YES – That’s wicked!

    Well done EnEsCe. Keep it up :P

    Hope to see some more fancy vids like the “Lag in Real Life” in the future :D

    Thank ya!

  5. croat1gamer says:

    Nice GetWeaponStat.

    You forgot the eating in soldat on the vid ;D

    Also, it isnt “Aufiderzein!” but “Aufwiedersehen!” :P

  6. iDante says:

    I wet myself out of excitement when I saw GetWeaponStat.

    This is amazing, thank you.

Leave a Reply

(required)

(required)

Valium prescription online
Order viagra online without prescription
Where can i buy viagra cheap
Xanax generic
Buy viagra london
Dose of valium
Valium for sale in ireland
Phentermine 37.5 pills
Cialis generic online
Prednisone pharmacy
Xanax buy canada
Brand name viagra
Viagra online free sample
25 mg valium
Levitra cheapest
Best price phentermine
Where to buy tramadol online without prescription
Xanax cheap
Phentermine online prescription
Cheap viagra alternatives
Cheap valium no prescription
Non prescription phentermine
Generic viagra in us
Generic cialis
Propecia cheapest
Order tramadol cod overnight delivery
Levitra online pharmacy
Purchase of viagra
Cheapest phentermine without a prescription
Canadian pharmacy levitra
Best place to buy viagra uk
Buy phentermine 37.5 mg
Phentermine 37.5mg without prescription
Generic tramadol online
Canadian pharmacy online cialis
Buy cialis tadalafil
Cialis sales online
Xanax 1 mg
Get tramadol online
Order viagra by phone
Generic viagra pharmacy
Cheap xanax no prescription
Generic viagra free shipping
Viagra 100 mg pricing
Viagra 100mg pfizer
Buy phentermine diet pills online
Generic viagra canada no prescription
Online cialis reviews
Best propecia prices
Buy valium no prescription
Phentermine diet pills without prescription
0.5 mg xanax
Buy phentermine without prescription in australia
Pfizer viagra online without prescription
Generic levitra
Where can i buy valium in the uk
Cheap tramadol cod
Phentermine online free shipping
Female viagra cheap
Tramadol buy
Uk viagra prices
Viagra drug store
Prednisone tablets
Buy viagra with no prescription
Generic viagra online without prescription
Levitra samples
Ordering phentermine without prescription
Buy phentermine online mastercard
Xanax online
Propecia without prescription
Viagra without prescription in canada
Cheap propecia no prescription
Phentermine 37.5 mg without a prescription
Cialis 20 mg dosage
Xanax prices
Xanax side effects
Purchase viagra uk
Buy cheap valium online without prescription
Best viagra generic
Doses of prednisone
Side effects of propecia
Order tramadol online without prescription
Phentermine 37.5 mg no prescription
Buy phentermine no prescription
Tramadol for sale uk
Viagra cheap canada
Prescription for cialis
Best price for phentermine
Cheap xanax
How to buy cialis without a prescription
50 mg tramadol
Generic tramadol
Buy propecia in the uk
Prescription valium
Viagra express delivery
Where to buy phentermine 37.5 without a prescription
1 mg xanax bar
Viagra shop
Cialis drug information
Generic viagra 25mg