]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/commitdiff
Merge remote-tracking branch 'origin/mand1nga/bot-assault'
authormand1nga <mand1nga@xonotic.org>
Wed, 17 Aug 2011 22:37:49 +0000 (19:37 -0300)
committermand1nga <mand1nga@xonotic.org>
Wed, 17 Aug 2011 22:37:49 +0000 (19:37 -0300)
defaultXonotic.cfg
qcsrc/common/urllib.qc [new file with mode: 0644]
qcsrc/common/urllib.qh [new file with mode: 0644]
qcsrc/server/miscfunctions.qc
qcsrc/server/playerstats.qc
qcsrc/server/progs.src

index f5efdc6852acdae5537255c3e6ee12f780b2c222..3dc51da56553df8c0ceb4a05c886bfeec4b16ceb 100644 (file)
@@ -450,8 +450,8 @@ set bot_ai_aimskill_offset 0.3 "Amount of error induced to the bots aim"
 set bot_ai_aimskill_think 1 "Aiming velocity. Use values below 1 for slower aiming"
 set bot_ai_custom_weapon_priority_distances "300 850"  "Define close and far distances in any order. Based on the distance to the enemy bots will choose different weapons"
 set bot_ai_custom_weapon_priority_far   "minstanex nex rifle electro rocketlauncher grenadelauncher hagar hlac crylink laser uzi fireball seeker shotgun tuba minelayer"       "Desired weapons for far distances ordered by priority"
-set bot_ai_custom_weapon_priority_mid   "minstanex rocketlauncher nex fireball seeker grenadelauncher electro uzi rifle crylink hlac hagar shotgun laser tuba minelayer"       "Desired weapons for middle distances ordered by priority"
-set bot_ai_custom_weapon_priority_close "minstanex shotgun nex uzi hlac tuba seeker hagar crylink grenadelauncher electro rifle rocketlauncher laser fireball minelayer"       "Desired weapons for close distances ordered by priority"
+set bot_ai_custom_weapon_priority_mid   "minstanex rocketlauncher nex fireball seeker grenadelauncher electro uzi crylink hlac hagar shotgun laser rifle tuba minelayer"       "Desired weapons for middle distances ordered by priority"
+set bot_ai_custom_weapon_priority_close "minstanex shotgun nex uzi hlac tuba seeker hagar crylink grenadelauncher electro rocketlauncher laser fireball rifle minelayer"       "Desired weapons for close distances ordered by priority"
 set bot_ai_weapon_combo 1      "Enable bots to do weapon combos"
 set bot_ai_weapon_combo_threshold 0.4  "Try to make a combo N seconds after the last attack"
 set bot_ai_friends_aware_pickup_radius "500"   "Bots will not pickup items if a team mate is this distance near the item"
