...
 
Commits (15)
......@@ -29,7 +29,7 @@ test_sv_game:
- wget -O data/maps/stormkeep.waypoints https://gitlab.com/xonotic/xonotic-maps.pk3dir/raw/master/maps/stormkeep.waypoints
- wget -O data/maps/stormkeep.waypoints.cache https://gitlab.com/xonotic/xonotic-maps.pk3dir/raw/master/maps/stormkeep.waypoints.cache
- make
- EXPECT=1cfe3a32d5e57d1917e14bce27b35b37
- EXPECT=fed9f3b94a544058593aaa8addaa9402
- HASH=$(${ENGINE} -noconfig -nohome +exec serverbench.cfg
| tee /dev/stderr
| grep '^:'
......
Fri Nov 9 07:24:16 CET 2018
Thu Nov 15 07:24:15 CET 2018
......@@ -17,8 +17,8 @@ msgstr ""
"Project-Id-Version: Xonotic\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2017-07-09 00:35+0200\n"
"PO-Revision-Date: 2018-11-02 19:48+0000\n"
"Last-Translator: Marinus Savoritias\n"
"PO-Revision-Date: 2018-11-10 10:16+0000\n"
"Last-Translator: Mensious Mensious <ektoras@tutanota.com>\n"
"Language-Team: Greek (http://www.transifex.com/team-xonotic/xonotic/language/"
"el/)\n"
"Language: el\n"
......@@ -4378,7 +4378,7 @@ msgstr ""
#: qcsrc/common/vehicles/vehicle/racer.qh:19
msgid "Racer"
msgstr ""
msgstr "Αγωνιζόμενος"
#: qcsrc/common/vehicles/vehicle/racer_weapon.qh:9
msgid "Racer cannon"
......@@ -5585,7 +5585,7 @@ msgstr ""
#: qcsrc/menu/xonotic/dialog_hudsetup_exit.qc:33
#: qcsrc/menu/xonotic/dialog_settings_user.qc:30
msgid "Set skin"
msgstr ""
msgstr "Ρύθμισε το σχεδιό σου"
#: qcsrc/menu/xonotic/dialog_hudsetup_exit.qc:37
msgid "Save current skin"
......@@ -5679,7 +5679,7 @@ msgstr ""
#: qcsrc/menu/xonotic/dialog_monstertools.qc:13
msgid "Monster:"
msgstr ""
msgstr "Τέρας:"
#: qcsrc/menu/xonotic/dialog_monstertools.qc:22
#: qcsrc/menu/xonotic/dialog_sandboxtools.qc:20
......@@ -5697,7 +5697,7 @@ msgstr ""
#: qcsrc/menu/xonotic/dialog_monstertools.qc:26
msgid "Follow"
msgstr ""
msgstr "Ακολούθησε"
#: qcsrc/menu/xonotic/dialog_monstertools.qc:27
msgid "Wander"
......@@ -6027,7 +6027,7 @@ msgstr ""
#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:49
#, c-format
msgid "%s Arena"
msgstr ""
msgstr "%s Αρένα"
#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:61
#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:159
......@@ -6114,11 +6114,11 @@ msgstr ""
#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:99
msgid "No powerups"
msgstr ""
msgstr "Όχι powerups"
#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:101
msgid "Powerups"
msgstr ""
msgstr "Powerups"
#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:103
#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:163
......
......@@ -9,7 +9,7 @@
# kalawore <kalawore@outlook.com>, 2015
# Losier Blackheath <losier.cc@gmail.com>, 2018
# sapphireliu <balancedliu@gmail.com>, 2014
# 茂森 杜 <dumaosen_main01@outlook.com>, 2018
# 杜茂森 <dumaosen_main01@outlook.com>, 2018
msgid ""
msgstr ""
"Project-Id-Version: Xonotic\n"
......
{
"files.associations": {
"*.qc": "c",
"*.qh": "c"
"*.qh": "c",
"*.inc": "c"
},
"C_Cpp.errorSquiggles": "Disabled"
"C_Cpp.errorSquiggles": "Disabled",
"C_Cpp.dimInactiveRegions": false
}
......@@ -74,6 +74,8 @@ bool autocvar_hud_panel_scoreboard_spectators_showping = true;
bool autocvar_hud_panel_scoreboard_spectators_aligned = false;
float autocvar_hud_panel_scoreboard_minwidth = 0.4;
AUTOCVAR(_scoreboard_instagib, bool, false, "");
// wrapper to put all possible scores titles through gettext
string TranslateScoresLabel(string l)
{
......@@ -116,6 +118,7 @@ string TranslateScoresLabel(string l)
case "suicides": return CTX(_("SCO^suicides"));
case "takes": return CTX(_("SCO^takes"));
case "ticks": return CTX(_("SCO^ticks"));
case "country": return CTX(_("SCO^country"));
default: return l;
}
}
......@@ -365,7 +368,7 @@ void Cmd_Scoreboard_Help()
// otherwise the previous exclusive rule warns anyway
// e.g. -teams,rc,cts,lms/kills ?+rc/kills
#define SCOREBOARD_DEFAULT_COLUMNS \
"ping pl fps name |" \
"ping pl fps name country |" \
" -teams,rc,cts,inv,lms/kills +ft,tdm/kills ?+rc,inv/kills" \
" -teams,lms/deaths +ft,tdm/deaths" \
" +tdm/sum" \
......@@ -382,17 +385,41 @@ void Cmd_Scoreboard_Help()
" +dom/ticks +dom/takes" \
" -lms,rc,cts,inv,nb/score"
#define SCOREBOARD_DEFAULT_COLUMNS_INSTAGIB \
"ping pl fps name country |" \
" -teams,rc,cts,inv,lms/kills +ft,tdm/kills ?+rc,inv/kills" \
" -teams,lms/deaths +ft,tdm/deaths" \
" +tdm/sum" \
" -teams,lms,rc,cts,inv,ka/suicides +ft,tdm/suicides ?+rc,inv/suicides" \
" -cts,dm,tdm,ka,ft/frags" /* tdm already has this in "score" */ \
" -cts,nb,rc/accuracy" \
" +tdm,ft,dom,ons,as/teamkills"\
" +ctf/pickups +ctf/fckills +ctf/returns +ctf/caps +ons/takes +ons/caps" \
" +lms/lives +lms/rank" \
" +kh/kckills +kh/losses +kh/caps" \
" ?+rc/laps ?+rc/time +rc,cts/fastest" \
" +as/objectives +nb/faults +nb/goals" \
" +ka/pickups +ka/bckills +ka/bctime +ft/revivals" \
" +dom/ticks +dom/takes" \
" -lms,rc,cts,inv,nb/score"
void Cmd_Scoreboard_SetFields(int argc)
{
TC(int, argc);
int i, slash;
string str, pattern;
string str, pattern, default_scoreboard;
bool have_name = false, have_primary = false, have_secondary = false, have_separator = false;
int missing;
if(!gametype)
return; // do nothing, we don't know gametype and scores yet
if (autocvar__scoreboard_instagib) {
default_scoreboard = SCOREBOARD_DEFAULT_COLUMNS_INSTAGIB;
} else {
default_scoreboard = SCOREBOARD_DEFAULT_COLUMNS;
}
// sbt_fields uses strunzone on the titles!
if(!sbt_field_title[0])
for(i = 0; i < MAX_SBT_FIELDS; ++i)
......@@ -403,16 +430,12 @@ void Cmd_Scoreboard_SetFields(int argc)
argc = tokenizebyseparator(strcat("0 1 ", autocvar_scoreboard_columns), " ");
if(argc < 3)
argc = tokenizebyseparator(strcat("0 1 ", SCOREBOARD_DEFAULT_COLUMNS), " ");
argc = tokenizebyseparator(strcat("0 1 ", default_scoreboard), " ");
if(argc == 3)
{
if(argv(2) == "default" || argv(2) == "expand_default")
{
if(argv(2) == "expand_default")
cvar_set("scoreboard_columns", SCOREBOARD_DEFAULT_COLUMNS);
argc = tokenizebyseparator(strcat("0 1 ", SCOREBOARD_DEFAULT_COLUMNS), " ");
}
if(argv(2) == "default")
argc = tokenizebyseparator(strcat("0 1 ", default_scoreboard), " ");
else if(argv(2) == "all")
{
string s = "ping pl name |"; // scores without a label
......@@ -463,6 +486,7 @@ void Cmd_Scoreboard_SetFields(int argc)
{
case "ping": sbt_field[sbt_num_fields] = SP_PING; break;
case "pl": sbt_field[sbt_num_fields] = SP_PL; break;
case "country": sbt_field[sbt_num_fields] = SP_COUNTRY; break;
case "kd": case "kdr": case "kdratio": sbt_field[sbt_num_fields] = SP_KDRATIO; break;
case "sum": case "diff": case "k-d": sbt_field[sbt_num_fields] = SP_SUM; break;
case "name": case "nick": sbt_field[sbt_num_fields] = SP_NAME; have_name = true; break;
......@@ -624,6 +648,10 @@ string Scoreboard_GetField(entity pl, PlayerScoreField field)
sbt_field_rgb = '1 1 1' - '0 1 1' * tmp;
return ftos(f);
case SP_COUNTRY:
float cn = pl.(scores(SP_COUNTRY));
return chr2str((cn >> 8) & 0xff, cn & 0xff);
case SP_PL:
if (!pl.gotscores)
return _("N/A");
......@@ -869,7 +897,7 @@ void Scoreboard_DrawItem(vector item_pos, vector rgb, entity pl, bool is_self, i
if(field == SP_SEPARATOR)
break;
if(is_spec && field != SP_NAME && field != SP_PING) {
if(is_spec && field != SP_NAME && field != SP_PING && field != SP_COUNTRY) {
pos.x += sbt_field_size[i] + hud_fontsize.x;
continue;
}
......
......@@ -534,9 +534,10 @@ MUTATOR_HOOKFUNCTION(ft, PlayerPreThink, CBC_ORDER_FIRST)
Send_Notification(NOTIF_ALL, NULL, MSG_INFO, INFO_FREEZETAG_REVIVED, player.netname, first.netname);
}
IL_EACH(reviving_players, true, {
STAT(REVIVE_PROGRESS, it) = STAT(REVIVE_PROGRESS, player);
});
if (reviving_players)
IL_EACH(reviving_players, true, {
STAT(REVIVE_PROGRESS, it) = STAT(REVIVE_PROGRESS, player);
});
}
if (reviving_players)
......
......@@ -571,6 +571,12 @@ MUTATOR_HOOKFUNCTION(mutator_instagib, OnEntityPreSpawn)
return true;
}
MUTATOR_HOOKFUNCTION(mutator_instagib, FixClientCvars)
{
entity player = M_ARGV(0, entity);
stuffcmd(player, "cl_cmd settemp _scoreboard_instagib 1\n");
}
MUTATOR_HOOKFUNCTION(mutator_instagib, BuildMutatorsString)
{
M_ARGV(0, string) = strcat(M_ARGV(0, string), ":instagib");
......
......@@ -31,6 +31,8 @@ REGISTER_SP(SCORE);
REGISTER_SP(DMG);
REGISTER_SP(DMGTAKEN);
REGISTER_SP(COUNTRY);
REGISTER_SP(KILLS);
REGISTER_SP(DEATHS);
REGISTER_SP(SUICIDES);
......@@ -84,6 +86,9 @@ REGISTER_SP(NEXBALL_FAULTS);
REGISTER_SP(ONS_TAKES);
REGISTER_SP(ONS_CAPS);
// accuracy
REGISTER_SP(ACC_VAPORIZER);
#endif
......
......@@ -36,3 +36,4 @@
#include <server/mutators/_mod.inc>
#include <server/pathlib/_mod.inc>
#include <server/weapons/_mod.inc>
#include <server/ip2country.qc>
......@@ -1197,6 +1197,7 @@ void havocbot_movetogoal(entity this)
dir = normalize(dir + dodge);
}
makevectors(this.v_angle);
//dir = this.bot_dodgevector;
//if (this.bot_dodgevector_jumpbutton)
// PHYS_INPUT_BUTTON_JUMP(this) = true;
......
......@@ -15,6 +15,7 @@
#include "g_damage.qh"
#include "handicap.qh"
#include "g_hook.qh"
#include "ip2country.qh"
#include "command/common.qh"
#include "command/vote.qh"
#include "clientkill.qh"
......@@ -801,6 +802,7 @@ void PutClientInServer(entity this)
} else if (IS_PLAYER(this)) {
PutPlayerInServer(this);
}
SetCountryToScoreboard(this);
}
// TODO do we need all these fields, or should we stop autodetecting runtime
......@@ -981,6 +983,7 @@ void ClientPreConnect(entity this)
((IS_REAL_CLIENT(this)) ? this.netaddress : "bot")
));
}
IP2Country_SetPlayer(self);
}
#endif
......@@ -1126,6 +1129,10 @@ void ClientConnect(entity this)
CS(this).jointime = time;
#ifndef DP_EXT_PRECONNECT
IP2Country_SetPlayer(self);
#endif
if (IS_REAL_CLIENT(this))
{
if (g_weaponarena_weapons == WEPSET(TUBA))
......
......@@ -1648,6 +1648,27 @@ void GameCommand_warp(int request, int argc)
}
}
void GameCommand_ip2country(float request, float argc)
{
switch(request)
{
case CMD_REQUEST_COMMAND:
IP2Country_command(argc);
return;
case CMD_REQUEST_USAGE:
default:
LOG_INFO("\nUsage:^3 sv_cmd ip2country command [arguments]\n");
LOG_INFO("Available commands:\n");
LOG_INFO(" ^2status^7: list requests in process\n");
LOG_INFO(" ^2reset^7: timeout all current requests\n");
LOG_INFO(" ^2lookup ip^7: query country for ip\n");
LOG_INFO(" ^2flushcache^7: remove all ips from cache\n");
LOG_INFO(" ^2players^7: list players with ip and country code\n");
LOG_INFO(" ^2change ID CN^7: change country code by player id\n");
return;
}
}
/* use this when creating a new command, making sure to place it in alphabetical order... also,
** ADD ALL NEW COMMANDS TO commands.cfg WITH PROPER ALIASES IN THE SAME FASHION!
void GameCommand_(int request)
......@@ -1707,6 +1728,7 @@ SERVER_COMMAND(stuffto, "Send a command to be executed on a client") { GameComma
SERVER_COMMAND(trace, "Various debugging tools with tracing") { GameCommand_trace(request, arguments); }
SERVER_COMMAND(unlockteams, "Enable the ability for players to switch or enter teams") { GameCommand_unlockteams(request); }
SERVER_COMMAND(warp, "Choose different level in campaign") { GameCommand_warp(request, arguments); }
SERVER_COMMAND(ip2country, "Get country code by ip") { GameCommand_ip2country(request, arguments); }
void GameCommand_macro_help()
{
......
......@@ -18,6 +18,7 @@
#include "scores.qh"
#include "scores_rules.qh"
#include "teamplay.qh"
#include "ip2country.qh"
#include "weapons/weaponstats.qh"
#include "../common/constants.qh"
#include <common/net_linked.qh>
......@@ -882,6 +883,8 @@ spawnfunc(worldspawn)
WeaponStats_Init();
IP2Country_Init();
Nagger_Init();
next_pingtime = time + 5;
......@@ -2211,6 +2214,7 @@ void Shutdown()
db_save(TemporaryDB, "server-temp.db");
}
CheatShutdown(); // must be after cheatcount check
IP2Country_Cleanup();
db_close(ServerProgsDB);
db_close(TemporaryDB);
LOG_TRACE("Saving persistent data... done!");
......
#include "ip2country.qh"
float IP2Country_cachedb;
.entity ip2country_cbent;
.string netaddress;
.ip2country_callback callbackfunction;
.float started_at;
void IP2Country_Init() {
registercvar("sv_ip2country", "1");
registercvar("sv_ip2country_localcn", "XX");
registercvar("sv_ip2country_timeout", "15");
registercvar("sv_ip2country_server", "http://api.vinnica.in/country?type=xonotic&ip=");
LOG_INFO("Loading cached ips\n");
IP2Country_cachedb = db_load(IP2COUNTRY_DBNAME);
}
void IP2Country_Cleanup() {
entity e;
for(e = world; (e = find(e, classname, "ip2country_cbprovider"));)
IP2Country_FreeCallbackEnt(e);
LOG_INFO("Saving cached ips\n");
db_save(IP2Country_cachedb, IP2COUNTRY_DBNAME);
db_close(IP2Country_cachedb);
}
void IP2Country_CacheIP(string ip, string cn) {
LOG_DEBUGF("Cached ip %s %s\n", ip, cn);
db_put(IP2Country_cachedb, ip, cn);
}
string IP2Country_Cache_Get(string ip) {
return db_get(IP2Country_cachedb, ip);
}
void IP2Country_AddCallback(string ip, ip2country_callback callback, float timeout, entity callbackent) {
if(timeout <= 0)
timeout = cvar("sv_ip2country_timeout");
entity cb = spawn();
cb.classname = "ip2country_cbprovider";
cb.netaddress = strzone(ip);
cb.ip2country_cbent = callbackent;
cb.callbackfunction = callback;
cb.started_at = time;
setthink(cb, IP2Country_RequestTimeout);
cb.nextthink = time + timeout;
}
void IP2Country_ExecCallback(string ip, string cn) {
entity e;
for(e = world; (e = find(e, classname, "ip2country_cbprovider")); ) {
if(e.netaddress == ip) {
e.callbackfunction(ip, cn, e.ip2country_cbent);
IP2Country_FreeCallbackEnt(e);
}
}
}
void IP2Country_FreeCallbackEnt(entity e) {
if(e.netaddress)
strunzone(e.netaddress);
remove(e);
}
void IP2Country_RequestTimeout(entity e) {
LOG_INFOF("\nIP to country request for ip : %s timed out after %f", e.netaddress, time - e.started_at);
e.callbackfunction(e.netaddress, "", e.ip2country_cbent);
IP2Country_FreeCallbackEnt(e);
}
int is_local(string IP) {
string ipl;
ipl = strtolower(IP);
if(strncmp(ipl, "local", 5) == 0)
return 1;
else if(strncmp(ipl, "127.", 4) == 0)
return 1;
else if(strncmp(ipl, "10.", 3) == 0)
return 1;
else if(strncmp(ipl, "192.168.", 8) == 0)
return 1;
else if(strncmp(ipl, "169.254.", 8) == 0)
return 1;
else if(strncmp(ipl, "172.16.", 7) == 0)
return 1;
else
return 0;
}
void IP2Country_lookup(string ip, ip2country_callback callback, float timeout, entity cbent) {
string res;
if(!cvar("sv_ip2country"))
return;
if(is_local(ip) == 1) {
callback(ip, cvar_string("sv_ip2country_localcn"), cbent);
return;
}
res = IP2Country_Cache_Get(ip);
if(res != "") {
callback(ip, res, cbent);
return;
}
IP2Country_AddCallback(ip, callback, timeout, cbent);
if (cvar_string("sv_ip2country_server") == "") {
LOG_INFOF("\nCan't lookup ip - %s, because sv_ip2country_server is not set", ip);
return;
}
uri_get(strcat(cvar_string("sv_ip2country_server"), ip), URI_GET_IP2C);
}
void IP2Country_Get_Callback(float id, float status, string data) {
string cn, ip;
if (status) {
LOG_INFOF("\nIP lookup failed, status: %f", status);
return;
}
tokenizebyseparator(data, " ");
cn = substring(argv(0), 0, 2);
ip = argv(1);
if (cn == "--") {
LOG_INFOF("\nServer can't determine country for ip -- %s", ip);
IP2Country_ExecCallback(ip, "");
return;
}
IP2Country_CacheIP(ip, cn);
IP2Country_ExecCallback(ip, cn);
}
void IP2Country_DumpToConsole(string ip, string cn, entity e) {
LOG_INFOF("Country for IP %s: %s\n", ip, (cn == "") ? "Unknown" : cn);
}
void IP2Country_check(string ip) {
IP2Country_lookup(ip, IP2Country_DumpToConsole, 0, world);
}
void IP2Country_status() {
entity e;
LOG_INFO("^3Requests in process:\n");
for(e = world; (e = find(e, classname, "ip2country_cbprovider"));)
LOG_INFOF("%-30s: ^5%4.2f\n", e.netaddress, time - e.started_at);
}
void IP2Country_reset() {
entity e;
for(e = world; (e = find(e, classname, "ip2country_cbprovider"));) {
e.think();
}
}
void IP2Country_flushcache() {
db_close(IP2Country_cachedb);
IP2Country_cachedb = db_create();
db_save(IP2Country_cachedb, IP2COUNTRY_DBNAME);
LOG_INFO("ip2country cache flushed\n");
}
void SetPlayerCountry(entity player, string cn) {
if(player.ip2country_code)
strunzone(player.ip2country_code);
player.ip2country_code = strzone(strtoupper(cn));
}
void SetCountryToScoreboard(entity player) {
string cn;
if(CS(player).scorekeeper && player.ip2country_code) {
cn = player.ip2country_code;
PlayerScore_Set(player, SP_COUNTRY, (str2chr(cn, 0) << 8) + str2chr(cn, 1));
} else {
LOG_INFOF("Player %s has no scorekeeper\n", player.netname);
}
}
void IP2Country_PlayerCallback(string ip, string cn, entity player) {
SetPlayerCountry(player, cn);
}
void IP2Country_SetPlayer(entity player) {
if(IS_REAL_CLIENT(player))
IP2Country_lookup(player.netaddress, IP2Country_PlayerCallback, 0, player);
else
SetPlayerCountry(player, "");
}
void IP2Country_players() {
FOREACH_CLIENT(IS_REAL_CLIENT(it), {
LOG_INFOF("#%-2d %12s^7 %18s [%2s]\n", num_for_edict(it), it.netname, it.netaddress, it.ip2country_code);
});
}
void IP2Country_redraw() {
FOREACH_CLIENT(IS_REAL_CLIENT(it), {
SetCountryToScoreboard(it);
});
}
void IP2Country_ChangeCountry(entity player, string country) {
if(strlen(country) == 2 && IS_REAL_CLIENT(player)) {
SetPlayerCountry(player, country);
SetCountryToScoreboard(player);
}
}
void IP2Country_command(float argc) {
if(argc < 2)
goto wrong_argument;
switch(argv(1)) {
case "status":
IP2Country_status();
if (argc != 2)
goto wrong_argument;
return;
case "reset":
if (argc != 2)
goto wrong_argument;
IP2Country_reset();
return;
case "flushcache":
if (argc != 2)
goto wrong_argument;
IP2Country_flushcache();
return;
case "players":
if (argc != 2)
goto wrong_argument;
IP2Country_players();
return;
case "redraw":
if (argc != 2)
goto wrong_argument;
IP2Country_redraw();
return;
case "lookup":
if (argc != 3)
goto wrong_argument;
IP2Country_check(argv(2));
return;
case "change":
if (argc != 4)
goto wrong_argument;
entity client = GetFilteredEntity(argv(2));
IP2Country_ChangeCountry(client, argv(3));
return;
default:
LOG_INFO("Wrong command\n"
"Available commands: status,reset,flushcache,players,lookup,change\n");
return;
}
:wrong_argument
LOG_INFO("Wrong argument count\n");
}
#ifndef IP2COUNTRY_H
#define IP2COUNTRY_H
#define IP2COUNTRY_DBNAME "ip2country.db"
typedef void(string, string, entity) ip2country_callback;
const int URI_GET_IP2C = 33;
.string ip2country_code;
void IP2Country_Init();
void IP2Country_Cleanup();
void IP2Country_lookup(string, ip2country_callback, float, entity);
void IP2Country_Get_Callback(float, float, string);
void IP2Country_FreeCallbackEnt(entity);
void IP2Country_RequestTimeout(entity);
void IP2Country_check(string);
void IP2Country_command(float);
void IP2Country_SetPlayer(entity);
void IP2Country_redraw();
void SetCountryToScoreboard(entity);
#endif
......@@ -35,6 +35,7 @@
#include "../lib/csqcmodel/sv_model.qh"
#include "../lib/warpzone/anglestransform.qh"
#include "../lib/warpzone/server.qh"
#include "ip2country.qh"
void crosshair_trace(entity pl)
{
......@@ -1138,6 +1139,10 @@ void URI_Get_Callback(float id, float status, string data)
{
// handled
}
else if (id == URI_GET_IP2C)
{
IP2Country_Get_Callback(id, status, data);
}
else if (id == URI_GET_DISCARD)
{
// discard
......
......@@ -84,8 +84,11 @@ void race_writeTime(string map, float t, string myuid)
// player has no ranked record yet
for (i = RANKINGS_CNT; i > newpos; --i)
{
db_put(ServerProgsDB, strcat(map, rr, "time", ftos(i)), ftos(race_readTime(map, i - 1)));
db_put(ServerProgsDB, strcat(map, rr, "crypto_idfp", ftos(i)), race_readUID(map, i - 1));
float other_time = race_readTime(map, i - 1);
if (other_time) {
db_put(ServerProgsDB, strcat(map, rr, "time", ftos(i)), ftos(other_time));
db_put(ServerProgsDB, strcat(map, rr, "crypto_idfp", ftos(i)), race_readUID(map, i - 1));
}
}
}
......
......@@ -271,11 +271,13 @@ float PlayerScore_Clear(entity player)
sk = CS(player).scorekeeper;
FOREACH(Scores, true, {
if(it != SP_COUNTRY) {
if(sk.(scores(it)) != 0)
if(scores_label(it) != "")
sk.SendFlags |= (2 ** (i % 16));
if(i != SP_ELO.m_id)
sk.(scores(it)) = 0;
}
});
return 1;
......@@ -286,6 +288,7 @@ void Score_ClearAll()
entity sk;
float t;
FOREACH_CLIENTSLOT(true, {
if(it != SP_COUNTRY) {
sk = CS(it).scorekeeper;
if (!sk) continue;
FOREACH(Scores, true, {
......@@ -294,6 +297,7 @@ void Score_ClearAll()
sk.SendFlags |= (2 ** (i % 16));
if(i != SP_ELO.m_id)
sk.(scores(it)) = 0;
}
});
});
for(t = 0; t < 16; ++t)
......@@ -309,6 +313,7 @@ void Score_ClearAll()
sk.(teamscores(j)) = 0;
}
}
IP2Country_redraw();
}
void PlayerScore_Attach(entity player)
......
......@@ -51,6 +51,8 @@ void ScoreRules_basics(int teams, float sprio, float stprio, float score_enabled
ScoreInfo_SetLabel_PlayerScore(SP_DMG, "dmg", 0);
ScoreInfo_SetLabel_PlayerScore(SP_DMGTAKEN, "dmgtaken", SFL_LOWER_IS_BETTER);
ScoreInfo_SetLabel_PlayerScore(SP_ELO, "elo", 0);
ScoreInfo_SetLabel_PlayerScore(SP_COUNTRY, "country", 0);
ScoreInfo_SetLabel_PlayerScore(SP_ACC_VAPORIZER, "accuracy", 0);
if(STAT(SHOWFPS))
ScoreInfo_SetLabel_PlayerScore(SP_FPS, "fps", 0);
......
......@@ -63,6 +63,7 @@ void accuracy_resend(entity e)
void accuracy_add(entity this, Weapon w, int fired, int hit)
{
int orig_wep = w.m_id;
if (IS_INDEPENDENT_PLAYER(this)) return;
entity a = CS(this).accuracy;
if (!a) return;
......@@ -84,7 +85,22 @@ void accuracy_add(entity this, Weapon w, int fired, int hit)
a.fired_time = time;
}
if (b == accuracy_byte(a.accuracy_hit[wepid], a.accuracy_fired[wepid])) return; // no change
int new_b = accuracy_byte(a.accuracy_hit[wepid], a.accuracy_fired[wepid]);
if (b == new_b) return; // no change
if (orig_wep == WEP_VAPORIZER.m_id) {
int acc;
if (new_b == 0) {
acc = 0;
} else if (new_b == 255) {
acc = 1.0;
} else {
acc = (new_b - 1) / 100;
}
// hack to make acc look same
PlayerScore_Set(this, SP_ACC_VAPORIZER, acc * 100);
}
int sf = 1 << (wepid % 24);
a.SendFlags |= sf;
FOREACH_CLIENT(IS_SPEC(it) && it.enemy == this, { CS(it).accuracy.SendFlags |= sf; });
......
This diff is collapsed.