//registercommand("hud_configure");
//registercommand("hud_save");
//registercommand("menu_action");
-
+
ConsoleCommand_macro_init();
registercvar("hud_usecsqc", "1");
turrets_precache();
Tuba_Precache();
CSQCPlayer_Precache();
-
+
if(autocvar_cl_reticle)
{
if(autocvar_cl_reticle_item_normal) { precache_pic("gfx/reticle_normal"); }
if(autocvar_cl_reticle_item_nex) { precache_pic("gfx/reticle_nex"); }
}
-
+
get_mi_min_max_texcoords(1); // try the CLEVER way first
minimapname = strcat("gfx/", mi_shortname, "_radar.tga");
shortmapname = mi_shortname;
hud_configure_prev = -1;
draw_currentSkin = strzone(strcat("gfx/menu/", cvar_string("menu_skin")));
+
+
+ //// WIP - zykure
+
+ PlayerInfo_Init();
+ PlayerInfo_Retrieve(self.owner);
}
// CSQC_Shutdown : Called every time the CSQC code is shutdown (changing maps, quitting, etc)
spn_origin_x = ReadShort();
spn_origin_y = ReadShort();
spn_origin_z = ReadShort();
-
+
if(is_new)
{
self.origin = spn_origin;
}
}
else { self.cnt = particleeffectnum("spawn_point_neutral"); }
-
+
self.draw = Spawn_Draw;
}
}
// this way the server can disable the sending of
// spawn origin or such to clients if wanted.
float entnum = ReadByte();
-
+
if(entnum)
{
self.origin_x = ReadShort();
}
}
}
-
+
// local spawn actions
if(is_new && (!entnum || (entnum == player_localentnum)))
{
button_zoom = FALSE;
}
}
-
+
//print(sprintf("Ent_ReadSpawnEvent(is_new = %d); origin = %s, entnum = %d, localentnum = %d\n", is_new, vtos(self.origin), entnum, player_localentnum));
}
case ENT_CLIENT_GAUNTLET: Ent_ReadHook(bIsNewEntity, ENT_CLIENT_GAUNTLET); break;
case ENT_CLIENT_ACCURACY: Ent_ReadAccuracy(); break;
case ENT_CLIENT_AUXILIARYXHAIR: Net_AuXair2(bIsNewEntity); break;
- case ENT_CLIENT_TURRET: ent_turret(); break;
+ case ENT_CLIENT_TURRET: ent_turret(); break;
case ENT_CLIENT_MODEL: CSQCModel_Read(bIsNewEntity); break;
- case ENT_CLIENT_ITEM: ItemRead(bIsNewEntity); break;
+ case ENT_CLIENT_ITEM: ItemRead(bIsNewEntity); break;
case ENT_CLIENT_BUMBLE_RAYGUN: bumble_raygun_read(bIsNewEntity); break;
case ENT_CLIENT_SPAWNPOINT: Ent_ReadSpawnPoint(bIsNewEntity); break;
case ENT_CLIENT_SPAWNEVENT: Ent_ReadSpawnEvent(bIsNewEntity); break;
}
}
+#endif // SVQC
+
//// WIP -zykure
-/*
- format spec:
+float playerinfo_db;
+string playerinfo_last;
+string playerinfo_events_last;
+.float playerid;
- A collection of lines of the format <key> SPACE <value> NEWLINE, where
- <key> is always a single character.
+void PlayerInfo_AddPlayer(entity e)
+{
+ string s;
- The following keys are defined:
+ if(playerinfo_db < 0)
+ return;
- V: format version (always a fixed number) - this MUST be the first line!
- #: comment (MUST be ignored by any parser)
- R: release information on the server
- T: time at which the game ended
- G: game type
- O: mod name (icon request) as in server browser
- M: map name
- I: match ID (see "matchid" in g_world.qc
- S: "hostname" of the server
- C: number of "unpure" cvar changes
- U: UDP port number of the server
- D: duration of the match
- P: player ID of an existing player; this also sets the owner for all following "n", "e" and "t" lines (lower case!)
- Q: team number of an existing team (format: team#NN); this also sets the owner for all following "e" lines (lower case!)
- n: nickname of the player (optional)
- t: team ID
- i: player index
- e: followed by an event name, a space, and the event count/score
- event names can be:
- alivetime: total playing time of the player
- avglatency: average network latency compounded throughout the match
- wins: number of games won (can only be set if matches is set)
- matches: number of matches played to the end (not aborted by map switch)
- joins: number of matches joined (always 1 unless player never played during the match)
- scoreboardvalid: set to 1 if the player was there at the end of the match
- total-<scoreboardname>: total score of that scoreboard item
- scoreboard-<scoreboardname>: end-of-game score of that scoreboard item (can differ in non-team games)
- achievement-<achievementname>: achievement counters (their "count" is usually 1 if nonzero at all)
- kills-<index>: number of kills against the indexed player
- rank <number>: rank of player
- acc-<weapon netname>-hit: total damage dealt
- acc-<weapon netname>-fired: total damage that all fired projectiles *could* have dealt
- acc-<weapon netname>-cnt-hit: amount of shots that actually hit
- acc-<weapon netname>-cnt-fired: amount of fired shots
- acc-<weapon netname>-frags: amount of frags dealt by weapon
+ s = sprintf("#%d", e.playerid);
- Response format (not used yet): see https://gist.github.com/4284222
-*/
-/*
-void PlayerStatsEntity_ready(entity fh, entity player_stats, float status)
+ string key;
+ key = sprintf("%s:*", s);
+
+ string p;
+ p = db_get(playerinfo_db, key);
+ if(p == "")
+ {
+ if(playerinfo_last)
+ {
+ db_put(playerinfo_db, key, playerinfo_last);
+ strunzone(playerinfo_last);
+ }
+ else
+ db_put(playerinfo_db, key, "#");
+ playerinfo_last = strzone(ftos(e.playerid));
+ print(" Added player ", s, " to playerinfo_db\n");
+ }
+}
+
+void PlayerInfo_AddItem(entity e, string item_id, string val)
{
+ if(playerinfo_db < 0)
+ return;
+
+ string key;
+ key = sprintf("*:%s", item_id);
+
+ string p;
+ p = db_get(playerinfo_db, key);
+ if(p == "")
+ {
+ if(playerinfo_events_last)
+ {
+ db_put(playerinfo_db, key, playerinfo_events_last);
+ strunzone(playerinfo_events_last);
+ }
+ else
+ db_put(playerinfo_db, key, "#");
+ playerinfo_events_last = strzone(item_id);
+ }
+
+ key = sprintf("#%d:%s", e.playerid, item_id);
+ db_put(playerinfo_db, key, val);
+
+ print("Added event ", key, "=", val, " to playerinfo_db\n");
+}
+
+string PlayerInfo_GetItem(entity e, string item_id)
+{
+ if(playerinfo_db < 0)
+ return string_null;
+
+ string key;
+ key = sprintf("#%d:%s", e.playerid, item_id);
+ return db_get(playerinfo_db, key);
+}
+
+void PlayerInfo_ready(entity fh, entity p, float status)
+{
+ float n;
string s;
- string key, value;
+
+ PlayerInfo_AddPlayer(p);
switch(status)
{
case URL_READY_CANREAD:
- print("Got response from player stats server:\n");
+ print("-- Got response from player stats server:\n");
+ float in_group = FALSE;
+ string gametype = string_null;
while((s = url_fgets(fh)))
{
- print(" ", s, "\n");
+ print(" >> ", s, "\n");
+
+ string key = string_null, value = string_null, data = string_null;
+
+ n = tokenizebyseparator(s, " "); // key (value) data
+ if (n == 1)
+ {
+ if (argv(0) == "}")
+ in_group = FALSE;
+ }
+ else if (n == 2)
+ {
+ key = argv(0);
+ data = argv(1);
+ }
+ else if (n == 3)
+ {
+ if (argv(0) == "{")
+ {
+ in_group = TRUE;
+ key = argv(1);
+ data = argv(2);
+ }
+ else
+ {
+ key = argv(0);
+ value = argv(1);
+ data = argv(2);
+ }
+ }
+ else if (n == 4)
+ {
+ key = argv(0);
+ value = argv(1);
+ data = argv(2);
+ }
+ else
+ continue;
+
+ if (data == "")
+ continue;
- key = substring(s, 0, 1);
- value = substring(s, 2, -1);
if (key == "#")
+ // comment
continue;
else if (key == "V")
// version
- continue;
+ PlayerInfo_AddItem(p, "_version", data);
+ else if (key == "R")
+ // watermark
+ PlayerInfo_AddItem(p, "_release", data);
+ else if (key == "T")
+ // timestamp
+ PlayerInfo_AddItem(p, "_time", data);
+ else if (key == "S")
+ // stats page URL
+ PlayerInfo_AddItem(p, "_statsurl", data);
else if (key == "P")
- player_stats.playerid = stof(value);
+ // player hashkey
+ PlayerInfo_AddItem(p, "_hashkey", data);
else if (key == "n")
- player_stats.playernick = value;
+ // player nick
+ PlayerInfo_AddItem(p, "_playernick", data);
+ else if (key == "i")
+ // xonstats id
+ PlayerInfo_AddItem(p, "_playerid", data);
+ else if (key == "G" && in_group)
+ gametype = data;
+ else if (key == "e" && value != "")
+ {
+ if (gametype == "")
+ PlayerInfo_AddItem(p, value, data);
+ else
+ PlayerInfo_AddItem(p, sprintf("%s-%s", gametype, value), data);
+ }
+ else
+ continue;
}
- print("End of response.\n");
+ print("-- End of response.\n");
url_fclose(fh);
break;
case URL_READY_CLOSED:
}
}
-void PlayerStats_GetPlayerInfo(entity p)
+void PlayerInfo_Init()
{
- string uri;
+ playerinfo_db = -1;
+ playerinfo_db = db_create();
+}
+
+void PlayerInfo_Retrieve(entity p)
+{
+ if(playerinfo_db < 0)
+ return;
+ string uri = "", hash = "";
+/*
+#ifdef SVQC
uri = autocvar_g_playerstats_uri;
- if(uri != "")
+ hash = p.crypto_idfp;
+#endif
+#ifdef CSQC
+ uri = "http://stats.xonotic.org"; // FIXME!
+ hash = "pQBWJrkNzHCMtndkICJacPENGctTNR59rmFS4x91FFo="; // FIXME!
+#endif
+*/
+#ifdef MENUQC
+ uri = "http://stats.xonotic.org"; // FIXME!
+ hash = crypto_getmyidfp(0);
+ if (hash == "")
+ print("Error: could not retrive hashkey for player (status: ", ftos(crypto_getmyidstatus(0)), ")\n");
+#endif
+ print("Checking for player hashkey: <", hash, "> (playerid=", ftos(p.playerid), ")\n");
+
+ if(uri != "" && hash != "")
{
- url_single_fopen(strcat(uri, "/"), FILE_READ, PlayerStatsEntity_ready, p.player_stats);
+ uri = strcat(uri, "/hashkey/", uri_escape(hash));
+ print("Retrieving playerstats from URL: ", uri, "\n");
+ url_single_fopen(uri, FILE_READ, PlayerInfo_ready, p);
}
}
-*/
-
-#endif // SVQC