diff --git a/qcsrc/common/urllib.qc b/qcsrc/common/urllib.qc
new file mode 100644 (file)
index 0000000..f7af9a4
--- /dev/null
@@ -0,0 +1,250 @@
+// files (-1 for URL)
+.float url_fh;
+
+// URLs
+.string url_url;
+.float url_wbuf;
+.float url_wbufpos;
+.float url_rbuf;
+.float url_rbufpos;
+.float url_id;
+.url_ready_func url_ready;
+.entity url_ready_pass;
+
+entity url_fromid[NUM_URL_ID];
+float autocvar__urllib_nextslot;
+
+float url_URI_Get_Callback(float id, float status, string data)
+{
+       if(id < MIN_URL_ID)
+               return 0;
+       id -= MIN_URL_ID;
+       if(id >= NUM_URL_ID)
+               return 0;
+       entity e;
+       e = url_fromid[id];
+       if(!e)
+               return 0;
+       if(e.url_rbuf >= 0 || e.url_wbuf >= 0)
+       {
+               print(sprintf("WARNING: handle %d (%s) has already received data?!?\n", id + NUM_URL_ID, e.url_url));
+               return 0;
+       }
+
+       // whatever happens, we will remove the URL from the list of IDs
+       url_fromid[id] = world;
+
+       if(status == 0)
+       {
+               // WE GOT DATA!
+               float n, i;
+               n = tokenizebyseparator(data, "\n");
+               e.url_rbuf = buf_create();
+               e.url_rbufpos = 0;
+               if(e.url_rbuf < 0)
+               {
+                       print("buf_create: out of memory\n");
+                       e.url_ready(e, e.url_ready_pass, URL_READY_ERROR);
+                       strunzone(e.url_url);
+                       remove(e);
+               }
+               for(i = 0; i < n; ++i)
+                       bufstr_set(e.url_rbuf, i, argv(i));
+               e.url_ready(e, e.url_ready_pass, URL_READY_CANREAD);
+               return 1;
+       }
+       else
+       {
+               // an ERROR
+               e.url_ready(e, e.url_ready_pass, -status);
+               strunzone(e.url_url);
+               remove(e);
+               return 1;
+       }
+}
+
+void url_fopen(string url, float mode, url_ready_func rdy, entity pass)
+{
+       entity e;
+       float i;
+       if(strstrofs(url, "://", 0) >= 0)
+       {
+               switch(mode)
+               {
+                       case FILE_WRITE:
+                       case FILE_APPEND:
+                               // collect data to a stringbuffer for a POST request
+                               // attempts to close will result in a reading handle
+                               e = spawn();
+                               e.classname = "url_fopen_file";
+                               e.url_url = strzone(url);
+                               e.url_fh = -1;
+                               e.url_wbuf = buf_create();
+                               if(e.url_wbuf < 0)
+                               {
+                                       print("buf_create: out of memory\n");
+                                       rdy(e, pass, URL_READY_ERROR);
+                                       strunzone(e.url_url);
+                                       remove(e);
+                                       return;
+                               }
+                               e.url_wbufpos = 0;
+                               e.url_rbuf = -1;
+                               rdy(e, pass, URL_READY_CANWRITE);
+                               break;
+
+                       case FILE_READ:
+                               // read data only
+                               for(i = autocvar__urllib_nextslot; i < NUM_URL_ID; ++i)
+                                       if(url_fromid[i] == world)
+                                               break;
+                               if(i >= NUM_URL_ID)
+                               {
+                                       for(i = 0; i < autocvar__urllib_nextslot; ++i)
+                                               if(url_fromid[i] == world)
+                                                       break;
+                                       if(i >= autocvar__urllib_nextslot)
+                                       {
+                                               rdy(world, pass, URL_READY_ERROR);
+                                               return;
+                                       }
+                               }
+
+                               e = spawn();
+                               e.classname = "url_fopen_file";
+                               e.url_url = strzone(url);
+                               e.url_fh = -1;
+                               e.url_rbuf = -1;
+                               e.url_wbuf = -1;
+                               if(!crypto_uri_postbuf(url, i + MIN_URL_ID, string_null, string_null, -1, 0))
+                               {
+                                       rdy(e, pass, URL_READY_ERROR);
+                                       strunzone(e.url_url);
+                                       remove(e);
+                                       return;
+                               }
+                               e.url_ready = rdy;
+                               e.url_ready_pass = pass;
+                               e.url_id = i;
+                               url_fromid[i] = e;
+                               cvar_set("_urllib_nextslot", ftos(mod(i + 1, NUM_URL_ID)));
+                               break;
+               }
+       }
+       else
+       {
+               float fh;
+               fh = fopen(url, mode);
+               if(fh < 0)
+               {
+                       rdy(world, pass, URL_READY_ERROR);
+                       return;
+               }
+               else
+               {
+                       e = spawn();
+                       e.classname = "url_fopen_file";
+                       e.url_fh = fh;
+                       if(mode == FILE_READ)
+                               rdy(e, pass, URL_READY_CANREAD);
+                       else
+                               rdy(e, pass, URL_READY_CANWRITE);
+               }
+       }
+}
+
+void url_fclose(entity e, url_ready_func rdy, entity pass)
+{
+       float i;
+
+       if(e.url_fh < 0)
+       {
+               if(e.url_wbuf >= 0)
+               {
+                       for(i = autocvar__urllib_nextslot; i < NUM_URL_ID; ++i)
+                               if(url_fromid[i] == world)
+                                       break;
+                       if(i >= NUM_URL_ID)
+                       {
+                               for(i = 0; i < autocvar__urllib_nextslot; ++i)
+                                       if(url_fromid[i] == world)
+                                               break;
+                               if(i >= autocvar__urllib_nextslot)
+                               {
+                                       buf_del(e.url_wbuf);
+                                       rdy(e, pass, URL_READY_ERROR);
+                                       strunzone(e.url_url);
+                                       remove(e);
+                                       return;
+                               }
+                       }
+                       print(ftos(i), "\n");
+
+                       if(!crypto_uri_postbuf(e.url_url, i + MIN_URL_ID, "text/plain", "", e.url_wbuf, 0))
+                       {
+                               buf_del(e.url_wbuf);
+                               rdy(e, pass, URL_READY_ERROR);
+                               strunzone(e.url_url);
+                               remove(e);
+                               return;
+                       }
+
+                       buf_del(e.url_wbuf);
+                       e.url_wbuf = -1;
+                       e.url_ready = rdy;
+                       e.url_ready_pass = pass;
+                       e.url_id = i;
+                       url_fromid[i] = e;
+                       cvar_set("_urllib_nextslot", ftos(mod(i + 1, NUM_URL_ID)));
+               }
+               else
+               {
+                       // we have READ all data
+                       rdy(e, pass, URL_READY_CLOSED);
+                       buf_del(e.url_rbuf);
+                       strunzone(e.url_url);
+                       remove(e);
+               }
+       }
+       else
+       {
+               // file
+               fclose(e.url_fh);
+               rdy(e, pass, URL_READY_CLOSED); // closing creates no reading handle
+               remove(e);
+       }
+}
+
+// with \n
+string url_fgets(entity e)
+{
+       if(e.url_fh < 0)
+       {
+               // curl
+               string s;
+               s = bufstr_get(e.url_rbuf, e.url_rbufpos);
+               e.url_rbufpos += 1;
+               return s;
+       }
+       else
+       {
+               // file
+               return fgets(e.url_fh);
+       }
+}
+
+// without \n
+void url_fputs(entity e, string s)
+{
+       if(e.url_fh < 0)
+       {
+               // curl
+               bufstr_set(e.url_wbuf, e.url_wbufpos, s);
+               e.url_wbufpos += 1;
+       }
+       else
+       {
+               // file
+               fputs(e.url_fh, s);
+       }
+}
diff --git a/qcsrc/common/urllib.qh b/qcsrc/common/urllib.qh
new file mode 100644 (file)
index 0000000..a7735ed
--- /dev/null
@@ -0,0 +1,16 @@
+float URL_READY_ERROR    = -1;
+float URL_READY_CLOSED   =  0;
+float URL_READY_CANWRITE =  1;
+float URL_READY_CANREAD  =  2;
+// errors: -1, or negative HTTP status code
+typedef void(entity handle, entity pass, float status) url_ready_func;
+
+void url_fopen(string url, float mode, url_ready_func rdy, entity pass);
+void url_fclose(entity e, url_ready_func rdy, entity pass);
+string url_fgets(entity e);
+void url_fputs(entity e, string s);
+
+// returns true if handled
+float url_URI_Get_Callback(float id, float status, string data);
+#define MIN_URL_ID 128
+#define NUM_URL_ID 64
index 9b0324755a41669bc1b6d0a750a306d45d481bba..09e2dfb05d4b60e64154b00498cc919b3369fc50 100644 (file)
@@ -2045,7 +2045,11 @@ void URI_Get_Callback(float id, float status, string data)
     dprint(data);
     dprint("\nEnd of data.\n");
 
