Хи. Я только-только закончил писать плагин, который сделает возможным запись голоса на HLTV.
(Просто HLTV на QueryClientCvar не отвечает, поэтому VTC туда ничего не отправляет)
Он пока не совсем готов, поэтому выкладываю пока тут, а не в добавленных плагинах.
#include <amxmodx>
#include <amxmisc>
#include <orpheu>
#define PLUGIN "VoiceTranscoderHLTVFix"
#define VERSION "1.0"
#define AUTHOR "Chuvi"
new OrpheuFunction:NumForEdict
new OrpheuFunction:MSG_ReadLong;
new OrpheuFunction:MSG_ReadString;
new OrpheuFunction:SV_ParseCvarValue2
new OrpheuHook:MSG_ReadLongHook;
new OrpheuHook:MSG_ReadStringHook;
new MsgReadStringCount=0;
new QueryRequestIDs[33]
new QueryRequestID
new CurClient;
new ClientID[33]
new OrpheuConfigs[200]
new pHltvCodec
public plugin_init()
{
get_configsdir(OrpheuConfigs,charsmax(OrpheuConfigs))
format(OrpheuConfigs,charsmax(OrpheuConfigs),"%s/orpheu/functions",OrpheuConfigs)
new bool:rs=false;
rs=Create_MSG_ReadLong()||rs;
rs=Create_MSG_ReadString()||rs;
rs=Create_NUM_FOR_EDICT()||rs;
rs=Create_QueryClientCvarValue2()||rs;
rs=Create_SV_ParseCvarValue2()||rs;
rs=Create_SV_ExecuteClientMessage()||rs;
if(rs)
server_cmd("restart");
register_plugin(PLUGIN, VERSION, AUTHOR)
OrpheuRegisterHook(OrpheuGetFunction("QueryClientCvarValue2"), "On_QueryClientCvarValue2", OrpheuHookPre)
OrpheuRegisterHook(OrpheuGetFunction("SV_ExecuteClientMessage"),"On_SV_ExecuteClientMessage",OrpheuHookPre)
pHltvCodec=register_cvar("vtc_hltv_codec","1")
NumForEdict=OrpheuGetFunction("NUM_FOR_EDICT");
MSG_ReadLong=OrpheuGetFunction("MSG_ReadLong");
MSG_ReadString=OrpheuGetFunction("MSG_ReadString");
SV_ParseCvarValue2=OrpheuGetFunction("SV_ParseCvarValue2");
// Add your code here...
}
public OrpheuHookReturn:On_SV_ExecuteClientMessage(client)
{
CurClient=client;
//server_print("On_SV_ExecuteClientMessage %i",client);
return OrpheuIgnored;
//Ну не придумал я способа лучше узнать client_t
}
public client_connect(id)
{
server_print("%i connected",id)
}
public client_authorized(id)
{
server_print("%i %s HLTV",id,is_user_hltv(id)?"is":"is not")
if(!is_user_hltv(id)||QueryRequestIDs[id]==0||ClientID[id]==0)
{
QueryRequestIDs[id]=0;
ClientID[id]=0;
return;
}
QueryRequestID=QueryRequestIDs[id]
MSG_ReadLongHook=OrpheuRegisterHook(MSG_ReadLong,"On_MSG_ReadLong",OrpheuHookPre)
MSG_ReadStringHook=OrpheuRegisterHook(MSG_ReadString,"On_MSG_ReadString",OrpheuHookPre)
MsgReadStringCount=0;
OrpheuCall(SV_ParseCvarValue2,ClientID[id])
OrpheuUnregisterHook(MSG_ReadLongHook)
OrpheuUnregisterHook(MSG_ReadStringHook)
QueryRequestIDs[id]=0;
ClientID[id]=0;
return
}
public OrpheuHookReturn:On_QueryClientCvarValue(Edict,CvarName[],RequestID)
{
server_print("On_QueryClientCvarValue CvarName:%s",CvarName);
return OrpheuIgnored
}
public OrpheuHookReturn:On_QueryClientCvarValue2(Edict,CvarName[],RequestID)
{
server_print("CvarName:%s",CvarName);
if(!equali(CvarName,"sv_version"))
{
server_print("On_QueryClientCvarValue2:Not sv_version");
return OrpheuIgnored;
}
server_print("On_QueryClientCvarValue2");
new id=OrpheuCall(NumForEdict,Edict);
if(id<1||id>get_maxplayers())
return OrpheuIgnored
server_print("CVAR_Query: %i (id=%i) ^"%s^" %i^nfunc=%i",Edict,id,CvarName,RequestID,NumForEdict)
server_print("MSG_ReadLong=%i^nMSG_ReadString=%i",MSG_ReadLong,MSG_ReadString);
QueryRequestIDs[id]=RequestID;
ClientID[id]=CurClient;
return OrpheuIgnored
}
public OrpheuHookReturn:On_MSG_ReadLong()
{
server_print("On_MSG_ReadLong");
OrpheuSetReturn(QueryRequestID)
server_print("QueryRequestId=%i",QueryRequestID);
return OrpheuSupercede
}
public OrpheuHookReturn:On_MSG_ReadString()
{
server_print("On_MSG_ReadString");
if(MsgReadStringCount==0)
{
OrpheuSetReturn("sv_version")
MsgReadStringCount++
return OrpheuSupercede
}
else
{
if(!get_pcvar_num(pHltvCodec))
OrpheuSetReturn("1.1.2.7/Stdio,48,5000")
else
OrpheuSetReturn("1.1.2.7/Stdio,48,6100")
MsgReadStringCount=0
return OrpheuSupercede
}
return OrpheuSupercede
}
public bool:Create_SV_ParseCvarValue2()
{
new FilePath[255]
format(FilePath,charsmax(FilePath),"%s/SV_ParseCvarValue2",OrpheuConfigs)
if(file_exists(FilePath))
return false;
new File=fopen(FilePath,"wt");
if(!File)
{
log_error(AMX_ERR_GENERAL,"Can't create ^"%s^" file",FilePath)
return false;
}
fprintf(File,"{^n ^"name^" : ^"SV_ParseCvarValue2^",^n ^"library^" : ^"engine^"");
fprintf(File,",^n^t ^"arguments^" :^n [^n^t^t{^n ^"type^" : ^"long^"^n ");
fprintf(File," }^n ],^n^t^"identifiers^" :^n^t[^n^t^t{^n^t^t^t^"os^" : ^"windows^",^n");
fprintf(File,"^t^t^t^"value^" : [0x55,0x8B,0xEC,0x81,0xEC,^"*^",^"*^",^"*^",^"*^",0x53,0");
fprintf(File,"x56,0x57,0xE8,^"*^",^"*^",^"*^",^"*^",0x68,^"*^",^"*^",^"*^",^"*^",0x8B,0xF0,");
fprintf(File,"0xE8,^"*^",^"*^",^"*^",^"*^",0x50,0x8D,0x85,^"*^",^"*^",^"*^",^"*^",0x50,0xE8");
fprintf(File,",^"*^",^"*^",^"*^",^"*^",0x83,0xC4,0x0C,0xC6,0x45,0xFE,0x00,0xE8,^"*^",");
fprintf(File,"^"*^",^"*^",^"*^",0x8B,0x5D,0x08,0x8B,0xF8,0xA1,^"*^",^"*^",^"*^",^"*^",0x8");
fprintf(File,"5,0xC0,0x74,0x15,0x8B,0x93,^"*^",^"*^",^"*^",^"*^",0x8D,0x8D,^"*^",^"*^",");
fprintf(File,"^"*^",^"*^",0x57,0x51,0x56,0x52,0xFF,0xD0,0x83,0xC4,0x10,0x8D,0x8");
fprintf(File,"5,^"*^",^"*^",^"*^",^"*^",0x57,0x50,0x81,0xC3,^"*^",^"*^",^"*^",^"*^",0x56,0x");
fprintf(File,"53,0x68,^"*^",^"*^",^"*^",^"*^",0xE8,^"*^",^"*^",^"*^",^"*^",0x83,0xC4,0x14,0");
fprintf(File,"x5F,0x5E,0x5B,0x8B,0xE5,0x5D,0xC3]^n^t^t},^n^t^t{^n^t^t^t^"os^" : ^"linux^"");
fprintf(File,",^n^t^t^t^"value^" : ^"SV_ParseCvarValue2^"^n^t^t}^n^t]^n}");
fclose(File);
return true;
}
public bool:Create_QueryClientCvarValue2()
{
new FilePath[255]
format(FilePath,charsmax(FilePath),"%s/QueryClientCvarValue2",OrpheuConfigs)
if(file_exists(FilePath))
return false;
new File=fopen(FilePath,"wt");
if(!File)
{
log_error(AMX_ERR_GENERAL,"Can't create ^"%s^" file",FilePath)
return false;
}
fprintf(File,"{^n ^"name^" : ^"QueryClientCvarValue2^",^n ^"library^" : ^"engi");
fprintf(File,"ne^",^n^t ^"arguments^" :^n [^n^t^t{^n ^"type^" : ^"int^"");
fprintf(File,"^n },^n {^n ^"type^" : ^"char *^"^n }");
fprintf(File,",^n {^n ^"type^" : ^"int^"^n }^n ],^n^t^"ide");
fprintf(File,"ntifiers^" :^n^t[^n^t^t{^n^t^t^t^"os^" : ^"windows^",^n^t^t^t^"value^" : [0x55,0x");
fprintf(File,"8B,0xEC,0x56,0x8B,0x75,0x08,0x56,0xE8,^"*^",^"*^",^"*^",^"*^",0x83,0x");
fprintf(File,"C4,0x04,0x83,0xF8,0x01,0x7C,0x44,0x3B,0x05,^"*^",^"*^",^"*^",^"*^",0x");
fprintf(File,"7F,0x3C,0x8D,0x0C,0x80,0x6A,0x3A,0xC1,0xE1,0x08,0x03,0xC8,0x8");
fprintf(File,"D,0x14,0x48,0xA1,^"*^",^"*^",^"*^",^"*^",0x8D,0x84,0xD0,^"*^",^"*^",^"*^",^"");
fprintf(File,"*^",0x8D,0x70,0x7C,0x56,0xE8,^"*^",^"*^",^"*^",^"*^",0x8B,0x4D,0x10,0x");
fprintf(File,"51,0x56,0xE8,^"*^",^"*^",^"*^",^"*^",0x8B,0x55,0x0C,0x52,0x56,0xE8,^"*");
fprintf(File,"^",^"*^",^"*^",^"*^",0x83,0xC4,0x18,0x5E,0x5D,0xC3,0xA1,^"*^",^"*^",^"*^",");
fprintf(File,"^"*^",0x85,0xC0,0x74,0x13,0x8B,0x4D,0x0C,0x8B,0x55,0x10,0x68,^"*");
fprintf(File,"^",^"*^",^"*^",^"*^",0x51,0x52,0x56,0xFF,0xD0,0x83,0xC4,0x10,0x68,^"*");
fprintf(File,"^",^"*^",^"*^",^"*^",0xE8,^"*^",^"*^",^"*^",^"*^",0x83,0xC4,0x04,0x5E,0x5D,0");
fprintf(File,"xC3]^n^t^t},^n^t^t{^n^t^t^t^"os^" : ^"linux^",^n^t^t^t^"value^" : ^"QueryClientCva");
fprintf(File,"rValue2^"^n^t^t}^n^t]^n}");
fclose(File);
return true;
}
public bool:Create_NUM_FOR_EDICT()
{
new FilePath[255]
format(FilePath,charsmax(FilePath),"%s/NUM_FOR_EDICT",OrpheuConfigs)
if(file_exists(FilePath))
return false;
new File=fopen(FilePath,"wt");
if(!File)
{
log_error(AMX_ERR_GENERAL,"Can't create ^"%s^" file",FilePath)
return false;
}
fprintf(File,"{^n ^"name^" : ^"NUM_FOR_EDICT^",^n ^"library^" : ^"engine^",^n^t ");
fprintf(File," ^"arguments^" :^n [^n^t^t{^n ^"type^" : ^"int^"^n ");
fprintf(File," }^n ],^n ^"return^" :^n {^n ^"type^" : ^"int^"^n ");
fprintf(File," },^n^t^"identifiers^" :^n^t[^n^t^t{^n^t^t^t^"os^" : ^"windows^",^n^t^t^t^"value^" :");
fprintf(File," [0x55,0x8B,0xEC,0x8B,0x4D,0x08,0x8B,0x15,^"*^",^"*^",^"*^",^"*^",0x2");
fprintf(File,"B,0xCA,0xB8,^"*^",^"*^",^"*^",^"*^",0xF7,0xE1,0x56,0x8B,0xF2,0xC1,0xE");
fprintf(File,"E,0x03,0x78,0x08,0x3B,0x35,^"*^",^"*^",^"*^",^"*^",0x7C,0x0D,0x68,^"*^"");
fprintf(File,",^"*^",^"*^",^"*^",0xE8,^"*^",^"*^",^"*^",^"*^",0x83,0xC4,0x04,0x8B,0xC6,0x");
fprintf(File,"5E,0x5D,0xC3]^n^t^t},^n^t^t{^n^t^t^t^"os^" : ^"linux^",^n^t^t^t^"value^" : ^"NUM_F");
fprintf(File,"OR_EDICT^"^n^t^t}^n^t]^n}");
fclose(File);
return true;
}
public bool:Create_MSG_ReadLong()
{
new FilePath[255]
format(FilePath,charsmax(FilePath),"%s/MSG_ReadLong",OrpheuConfigs)
if(file_exists(FilePath))
return false;
new File=fopen(FilePath,"wt");
if(!File)
{
log_error(AMX_ERR_GENERAL,"Can't create ^"%s^" file",FilePath)
return false;
}
fprintf(File,"{^n ^"name^" : ^"MSG_ReadLong^",^n ^"library^" : ^"engine^",^n ");
fprintf(File,"^"return^" :^n {^n ^"type^" : ^"long^"^n },^n^t^"identif");
fprintf(File,"iers^" :^n^t[^n^t^t{^n^t^t^t^"os^" : ^"windows^",^n^t^t^t^"value^" : [0x8B,0x0D,^"");
fprintf(File,"*^",^"*^",^"*^",^"*^",0xA1,^"*^",^"*^",^"*^",^"*^",0x57,0x8D,0x79,0x04,0x3B,");
fprintf(File,"0xF8,0x7E,0x0F,0xC7,0x05,^"*^",^"*^",^"*^",^"*^",^"*^",^"*^",^"*^",^"*^",0x83");
fprintf(File,",0xC8,0xFF,0x5F,0xC3,0x56,0x8B,0x35,^"*^",^"*^",^"*^",^"*^",0x33,0xC0");
fprintf(File,",0x33,0xD2,0x8A,0x44,0x0E,0x03,0x8A,0x54,0x0E,0x02,0xC1,0xE0,");
fprintf(File,"0x08,0x03,0xC2,0x33,0xD2,0x8A,0x54,0x0E,0x01,0x89,0x3D,^"*^",^"*");
fprintf(File,"^",^"*^",^"*^",0xC1,0xE0,0x08,0x03,0xC2,0x33,0xD2,0x8A,0x14,0x0E,0");
fprintf(File,"x5E,0xC1,0xE0,0x08,0x03,0xC2,0x5F,0xC3]^n^t^t},^n^t^t{^n^t^t^t^"os^" : ^"l");
fprintf(File,"inux^",^n^t^t^t^"value^" : ^"MSG_ReadLong^"^n^t^t}^n^t]^n}");
fclose(File);
return true;
}
public bool:Create_SV_ExecuteClientMessage()
{
new FilePath[255]
format(FilePath,charsmax(FilePath),"%s/SV_ExecuteClientMessage",OrpheuConfigs)
if(file_exists(FilePath))
return false;
new File=fopen(FilePath,"wt");
if(!File)
{
log_error(AMX_ERR_GENERAL,"Can't create ^"%s^" file",FilePath)
return false;
}
fprintf(File,"{^n ^"name^" : ^"SV_ExecuteClientMessage^",^n ^"library^" : ^"en");
fprintf(File,"gine^",^n^t ^"arguments^" :^n [^n^t^t{^n ^"type^" : ^"lo");
fprintf(File,"ng^"^n }^n ],^n^t^"identifiers^" :^n^t[^n^t^t{^n^t^t^t^"os^" : ^"windo");
fprintf(File,"ws^",^n^t^t^t^"value^" : [0x55,0x8B,0xEC,0x8B,0x0D,^"*^",^"*^",^"*^",^"*^",0");
fprintf(File,"x56,0x8B,0x75,0x08,0xC7,0x05,^"*^",^"*^",^"*^",^"*^",^"*^",^"*^",^"*^",^"*^",");
fprintf(File,"0xDD,0x05,^"*^",^"*^",^"*^",^"*^",0x8B,0x46,0x5C,0x23,0xC1,0x8D,0x0C,");
fprintf(File,"0x40,0xC1,0xE1,0x07,0x03,0xC8,0x8B,0x86,^"*^",^"*^",^"*^",^"*^",0xC1,");
fprintf(File,"0xE1,0x04,0x03,0xC8,0xDC,0x21,0xDC,0xA6,^"*^",^"*^",^"*^",^"*^",0xD9,");
fprintf(File,"0x59,0x08,0xDD,0x01,0xDC,0x1D,^"*^",^"*^",^"*^",^"*^",0xDF,0xE0,0xF6,");
fprintf(File,"0xC4,0x44,0x7A,0x07,0xC7,0x41,^"*^",^"*^",^"*^",^"*^",^"*^",0xDD,0x05,^"");
fprintf(File,"*^",^"*^",^"*^",^"*^",0xDC,0xA6,^"*^",^"*^",^"*^",^"*^",0xDC,0x1D,^"*^",^"*^",^"*");
fprintf(File,"^",^"*^",0xDF,0xE0,0xF6,0xC4,0x05,0x7A,0x19,0xD9,0x41,0x08,0xDC,");
fprintf(File,"0x1D,^"*^",^"*^",^"*^",^"*^",0xDF,0xE0,0x25,^"*^",^"*^",^"*^",^"*^",0x75,0x07");
fprintf(File,",0xC7,0x41,^"*^",^"*^",^"*^",^"*^",^"*^",0x56,0xE8,^"*^",^"*^",^"*^",^"*^",0x8B");
fprintf(File,",0x86,^"*^",^"*^",^"*^",^"*^",0x89,0x35,^"*^",^"*^",^"*^",^"*^",0xA3,^"*^",^"*^",");
fprintf(File,"^"*^",^"*^",0xC7,0x86,^"*^",^"*^",^"*^",^"*^",^"*^",^"*^",^"*^",^"*^",0xC7,0x05,^"");
fprintf(File,"*^",^"*^",^"*^",^"*^",^"*^",^"*^",^"*^",^"*^",0x83,0xC4,0x04,0xA1,^"*^",^"*^",^"*");
fprintf(File,"^",^"*^",0x85,0xC0,0x75,0x26,0xE8,^"*^",^"*^",^"*^",^"*^",0x83,0xF8,0xFF");
fprintf(File,",0x74,0x47,0x85,0xC0,0x7C,0x28,0x83,0xF8,0x0B,0x7F,0x23,0x8D,");
fprintf(File,"0x0C,0x40,0x8B,0x04,0x8D,^"*^",^"*^",^"*^",^"*^",0x85,0xC0,0x74,0xD6,");
fprintf(File,"0x56,0xFF,0xD0,0xEB,0xCE,0x68,^"*^",^"*^",^"*^",^"*^",0xE8,^"*^",^"*^",^"*");
fprintf(File,"^",^"*^",0x83,0xC4,0x04,0x5E,0x5D,0xC3,0x50,0x68,^"*^",^"*^",^"*^",^"*^"");
fprintf(File,",0xE8,^"*^",^"*^",^"*^",^"*^",0x68,^"*^",^"*^",^"*^",^"*^",0x6A,0x00,0x56,0xE");
fprintf(File,"8,^"*^",^"*^",^"*^",^"*^",0x83,0xC4,0x14,0x5E,0x5D,0xC3]^n^t^t},^n^t^t{^n^t^t^t");
fprintf(File,"^"os^" : ^"linux^",^n^t^t^t^"value^" : ^"SV_ExecuteClientMessage^"^n^t^t}^n^t]");
fprintf(File,"^n}");
fclose(File);
return true;
}
public bool:Create_MSG_ReadString()
{
new FilePath[255]
format(FilePath,charsmax(FilePath),"%s/MSG_ReadString",OrpheuConfigs)
if(file_exists(FilePath))
return false;
new File=fopen(FilePath,"wt");
if(!File)
{
log_error(AMX_ERR_GENERAL,"Can't create ^"%s^" file",FilePath)
return false;
}
fprintf(File,"{^n ^"name^" : ^"MSG_ReadString^",^n ^"library^" : ^"engine^",^n ");
fprintf(File," ^"return^" :^n {^n ^"type^" : ^"char *^"^n },^n^t^"ide");
fprintf(File,"ntifiers^" :^n^t[^n^t^t{^n^t^t^t^"os^" : ^"windows^",^n^t^t^t^"value^" : [0x53,0x");
fprintf(File,"56,0x33,0xDB,0x33,0xF6,0xE8,^"*^",^"*^",^"*^",^"*^",0x83,0xF8,0xFF,0x");
fprintf(File,"74,0x13,0x3B,0xC3,0x74,0x0F,0x88,0x86,^"*^",^"*^",^"*^",^"*^",0x46,0x");
fprintf(File,"81,0xFE,^"*^",^"*^",^"*^",^"*^",0x72,0xE3,0x88,0x9E,^"*^",^"*^",^"*^",^"*^",0");
fprintf(File,"x5E,0xB8,^"*^",^"*^",^"*^",^"*^",0x5B,0xC3]^n^t^t},^n^t^t{^n^t^t^t^"os^" : ^"linux");
fprintf(File,"^",^n^t^t^t^"value^" : ^"MSG_ReadString^"^n^t^t}^n^t]^n}");
fclose(File);
return true;
}
Что как и почему- объясню, когда доберусь до дома. А то я что-то на работе засиделся.