/* * Localize Bug Fix * Copyright (c) 2013 - 2014 AGHL.RU Dev Team * * http://aghl.ru/forum/ - Russian Half-Life and Adrenaline Gamer Community * * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software Foundation, * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * In addition, as a special exception, the author gives permission to * link the code of this program with the Half-Life Game Engine ("HL * Engine") and Modified Game Libraries ("MODs") developed by Valve, * L.L.C ("Valve"). You must obey the GNU General Public License in all * respects for all of the code used other than the HL Engine and MODs * from Valve. If you modify this file, you may extend this exception * to your version of the file, but you are not obligated to do so. If * you do not wish to do so, delete this exception statement from your * version. * */ #include "main.h" void Cmd_TokenizeString_Handler(char *buf) { if(!strncmp(buf,"say ",4) || !strncmp(buf,"say_team ",9)) { localize_string(buf,true); } pfnCmd_TokenizeString(buf); } void OnMetaAttach() { lib_t lib; char *addr; char patch[4]; #ifdef _WIN32 char p1[] = "\x55\x8B\x2A\xA1\x2A\x2A\x2A\x2A\x56\x33\x2A\x85\x2A\x7E\x2A\x8B\x2A\x2A\x2A\x2A\x2A\x2A\x50"; char p2[] = "\x56\xE8\x2A\x2A\x2A\x2A\xA1\x2A\x2A\x2A\x2A\x50\xFF\x2A\x2A\x2A\x2A\x2A\x83\x2A\x2A\x5E\xC3"; #endif lib_load_info((void *)gpGlobals,&lib); #ifdef _WIN32 // * Cmd_TokenizeString | addr - 049A3FC0 addr = lib_find_pattern(&lib,p1,sizeof(p1) - 1);//23 #else addr = lib_find_symbol(&lib,"Cmd_TokenizeString"); #endif if(!addr) { LOG_ERROR(PLID,"can't find \"Cmd_TokenizeString\""); return; } pfnCmd_TokenizeString = reinterpret_cast(addr); #ifdef _WIN32 // * SV_ParseStringCommand | addr - 01DAB0AF addr = lib_find_pattern(&lib,p2,sizeof(p2) - 1); if(!addr) { LOG_ERROR(PLID,"can't find \"Cmd_TokenizeString\" inside function \"SV_ParseStringCommand\""); return; } // 01DAB0D8 56 push esi // 01DAB0D9 E8 E2 8E F8 FF call Cmd_TokenizeString addr += 2;// 01DAB0D8 + 1 #else addr = lib_find_symbol(&lib,"SV_ParseStringCommand"); if(!addr) { LOG_ERROR(PLID,"can't find \"SV_ParseStringCommand\""); return; } // 0009B1B0 53 push ebx // 0009B1B1 E8 AA A5 FA FF call Cmd_TokenizeString addr = mem_find_ref(addr,200,'\xE8',(dword)pfnCmd_TokenizeString,1); if(!addr) { LOG_ERROR(PLID,"can't find \"Cmd_TokenizeString\" inside function \"SV_ParseStringCommand\""); return; } addr += 1; #endif *(dword *)patch = (dword)Cmd_TokenizeString_Handler - (dword)addr - 4; if(!mem_change_protection(addr,patch,sizeof(patch))) { LOG_ERROR(PLID,"patch failed."); return; } #ifdef _WIN32 addr = lib_find_pattern_fstr(&lib,"# name userid uniqueid frag time ping loss adr\n",-12,"\x68\x2A\x2A\x2A\x2A\x53\x56",7); #else addr = lib_find_symbol(&lib,"svs"); #endif if(!addr) { LOG_ERROR(PLID,"can't find \"svs\""); return; } #ifdef _WIN32 addr += 25; global_svs = (struct server_static_s *)(*(dword **)addr - 2); #else global_svs = (struct server_static_s *)addr; #endif localize_push(); }; void ClientUserInfoChanged(edict_t *pEdict,char *infobuffer) { if(!global_svs) RETURN_META(MRES_IGNORED); char c; char *s; char *buf; int i = 0; int j = 0; s = getClientName(pEdict); buf = INFOKEY_VALUE(infobuffer,"name"); if(*s != '\0' && !strcmp(s,buf)) RETURN_META(MRES_IGNORED); if(*s == '#') *s = '*'; for(;*buf != '\0'; buf++, i++) { if(*buf != '+') continue; c = *(buf + 1); if(!isspace(c) && (isdigit(c) || isalpha(c))) { *buf = '*'; j++; } }; if(localize_string(buf -= i,false) || j) { SET_CLIENT_KEYVALUE(ENTINDEX(pEdict),infobuffer,"name",buf); } RETURN_META(MRES_IGNORED); }; #ifdef _WIN32 static char *strcasestr(const char *phaystack,const char *pneedle) { const char *a,*b; for(;*phaystack; *phaystack++) { a = phaystack; b = pneedle; while((*a++|32) == (*b++|32)) { if(!*b) return (char *)phaystack; } } return NULL; }; #endif static int localize_string(char *buf,bool apersand) { if(*buf == '\0') { return 0; } int t = 0; char *j,*a; char *c = buf; if(apersand) { do { if(*c == '%') *c = ' '; t++; } while(*c++); c -= t; } t = 0; while(1) { if(!c || !(j = strstr(c,"#"))) break; c = j + 1; if(!isdigit(*c) && isalpha(*c) && !isspace(*c)) { CVector *p = &(localize); for(CVector::iterator i = p->begin(); i != p->end(); i++) { while(1) { if(!(a = strcasestr(buf,(*i))) && !(a = strcasestr(buf,"#CZero_")) && !(a = strcasestr(buf,"#Cstrike_")) && !(a = strcasestr(buf,"#Career_"))) { break; } *a = '*'; t++; } } } } return (t > 0 && *buf != '\0'); };