-    if (id == URI_GET_DISCARD)
+    if(url_URI_Get_Callback(id, status, data))
+    {
+        // handled
+    }
+    else if (id == URI_GET_DISCARD)
     {
         // discard
     }
index c691d542bb63f2cf4bf44ec2c61ce009faee12c2..7f20b92454db5084718d1ca79df4a4cef219fb76 100644 (file)
@@ -284,10 +284,10 @@ void PlayerStats_AddGlobalInfo(entity p)
 
        // add global info!
        if(p.alivetime)
+       {
                PlayerStats_Event(p, PLAYERSTATS_ALIVETIME, time - p.alivetime);
-
-       if(p.alivetime)
-               PlayerStats_Event(p, PLAYERSTATS_ALIVETIME, time - p.alivetime);
+               p.alivetime = 0;
+       }
 
        db_put(playerstats_db, sprintf("%s:_netname", p.playerstats_id), ftos(p.playerid));
        
@@ -297,7 +297,7 @@ void PlayerStats_AddGlobalInfo(entity p)
     if(teamplay)
                db_put(playerstats_db, sprintf("%s:_team", p.playerstats_id), ftos(p.team));
 
-       if(p.alivetime > 0)
+       if(stof(db_get(playerstats_db, sprintf("%d:%s", p.playerstats_id, PLAYERSTATS_ALIVETIME))) > 0)
                PlayerStats_Event(p, PLAYERSTATS_JOINS, 1);
 
        strunzone(p.playerstats_id);
@@ -328,7 +328,7 @@ void PlayerStats_EndMatch(float finished)
 {
        entity p, winner;
     winner = PlayerScore_Sort(score_dummyfield);
-       FOR_EACH_PLAYER(p)
+       FOR_EACH_PLAYER(p) // spectators intentionally not included
        {
                PlayerScore_PlayerStats(p);
                PlayerStats_Accuracy(p);
index 58d40dbea8f66c07b94bc1f035ab3e1046daa681..c78b9f2fa5908c650ba76fd71cb0298146764599 100644 (file)
@@ -18,6 +18,7 @@ post-builtins.qh
 ../common/util.qh
 ../common/items.qh
 ../common/explosion_equation.qh
+../common/urllib.qh
 
 autocvars.qh
 constants.qh
@@ -132,6 +133,7 @@ vote.qc
 campaign.qc
 ../common/campaign_file.qc
 ../common/campaign_setup.qc
+../common/urllib.qc
 
 ../common/gamecommand.qc
 gamecommand.qc