diff -Naur openarena-engine-source-0.8.x-28/code//server/sv_ccmds.c openarena-engine-source-0.8.x-28-rcon-tell-patch/code//server/sv_ccmds.c --- openarena-engine-source-0.8.x-28/code//server/sv_ccmds.c 2011-12-24 12:29:37 +0000 +++ openarena-engine-source-0.8.x-28-rcon-tell-patch/code//server/sv_ccmds.c 2012-02-05 16:17:45 +0000 @@ -59,7 +59,7 @@ // Check whether this is a numeric player handle for(i = 0; s[i] >= '0' && s[i] <= '9'; i++); - + if(!s[i]) { int plid = atoi(s); @@ -68,7 +68,7 @@ if(plid >= 0 && plid < sv_maxclients->integer) { cl = &svs.clients[plid]; - + if(cl->state) return cl; } @@ -267,7 +267,7 @@ // check for maxclients change if ( sv_maxclients->modified || sv_gametype->modified || sv_dorestart->integer ) { char mapname[MAX_QPATH]; - + sv_dorestart->integer = 0; Com_Printf( "variable change -- restarting.\n" ); // restart the map the slow way @@ -281,7 +281,7 @@ // map_restart has happened svs.snapFlagServerBit ^= SNAPFLAG_SERVERCOUNT; - // generate a new serverid + // generate a new serverid // TTimo - don't update restartedserverId there, otherwise we won't deal correctly with multiple map_restart sv.serverId = com_frameTime; Cvar_Set( "sv_serverid", va("%i", sv.serverId ) ); @@ -351,7 +351,7 @@ // which is wrong obviously. SV_ClientEnterWorld(client, NULL); } - } + } // run another frame to allow things to look at all the players VM_Call (gvm, GAME_RUN_FRAME, sv.time); @@ -473,7 +473,7 @@ // otherwise send their ip to the authorize server if ( svs.authorizeAddress.type != NA_BAD ) { NET_OutOfBandPrint( NS_SERVER, svs.authorizeAddress, - "banUser %i.%i.%i.%i", cl->netchan.remoteAddress.ip[0], cl->netchan.remoteAddress.ip[1], + "banUser %i.%i.%i.%i", cl->netchan.remoteAddress.ip[0], cl->netchan.remoteAddress.ip[1], cl->netchan.remoteAddress.ip[2], cl->netchan.remoteAddress.ip[3] ); Com_Printf("%s was banned from coming back\n", cl->name); } @@ -527,7 +527,7 @@ // otherwise send their ip to the authorize server if ( svs.authorizeAddress.type != NA_BAD ) { NET_OutOfBandPrint( NS_SERVER, svs.authorizeAddress, - "banUser %i.%i.%i.%i", cl->netchan.remoteAddress.ip[0], cl->netchan.remoteAddress.ip[1], + "banUser %i.%i.%i.%i", cl->netchan.remoteAddress.ip[0], cl->netchan.remoteAddress.ip[1], cl->netchan.remoteAddress.ip[2], cl->netchan.remoteAddress.ip[3] ); Com_Printf("%s was banned from coming back\n", cl->name); } @@ -547,9 +547,9 @@ fileHandle_t readfrom; char *textbuf, *curpos, *maskpos, *newlinepos, *endpos; char filepath[MAX_QPATH]; - + serverBansCount = 0; - + if(!sv_banFile->string || !*sv_banFile->string) return; @@ -565,36 +565,36 @@ } curpos = textbuf = Z_Malloc(filelen); - + filelen = FS_Read(textbuf, filelen, readfrom); FS_FCloseFile(readfrom); - + endpos = textbuf + filelen; - + for(index = 0; index < SERVER_MAXBANS && curpos + 2 < endpos; index++) { // find the end of the address string for(maskpos = curpos + 2; maskpos < endpos && *maskpos != ' '; maskpos++); - + if(maskpos + 1 >= endpos) break; *maskpos = '\0'; maskpos++; - + // find the end of the subnet specifier for(newlinepos = maskpos; newlinepos < endpos && *newlinepos != '\n'; newlinepos++); - + if(newlinepos >= endpos) break; - + *newlinepos = '\0'; - + if(NET_StringToAdr(curpos + 2, &serverBans[index].ip, NA_UNSPEC)) { serverBans[index].isexception = (curpos[0] != '0'); serverBans[index].subnet = atoi(maskpos); - + if(serverBans[index].ip.type == NA_IP && (serverBans[index].subnet < 1 || serverBans[index].subnet > 32)) { @@ -606,12 +606,12 @@ serverBans[index].subnet = 128; } } - + curpos = newlinepos + 1; } - + serverBansCount = index; - + Z_Free(textbuf); } } @@ -628,21 +628,21 @@ int index; fileHandle_t writeto; char filepath[MAX_QPATH]; - + if(!sv_banFile->string || !*sv_banFile->string) return; - + Com_sprintf(filepath, sizeof(filepath), "%s/%s", FS_GetCurrentGameDir(), sv_banFile->string); if((writeto = FS_SV_FOpenFileWrite(filepath))) { char writebuf[128]; serverBan_t *curban; - + for(index = 0; index < serverBansCount; index++) { curban = &serverBans[index]; - + Com_sprintf(writebuf, sizeof(writebuf), "%d %s %d\n", curban->isexception, NET_AdrToString(curban->ip), curban->subnet); FS_Write(writebuf, strlen(writebuf), writeto); @@ -686,7 +686,7 @@ static qboolean SV_ParseCIDRNotation(netadr_t *dest, int *mask, char *adrstr) { char *suffix; - + suffix = strchr(adrstr, '/'); if(suffix) { @@ -700,7 +700,7 @@ if(suffix) { *mask = atoi(suffix); - + if(dest->type == NA_IP) { if(*mask < 1 || *mask > 32) @@ -716,7 +716,7 @@ *mask = 32; else *mask = 128; - + return qfalse; } @@ -735,9 +735,9 @@ netadr_t ip; int index, argc, mask; serverBan_t *curban; - + argc = Cmd_Argc(); - + if(argc < 2 || argc > 3) { Com_Printf ("Usage: %s (ip[/subnet] | clientnum [subnet])\n", Cmd_Argv(0)); @@ -751,11 +751,11 @@ } banstring = Cmd_Argv(1); - + if(strchr(banstring, '.') || strchr(banstring, ':')) { // This is an ip address, not a client num. - + if(SV_ParseCIDRNotation(&ip, &mask, banstring)) { Com_Printf("Error: Invalid address %s\n", banstring); @@ -765,14 +765,14 @@ else { client_t *cl; - + // client num. if(!com_sv_running->integer) { Com_Printf("Server is not running.\n"); return; } - + cl = SV_GetPlayerByNum(); if(!cl) @@ -780,13 +780,13 @@ Com_Printf("Error: Playernum %s does not exist.\n", Cmd_Argv(1)); return; } - + ip = cl->netchan.remoteAddress; - + if(argc == 3) { mask = atoi(Cmd_Argv(2)); - + if(ip.type == NA_IP) { if(mask < 1 || mask > 32) @@ -812,13 +812,13 @@ for(index = 0; index < serverBansCount; index++) { curban = &serverBans[index]; - + if(curban->subnet <= mask) { if((curban->isexception || !isexception) && NET_CompareBaseAdrMask(curban->ip, ip, curban->subnet)) { Q_strncpyz(addy2, NET_AdrToString(ip), sizeof(addy2)); - + Com_Printf("Error: %s %s/%d supersedes %s %s/%d\n", curban->isexception ? "Exception" : "Ban", NET_AdrToString(curban->ip), curban->subnet, isexception ? "exception" : "ban", addy2, mask); @@ -830,7 +830,7 @@ if(!curban->isexception && isexception && NET_CompareBaseAdrMask(curban->ip, ip, mask)) { Q_strncpyz(addy2, NET_AdrToString(curban->ip), sizeof(addy2)); - + Com_Printf("Error: %s %s/%d supersedes already existing %s %s/%d\n", isexception ? "Exception" : "Ban", NET_AdrToString(ip), mask, curban->isexception ? "exception" : "ban", addy2, curban->subnet); @@ -844,7 +844,7 @@ while(index < serverBansCount) { curban = &serverBans[index]; - + if(curban->subnet > mask && (!curban->isexception || isexception) && NET_CompareBaseAdrMask(curban->ip, ip, mask)) SV_DelBanEntryFromList(index); else @@ -854,9 +854,9 @@ serverBans[serverBansCount].ip = ip; serverBans[serverBansCount].subnet = mask; serverBans[serverBansCount].isexception = isexception; - + serverBansCount++; - + SV_WriteBans(); Com_Printf("Added %s: %s/%d\n", isexception ? "ban exception" : "ban", @@ -876,7 +876,7 @@ int index, count = 0, todel, mask; netadr_t ip; char *banstring; - + if(Cmd_Argc() != 2) { Com_Printf ("Usage: %s (ip[/subnet] | num)\n", Cmd_Argv(0)); @@ -884,23 +884,23 @@ } banstring = Cmd_Argv(1); - + if(strchr(banstring, '.') || strchr(banstring, ':')) { serverBan_t *curban; - + if(SV_ParseCIDRNotation(&ip, &mask, banstring)) { Com_Printf("Error: Invalid address %s\n", banstring); return; } - + index = 0; - + while(index < serverBansCount) { curban = &serverBans[index]; - + if(curban->isexception == isexception && curban->subnet >= mask && NET_CompareBaseAdrMask(curban->ip, ip, mask)) @@ -908,7 +908,7 @@ Com_Printf("Deleting %s %s/%d\n", isexception ? "exception" : "ban", NET_AdrToString(curban->ip), curban->subnet); - + SV_DelBanEntryFromList(index); } else @@ -924,13 +924,13 @@ Com_Printf("Error: Invalid ban number given\n"); return; } - + for(index = 0; index < serverBansCount; index++) { if(serverBans[index].isexception == isexception) { count++; - + if(count == todel) { Com_Printf("Deleting %s %s/%d\n", @@ -944,7 +944,7 @@ } } } - + SV_WriteBans(); } @@ -961,7 +961,7 @@ { int index, count; serverBan_t *ban; - + // List all bans for(index = count = 0; index < serverBansCount; index++) { @@ -999,10 +999,10 @@ static void SV_FlushBans_f(void) { serverBansCount = 0; - + // empty the ban file. SV_WriteBans(); - + Com_Printf("All bans and exceptions have been deleted.\n"); } @@ -1101,13 +1101,13 @@ } Com_Printf ("%s", cl->name); - + // TTimo adding a ^7 to reset the color // NOTE: colored names in status breaks the padding (WONTFIX) Com_Printf ("^7"); l = 14 - strlen(cl->name); j = 0; - + do { Com_Printf (" "); @@ -1120,13 +1120,13 @@ Com_Printf ("%s", s); l = 22 - strlen(s); j = 0; - + do { Com_Printf(" "); j++; } while(j < l); - + Com_Printf ("%5i", cl->netchan.qport); Com_Printf (" %5i", cl->rate); @@ -1171,6 +1171,48 @@ /* ================== +SV_ConTell_f + +Based on Urban Terror implementation +================== +*/ +static void SV_ConTell_f(void) { + char *p; + char text[1024]; + client_t *cl; + + // make sure server is running + if ( !com_sv_running->integer ) { + Com_Printf( "Server is not running.\n" ); + return; + } + + if ( Cmd_Argc() < 3 ) { + Com_Printf ("Usage: tell \n"); + return; + } + + cl = SV_GetPlayerByNum(); + if ( !cl ) { + return; + } + + strcpy (text, "console_tell: "); + p = Cmd_ArgsFrom(2); + + if ( *p == '"' ) { + p++; + p[strlen(p)-1] = 0; + } + + strcat(text, p); + + SV_SendServerCommand(cl, "chat \"%s\"", text); +} + + +/* +================== SV_Heartbeat_f Also called by SV_DropClient, SV_DirectConnect, and SV_SpawnServer @@ -1303,8 +1345,9 @@ Cmd_AddCommand ("killserver", SV_KillServer_f); if( com_dedicated->integer ) { Cmd_AddCommand ("say", SV_ConSay_f); + Cmd_AddCommand ("tell", SV_ConTell_f); } - + Cmd_AddCommand("rehashbans", SV_RehashBans_f); Cmd_AddCommand("listbans", SV_ListBans_f); Cmd_AddCommand("banaddr", SV_BanAddr_f); @@ -1335,4 +1378,3 @@ Cmd_RemoveCommand ("say"); #endif } -