diff --git a/docs/history.xml b/docs/history.xml
index 135a112b..bfe291dd 100644
--- a/docs/history.xml
+++ b/docs/history.xml
@@ -32,7 +32,7 @@
server MOTD (message of the day)
master can now force a player to the enemy team
player collisions improved
- auto renaming of unnamed players
+ local renaming of duplicate player names (sauer backport)
improved app launcher for Mac (sauer backport)
reload animation now plays correctly
flag now drops correctly on heighfields
diff --git a/source/src/clientgame.cpp b/source/src/clientgame.cpp
index 351ffdc5..2a81f4f8 100644
--- a/source/src/clientgame.cpp
+++ b/source/src/clientgame.cpp
@@ -39,6 +39,23 @@ void setskin(playerent *pl, uint skin)
pl->skin = skin % (maxskin[team_int(pl->team)]+1);
}
+bool duplicatename(playerent *d, char *name = NULL)
+{
+ if(!name) name = d->name;
+ if(d!=player1 && !strcmp(name, player1->name)) return true;
+ loopv(players) if(players[i] && d!=players[i] && !strcmp(name, players[i]->name)) return true;
+ return false;
+}
+
+char *colorname(playerent *d, char *name, char *prefix)
+{
+ if(!name) name = d->name;
+ if(name[0] && !duplicatename(d, name)) return name;
+ static string cname;
+ s_sprintf(cname)("%s%s \fs\f5(%d)\fr", prefix, name, d->clientnum);
+ return cname;
+}
+
void newname(char *name)
{
if(name[0])
diff --git a/source/src/clients2c.cpp b/source/src/clients2c.cpp
index 694a6f0c..8f44bc2c 100644
--- a/source/src/clients2c.cpp
+++ b/source/src/clients2c.cpp
@@ -122,7 +122,6 @@ void parsemessages(int cn, playerent *d, ucharbuf &p)
return;
}
player1->clientnum = mycn; // we are now fully connected
- if(strstr(player1->name, "Player-")) s_sprintf(player1->name)("Player-%d", mycn);
joining = getint(p);
if(getint(p) > 0) conoutf("INFO: this server is password protected");
if(joining<0 && getclientmap()[0]) changemap(getclientmap()); // we are the first client on this server, set map
@@ -285,7 +284,7 @@ void parsemessages(int cn, playerent *d, ucharbuf &p)
if(actor==cn)
{
- conoutf("\f2%s suicided", d->name);
+ conoutf("\f2%s suicided", colorname(d));
act = d;
}
else if(actor==getclientnum() /*|| (demoplayback && actor==democlientnum)*/) // player-neutral gameplay messages?
@@ -295,14 +294,14 @@ void parsemessages(int cn, playerent *d, ucharbuf &p)
if(isteam(player1->team, d->team))
{
frags = -1;
- conoutf("\f2you %s a teammate (%s)", death, d->name);
+ conoutf("\f2you %s a teammate (%s)", death, colorname(d));
extern void showteamkill();
showteamkill();
}
else
{
frags = gib ? 2 : 1;
- conoutf("\f2you %s %s", death, d->name);
+ conoutf("\f2you %s %s", death, colorname(d));
}
addmsg(SV_FRAGS, "ri", player1->frags += frags);
if(gib) addgib(d);
@@ -315,11 +314,11 @@ void parsemessages(int cn, playerent *d, ucharbuf &p)
act = a;
if(isteam(a->team, d->team))
{
- conoutf("\f2%s %s his teammate (%s)", a->name, death, d->name);
+ conoutf("\f2%s %s his teammate (%s)", colorname(a), death, colorname(d));
}
else
{
- conoutf("\f2%s %s %s", a->name, death, d->name);
+ conoutf("\f2%s %s %s", colorname(a), death, colorname(d));
}
if(gib) addgib(d);
}
@@ -523,7 +522,7 @@ void parsemessages(int cn, playerent *d, ucharbuf &p)
if(pl)
{
pl->clientrole = r;
- if(pl->name[0]) conoutf("%s claimed %s status", pl == player1 ? "you" : pl->name, r == CR_ADMIN ? "admin" : "master");
+ if(pl->name[0]) conoutf("%s claimed %s status", pl == player1 ? "you" : colorname(pl), r == CR_ADMIN ? "admin" : "master");
}
}
break;
@@ -538,7 +537,7 @@ void parsemessages(int cn, playerent *d, ucharbuf &p)
case SOPCMD_KICK:
case SOPCMD_BAN:
{
- if(pl) conoutf("%s has been %s", pl->name, cmd == SOPCMD_KICK ? "kicked" : "banned");
+ if(pl) conoutf("%s has been %s", colorname(pl), cmd == SOPCMD_KICK ? "kicked" : "banned");
break;
}
case SOPCMD_REMBANS:
@@ -555,11 +554,11 @@ void parsemessages(int cn, playerent *d, ucharbuf &p)
break;
case SOPCMD_GIVEMASTER:
- if(pl) conoutf("the admin gave master state to %s", pl->name);
+ if(pl) conoutf("the admin gave master state to %s", colorname(pl));
break;
case SOPCMD_FORCETEAM:
- if(pl) conoutf("player %s was forced to change the team", pl->name);
+ if(pl) conoutf("player %s was forced to change the team", colorname(pl));
break;
}
break;
diff --git a/source/src/protos.h b/source/src/protos.h
index efe879ea..0412c282 100644
--- a/source/src/protos.h
+++ b/source/src/protos.h
@@ -155,6 +155,7 @@ extern void arenarespawn();
extern void respawn();
extern void serveropcommand(int cmd, int arg1);
extern void refreshsopmenu(void *menu, bool init);
+extern char *colorname(playerent *d, char *name = NULL, char *prefix = "");
// scoreboard
extern void showscores(bool on);
diff --git a/source/src/renderhud.cpp b/source/src/renderhud.cpp
index 5a2a1a75..f1d6063e 100644
--- a/source/src/renderhud.cpp
+++ b/source/src/renderhud.cpp
@@ -194,7 +194,7 @@ void drawradar(int w, int h)
{
playerent *pl = players[i];
if(!pl || !isteam(player1->team, pl->team) || !insideradar(centerpos, res/2, pl->o)) continue;
- drawradarent(pl->o.x*coordtrans, pl->o.y*coordtrans, pl->yaw, pl->state==CS_ALIVE ? (isattacking(pl) ? 2 : 0) : 1, team_int(pl->team), iconsize, isattacking(pl), pl->name);
+ drawradarent(pl->o.x*coordtrans, pl->o.y*coordtrans, pl->yaw, pl->state==CS_ALIVE ? (isattacking(pl) ? 2 : 0) : 1, team_int(pl->team), iconsize, isattacking(pl), colorname(pl));
}
if(m_ctf)
{
@@ -304,7 +304,7 @@ void gl_drawhud(int w, int h, int curfps, int nquads, int curvert, bool underwat
char *infostr = editinfo();
if(command) rendercommand(20, 1570);
else if(infostr) draw_text(infostr, 20, 1570);
- else if(targetplayer) draw_text(targetplayer->name, 20, 1570);
+ else if(targetplayer) draw_text(colorname(targetplayer), 20, 1570);
}
glLoadIdentity();
@@ -327,7 +327,7 @@ void gl_drawhud(int w, int h, int curfps, int nquads, int curvert, bool underwat
const int left = VIRTW*2/80, top = VIRTH*2*3/4;
int dmillis = demomillis();
s_sprintfd(time)("%d:%02d", dmillis/1000/60, dmillis/1000%60);
- s_sprintfd(following)("\f0Following %s", demoplayer->name);
+ s_sprintfd(following)("\f0Following %s", colorname(demoplayer));
draw_text(time, left, top-FONTH);
draw_text(following, left, top);
diff --git a/source/src/scoreboard.cpp b/source/src/scoreboard.cpp
index 24834634..825e3a0f 100644
--- a/source/src/scoreboard.cpp
+++ b/source/src/scoreboard.cpp
@@ -22,9 +22,9 @@ void renderscore(void *menu, playerent *d, int cn)
else if(d->state==CS_DEAD) status = "\f4";
s_sprintfd(lag)("%d", d->plag);
string &s = scorelines.add().s;
- if(m_ctf) s_sprintf(s)("%d\t%d\t%d\t%s\t%d\t%s\t%s%s\t%d", d->flagscore, d->frags, d->lifesequence, d->state==CS_LAGGED ? "LAG" : lag, d->ping, d->team, status, d->name, cn);
- else if(m_teammode) s_sprintf(s)("%d\t%d\t%s\t%d\t%s\t%s%s\t%d", d->frags, d->lifesequence, d->state==CS_LAGGED ? "LAG" : lag, d->ping, m_teammode ? d->team : "", status, d->name, cn);
- else s_sprintf(s)("%d\t%d\t%s\t%d\t%s%s\t%d", d->frags, d->lifesequence, d->state==CS_LAGGED ? "LAG" : lag, d->ping, status, d->name, cn);
+ if(m_ctf) s_sprintf(s)("%d\t%d\t%d\t%s\t%d\t%s\t%s%s\t%d", d->flagscore, d->frags, d->lifesequence, d->state==CS_LAGGED ? "LAG" : lag, d->ping, d->team, status, colorname(d), cn);
+ else if(m_teammode) s_sprintf(s)("%d\t%d\t%s\t%d\t%s\t%s%s\t%d", d->frags, d->lifesequence, d->state==CS_LAGGED ? "LAG" : lag, d->ping, m_teammode ? d->team : "", status, colorname(d), cn);
+ else s_sprintf(s)("%d\t%d\t%s\t%d\t%s%s\t%d", d->frags, d->lifesequence, d->state==CS_LAGGED ? "LAG" : lag, d->ping, status, colorname(d), cn);
menumanual(menu, scorelines.length()-1, s);
}