C TeamSpeak 3程序在添加自己的插件后停止工作

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) {

我制作了一个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) {
        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函数?在启动线程之前为其分配内存,并将其传递给线程。