C TeamSpeak 3程序在添加自己的插件后停止工作
我制作了一个ts3插件,代码如下:C TeamSpeak 3程序在添加自己的插件后停止工作,c,asynchronous,plugins,teamspeak,C,Asynchronous,Plugins,Teamspeak,我制作了一个ts3插件,代码如下: int ts3plugin_onTextMessageEvent(uint64 serverConnectionHandlerID, anyID targetMode, anyID toID, anyID fromID, const char* fromName, const char* fromUniqueIdentifier, const char* message, int ffIgnored) { if(ffIgnored) {
int ts3plugin_onTextMessageEvent(uint64 serverConnectionHandlerID, anyID targetMode, anyID toID, anyID fromID, const char* fromName, const char* fromUniqueIdentifier, const char* message, int ffIgnored) {
if(ffIgnored) {
return 0; /* Client will ignore the message anyways, so return value here doesn't matter */
}
/* Example code: Autoreply to sender */
/* Disabled because quite annoying, but should give you some ideas what is possible here */
/* Careful, when two clients use this, they will get banned quickly... */
anyID myID;
if(ts3Functions.getClientID(serverConnectionHandlerID, &myID) != ERROR_ok) {
ts3Functions.logMessage("Error querying own client id", LogLevel_ERROR, "Plugin", serverConnectionHandlerID);
return 0;
}
printf("start plugin music");
HANDLE hStdout;
TCHAR msgBuf[255];
msgBuf[0] = "a";
size_t cchStringSize;
DWORD dwChars;
// Make sure there is a console to receive output results.
hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
if(hStdout == INVALID_HANDLE_VALUE)
return 1;
if(targetMode == TextMessageTarget_CHANNEL) {
if(fromID != myID && serverConnectionHandlerID != 1) { /* Don't reply when source is own client */
char *str3 = (char *)malloc(1 + strlen(message) + 1 + strlen(fromUniqueIdentifier));
strcpy(str3, message);
strcat(str3, " ");
strcat(str3, fromUniqueIdentifier);
if(checkMessage(str3, serverConnectionHandlerID, toID, fromID)) {
printf("true");
}
}
}
return 0; /* 0 = handle normally, 1 = client will ignore the text message */
}
// Sample custom data structure for threads to use.
// This is passed by void pointer so it can be any data type
// that can be passed using a single void pointer (LPVOID).
typedef struct MyData {
uint64 serverConnectionHandlerID;
anyID toID;
anyID fromID;
} MYDATA, *PMYDATA;
BOOL checkMessage(const char *message, uint64 serverConnectionHandlerID, anyID toID, anyID fromID) {
const char *init = "#pj ";
for(int i = 0; i < strlen(init); i++) {
if(message[i] != init[i])
return FALSE;
}
writeToFile(message, "file.txt");
PMYDATA pData;
DWORD dwThreadId;
HANDLE hThread;
pData = (PMYDATA)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(MYDATA));
if(pData == NULL) {
// If the array allocation fails, the system is out of memory
// so there is no point in trying to print an error message.
// Just terminate execution.
ExitProcess(2);
}
pData->serverConnectionHandlerID = serverConnectionHandlerID;
pData->toID = toID;
pData->fromID = fromID;
hThread = CreateThread(
NULL, // default security attributes
0, // use default stack size
MyThreadFunction, // thread function name
pData, // argument to thread function
0, // use default creation flags
&dwThreadId); // returns the thread identifier
//WaitForMultipleObjects(MAX_THREADS, hThreadArray, TRUE, INFINITE);
return FALSE;
}
void writeToFile(char *comm, char *file) {
FILE *fp;
char *str1 = "some/path/";
char *str3 = (char *)malloc(1 + strlen(str1) + strlen(file));
strcpy(str3, str1);
strcat(str3, file);
fp = fopen(str3, "w");
fprintf(fp, "%s", comm);
fclose(fp);
free(str3);
}
DWORD WINAPI MyThreadFunction(LPVOID lpParam) {
PMYDATA pDataArray;
// Cast the parameter to the correct data type.
// The pointer is known to be valid because
// it was checked for NULL before the thread was created.
pDataArray = (PMYDATA)lpParam;
FILE *fp;
long lSize;
const char *buffer;
fp = fopen("some/path/file2.txt", "r");
fseek(fp, 0L, SEEK_END);
lSize = ftell(fp);
if(lSize > 0) {
const char *priv = "$";
int priv_length = 1;
rewind(fp);
buffer = calloc(1, lSize + 1);
fread(buffer, lSize, 1, fp);
fclose(fp);
fp = fopen("some/path/file2.txt", "w");
fclose(fp);
if(buffer[0] == priv[0]) {
const char *buffer2;
buffer2 = calloc(1, lSize);
strncpy(buffer2, buffer + 1, lSize - 1);
ts3Functions.requestSendPrivateTextMsg(pDataArray->serverConnectionHandlerID, buffer2, pDataArray->fromID, NULL);
free(buffer2);
} else
ts3Functions.requestSendChannelTextMsg(pDataArray->serverConnectionHandlerID, buffer, pDataArray->toID, NULL);
free(buffer);
}
Sleep(1000);
MyThreadFunction(lpParam);
}
int ts3plugin\u onTextMessageEvent(uint64服务器连接HandlerId、anyID targetMode、anyID toID、anyID fromID、const char*fromName、const char*fromUniqueIdentifier、const char*message、int ffIgnored){
如果(ffIgnored){
返回0;/*客户端无论如何都会忽略该消息,因此此处的返回值无关紧要*/
}
/*示例代码:自动回复发件人*/
/*因为很烦人而被禁用,但是应该给你一些可能的想法*/
/*小心,当两个客户使用这个时,他们会很快被禁止*/
anyID-myID;
if(ts3Functions.getClientID(serverConnectionHandlerID和myID)!=错误\u确定){
logMessage(“查询自己的客户端id时出错”,LogLevel_错误,“插件”,serverConnectionHandlerID);
返回0;
}
printf(“启动插件音乐”);
处理HST输出;
TCHAR msgBuf[255];
msgBuf[0]=“a”;
尺寸(不包括螺纹尺寸);
德沃德·德查尔斯;
//确保有一个控制台来接收输出结果。
hStdout=GetStdHandle(标准输出句柄);
if(hStdout==无效的句柄值)
返回1;
如果(targetMode==TextMessageTarget_通道){
如果(fromID!=myID&&serverConnectionHandlerID!=1){/*当源是自己的客户端时,不回复*/
char*str3=(char*)malloc(1+strlen(message)+1+strlen(fromUniqueIdentifier));
strcpy(str3,消息);
strcat(str3,“”);
strcat(str3,来自uniqueidentifier);
if(检查消息(str3,serverConnectionHandlerID,toID,fromID)){
printf(“真实”);
}
}
}
返回0;/*0=正常处理,1=客户端将忽略文本消息*/
}
//要使用的线程的示例自定义数据结构。
//这是通过void指针传递的,因此它可以是任何数据类型
//可以使用单个void指针(LPVOID)传递的。
类型定义结构MyData{
uint64服务器连接handlerid;
anyID-toID;
anyID fromID;
}MYDATA,*PMYDATA;
BOOL checkMessage(const char*message、uint64 serverConnectionHandlerID、anyID toID、anyID fromID){
常量char*init=“#pj”;
for(int i=0;iserverConnectionHandlerID=serverConnectionHandlerID;
pData->toID=toID;
pData->fromID=fromID;
hThread=CreateThread(
NULL,//默认安全属性
0,//使用默认堆栈大小
MyThreadFunction,//线程函数名
pData,//线程函数的参数
0,//使用默认创建标志
&dwThreadId);//返回线程标识符
//WaitForMultipleObjects(最大线程、hThreadArray、TRUE、无限);
返回FALSE;
}
无效写入文件(char*comm,char*file){
文件*fp;
char*str1=“some/path/”;
char*str3=(char*)malloc(1+strlen(str1)+strlen(文件));
strcpy(str3,str1);
strcat(str3,文件);
fp=fopen(str3,“w”);
fprintf(fp,“%s”,comm);
fclose(fp);
免费(str3);
}
DWORD WINAPI MyThreadFunction(LPVOID lpParam){
PMYDATA-pDataArray;
//将参数强制转换为正确的数据类型。
//已知指针有效,因为
//在创建线程之前,已检查它是否为NULL。
pDataArray=(PMYDATA)lpParam;
文件*fp;
长时间lSize;
常量字符*缓冲区;
fp=fopen(“some/path/file2.txt”、“r”);
fseek(fp,0L,SEEK_END);
lSize=ftell(fp);
如果(lSize>0){
常量字符*priv=“$”;
int priv_length=1;
倒带(fp);
buffer=calloc(1,lSize+1);
fread(缓冲区,lSize,1,fp);
fclose(fp);
fp=fopen(“some/path/file2.txt”,“w”);
fclose(fp);
if(缓冲区[0]==priv[0]){
const char*buffer2;
buffer2=calloc(1,lSize);
strncpy(buffer2,buffer+1,lSize-1);
requestSendPrivateTextMsg(pDataArray->serverConnectionHandlerID,buffer2,pDataArray->fromID,NULL);
免费(2);
}否则
ts3Functions.requestSendChannelTextMsg(pDataArray->serverConnectionHandlerID,buffer,pDataArray->toID,NULL);
自由(缓冲);
}
睡眠(1000);
MyThreadFunction(lpParam);
}
问题是(当我打开我的插件)在运行ts3几分钟后,它停止工作。创建线程一定有问题,因为在我添加代码之前,一切都很好,但现在我需要检查文件是否已更改。这个问题是否相关:在添加新线程之前,我在这个插件中使用了malloc,它工作正常。是的,但现在您在
MyThreadFunction
(接下来是malloc
)。如何替换calloc函数?在启动线程之前为其分配内存,并将其传递给线程。