Т.е. в CommfortProcess нужно передавать массив wchar_t ?Maxim Mirgorodsky писал(а):adamix
Возможно, проблема в этом:std::string fTextToAnsiString(std::wstring uText) //вспомогательная функция для упрощения работы с данными
{
//функция предназначена для ознакомительных целей,
//не рекомендуется для реального применения,
//так как при ее использовании проявляется избыточное копирование данных
std::string ret;
std::stringstream ss;
ss << uText.length();
ss << utf8_wcstombs(uText);
ss >> ret;
return ret;
}
ss << utf8_wcstombs(uText);
Текст должен быть в формате UTF16, на каждый символ по 2 байта.
Архив: Технология создания плагинов
Re: Технология создания плагинов
Re: Технология создания плагинов
Нужно передавать wchar_t. Можно и просто wstring, но это как вам удобнее.adamix писал(а): Т.е. в CommfortProcess нужно передавать массив wchar_t ?
Когда пишете программу, всегда думайте о том, что её может затем поддерживать психопат и насильник, который знает где вы живёте.
— Martin Golding
— Martin Golding
Re: Технология создания плагинов
Код: Выделить всё
//---------------------------------------------------------------------------
//#include <vcl.h>
#include <windows.h>
#include <string>
#include <time.h>
#include <iostream>
#include <sstream>
#pragma hdrstop
void logprintf(char * format, ...)
{
if(true)
{
char tmp_buf[512];
va_list args;
FILE* file;
va_start(args, format);
vsprintf(tmp_buf, format, args);
va_end(args);
puts(tmp_buf);
file = fopen("plugin.log", "a");
if(true)
{
time_t rawtime;
struct tm * timeinfo;
char sztime[80];
//char *result = NULL;
time(&rawtime);
timeinfo = localtime(&rawtime);
strftime(sztime, 80, "%H:%M:%S", timeinfo);
//result = strtok(tmp_buf, "\n");
fprintf(file, "[%s] %s\n", sztime, tmp_buf);
}
else
{
fprintf(file, "%s\n", tmp_buf);
}
fclose(file);
}
}
#include "UTF8.h"
DWORD dwPluginID;
typedef VOID (__stdcall *typeCommFortProcess)(DWORD dwPluginID, DWORD dID, BYTE * bOutBuffer, DWORD dwOutBufferSize);
typedef DWORD (__stdcall *typeCommFortGetData)(DWORD dwPluginID, DWORD dwID, BYTE * bInBuffer, DWORD dwInBufferSize, BYTE * bOutBuffer, DWORD dwOutBufferSize);
typeCommFortProcess CommFortProcess;
typeCommFortGetData CommFortGetData;
extern "C" __declspec(dllexport) BOOL PluginStart(DWORD dwThisPluginID, typeCommFortProcess, typeCommFortGetData);
extern "C" __declspec(dllexport) VOID PluginStop();
extern "C" __declspec(dllexport) VOID PluginProcess(DWORD dwID, BYTE * bInBuffer, DWORD dwInBufferSize);
extern "C" __declspec(dllexport) DWORD PluginGetData(DWORD dwID, BYTE * bInBuffer, DWORD dwInBufferSize, BYTE * bOutBuffer, DWORD dwOutBufferSize);
extern "C" __declspec(dllexport) BOOL PluginPremoderation(DWORD dwID, wchar_t * wText, DWORD *dwTextLength);
extern "C" __declspec(dllexport) VOID PluginShowOptions();
extern "C" __declspec(dllexport) VOID PluginShowAbout();
//---------------------------------------------------------------------------
int WINAPI DllMain(HINSTANCE hinst, unsigned long reason, void* lpReserved)
{
int iOffset, i2;
memcpy(&iOffset,&i2,4);
logprintf("DllMain");
return 1;
}
std::wstring fTextToAnsiStringW(std::wstring uText) //вспомогательная функция для упрощения работы с данными
{
//функция предназначена для ознакомительных целей,
//не рекомендуется для реального применения,
//так как при ее использовании проявляется избыточное копирование данных
std::wstring ret;
std::wstringstream ss;
ss << uText.length();
ss << uText;
ss >> ret;
return ret;
}
//---------------------------------------------------------------------------
std::wstring fIntegerToAnsiStringW(int iValue) //вспомогательная функция для упрощения работы с данными
{
std::wstring aReturn;
std::wstringstream ss;
ss << iValue;
ss >> aReturn;
return aReturn;
}
std::string fTextToAnsiString(std::wstring uText) //вспомогательная функция для упрощения работы с данными
{
//функция предназначена для ознакомительных целей,
//не рекомендуется для реального применения,
//так как при ее использовании проявляется избыточное копирование данных
std::string ret;
std::stringstream ss;
ss << uText.length();
ss << utf8_wcstombs(uText);
ss >> ret;
return ret;
}
//---------------------------------------------------------------------------
std::string fIntegerToAnsiString(int iValue) //вспомогательная функция для упрощения работы с данными
{
std::string aReturn;
std::stringstream ss;
ss << iValue;
ss >> aReturn;
return aReturn;
}
BYTE * fAnsiStringToByte(const char * szText)
{
BYTE * out = new BYTE[strlen(szText)];
for(int i = 0; i <= strlen(szText); i++)
{
out[i] = szText[i];
}
out[strlen(szText)] = '\0';
return out;
}
//---------------------------------------------------------------------------
int fReadInteger(BYTE * bInBuffer, int * iOffset) //вспомогательная функция для упрощения работы с чтением данных
{
int iLength;
memcpy(&iLength, bInBuffer + (*iOffset),4);
(*iOffset)+=4;
return iLength;
}
//---------------------------------------------------------------------------
std::wstring fReadText(BYTE * bInBuffer, int * iOffset) //вспомогательная функция для упрощения работы с чтением данных
{
int iLength;
memcpy(&iLength, bInBuffer + (*iOffset),4);
(*iOffset)+=4;
wchar_t * uRet = new wchar_t[iLength+1];
for(int i = 0; i < iLength; i++)
{
memcpy(&uRet[i], bInBuffer + (*iOffset)+(i*2), 2);
}
(*iOffset)+=iLength*2;
uRet[iLength] = '\0';
std::wstring str = uRet;
std::string s = utf8_wcstombs(str);
return str;
}
//---------------------------------------------------------------------------
void fWriteInteger(BYTE * bOutBuffer, int iOffset, int iValue) //вспомогательная функция для упрощения работы с записью данных
{
memcpy(bOutBuffer + iOffset, &iValue, 4);
iOffset+=4;
}
//---------------------------------------------------------------------------
void fWriteText(BYTE * bOutBuffer, int * iOffset, std::wstring uValue) //вспомогательная функция для упрощения работы с записью данных
{
int iLength = uValue.length();
memcpy(bOutBuffer + (*iOffset),&iLength,4);
(*iOffset)+=4;
memcpy(bOutBuffer + (*iOffset),uValue.c_str(),iLength*2);
(*iOffset)+=iLength*2;
}
//---------------------------------------------------------------------------
BOOL PluginStart(DWORD dwThisPluginID, typeCommFortProcess func1, typeCommFortGetData func2)
{
dwPluginID = dwThisPluginID;
//При инициализации планину присваивается уникальный идентификатор
//его необходимо обязательно сохранить, и указывать
//в качестве первого параметра при инициировании событий
CommFortProcess = func1;
//указываем функцию обратного вызова,
//с помощью которой плагин сможет инициировать события
CommFortGetData = func2;
//указываем функцию обратного вызова,
//с помощью которой можно будет запрашивать необходимые данные от программы
//Пример получения данных от программы (получение типа программы):
int iSize = (*CommFortGetData)(dwPluginID, 2000, NULL, NULL, NULL, NULL); //получаем объем буфера
BYTE * cData = new BYTE[iSize];
(*CommFortGetData)(dwPluginID, 2000,cData,iSize, NULL, NULL);//заполняем буфер
int iProgramType;
memcpy(&iProgramType,cData,4);//копируем число
if(iProgramType==0)
logprintf("Плагин успешно запущен на сервере CommFort");
else if(iProgramType==1)
logprintf("Плагин успешно запущен на клиенте CommFort");
logprintf("Plugin started.");
//Возвращаемые значения:
//TRUE - запуск прошел успешно
//FALSE - запуск невозможен
return TRUE;
}
//---------------------------------------------------------------------------
VOID PluginStop()
{
logprintf("Plugin stopped.");
//данная функция вызывается при завершении работы плагина
}
//---------------------------------------------------------------------------
VOID PluginProcess(DWORD dwID, BYTE * bInBuffer, DWORD dwInBufferSize)
{
logprintf("PluginProcess: [%d] [%s] [%d]", dwID, bInBuffer, dwInBufferSize);
//Функция приема событий
//Параметры:
//dwID - идентификатор события
//bInBuffer - указатель на данные
//dwInBufferSize - объем данных в байтах
int iReadOffset = 0;
if(dwID==5) //личное сообщение
{
std::wstring userName = fReadText(bInBuffer, &iReadOffset);
std::wstring ip = fReadText(bInBuffer, &iReadOffset);
int userType = fReadInteger(bInBuffer, &iReadOffset);
std::wstring chanName = fReadText(bInBuffer, &iReadOffset);
int type = fReadInteger(bInBuffer, &iReadOffset);
std::wstring text = fReadText(bInBuffer, &iReadOffset);
std::wstring send = fTextToAnsiStringW(L"unix-net") + fIntegerToAnsiStringW(0) + fTextToAnsiStringW(text);
logprintf("send: %s", send.c_str(), sizeof(BYTE));
(*CommFortProcess)(dwPluginID,50,(BYTE*)send.c_str(),send.length());
}
}
//---------------------------------------------------------------------------
DWORD PluginGetData(DWORD dwID, BYTE * bInBuffer, DWORD dwInBufferSize, BYTE * bOutBuffer, DWORD dwOutBufferSize)
{
//функция передачи данных программе
int iReadOffset = 0; //вспомогательные переменные для упрощения работы с блоком данных
int iWriteOffset = 0;
//при значении dwOutBufferSize равным нулю функция должна вернуть объем данных, ничего не записывая
if(dwID==2800) //предназначение плагина
{
if(dwOutBufferSize==0)
return 4; //объем памяти в байтах, которую необходимо выделить программе
fWriteInteger(bOutBuffer,iWriteOffset,0); //плагин подходит как для клиента, так и для сервера
return 4;//объем заполненного буфера в байтах
}
else if(dwID==2810) //название плагина (отображается в списке)
{
std::wstring uName(L"NULL: тест");//название плагина
int iSize = uName.length()*2+4;
if(dwOutBufferSize==0)
return iSize; //объем памяти в байтах, которую необходимо выделить программе
fWriteText(bOutBuffer, &iWriteOffset, uName);
return iSize;//объем заполненного буфера в байтах
}
return 0;//возвращаемое значение - объем записанных данных
}
//---------------------------------------------------------------------------
VOID PluginShowOptions()
{
//данная функция вызывается при нажатии кнопки "Настроить" в списке плагинов
//если Вы не желаете чтобы активировалась кнопка "Настроить", просто сотрите данную функцию
// ShowMessage(L"Options dialog");
std::wstring send2 = fIntegerToAnsiStringW(2) + fIntegerToAnsiStringW(0) + fIntegerToAnsiStringW(0) + fTextToAnsiStringW(L"stest");
(*CommFortProcess)(dwPluginID,100,(BYTE*)send2.c_str(),send2.length()*2);
}
//---------------------------------------------------------------------------
VOID PluginShowAbout()
{
//данная функция вызывается при нажатии кнопки "О плагине" в списке плагинов
//если Вы не желаете чтобы активировалась кнопка "Настроить", просто сотрите данную функцию
// ShowMessage(L"Test plugin for CommFort 5\n\nCreated by CommFort software Ltd.");
}
//---------------------------------------------------------------------------
Re: Технология создания плагинов
Проблема решена. Спасибо пользователю ОреЛ. Так же есть небольшая просьба, сделайте отдельный сигнал плагину при каждой итерации основного потока чата. Чтоб не приходилось прикручивать многопоточность.
Re: Технология создания плагинов
Нужно код переделать примерно так:dark писал(а):NetBeans. Что использую написал выше. Последний раз вообще собрал из консольки, т.ч. среда не при чем. Результат тот же.@serg@ писал(а):dark, в какой среде компилишь?
Код: Выделить всё
DWORD dwPluginID;
typedef VOID (__stdcall *typeCommFortProcess)(DWORD dwPluginID, DWORD dID, BYTE * bOutBuffer, DWORD dwOutBufferSize);
typedef DWORD (__stdcall *typeCommFortGetData)(DWORD dwPluginID, DWORD dwID, BYTE * bInBuffer, DWORD dwInBufferSize, BYTE * bOutBuffer, DWORD dwOutBufferSize);
typeCommFortProcess CommFortProcess;
typeCommFortGetData CommFortGetData;
#ifdef __cplusplus
extern "C" {
#endif
__declspec(dllexport) BOOL __stdcall PluginStart(DWORD dwThisPluginID, typeCommFortProcess, typeCommFortGetData);
__declspec(dllexport) VOID __stdcall PluginStop();
__declspec(dllexport) VOID __stdcall PluginProcess(DWORD dwID, BYTE * bInBuffer, DWORD dwInBufferSize);
__declspec(dllexport) DWORD __stdcall PluginGetData(DWORD dwID, BYTE * bInBuffer, DWORD dwInBufferSize, BYTE * bOutBuffer, DWORD dwOutBufferSize);
__declspec(dllexport) VOID __stdcall PluginShowOptions();
__declspec(dllexport) VOID __stdcall PluginShowAbout();
#ifdef __cplusplus
}
#endif
//---------------------------------------------------------------------------
int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved)
{
return 1;
}
//---------------------------------------------------------------------------
BOOL __stdcall PluginStart (DWORD dwThisPluginID, typeCommFortProcess func1, typeCommFortGetData func2)
{
dwPluginID = dwThisPluginID;
//... дальше реализация
А еще можно скачать мои исходники плагина под VC++ и переделать
-
- Сообщения: 109
- Зарегистрирован: 08:23, 11.12.2008
- Откуда: Комсомольск-на-Амуре
- Контактная информация:
Re: Технология создания плагинов
Сделайте пожалуйста чтобы можно было считывать информацию с анкеты пользователя, очень желательно вместе с картинкой...
Также очень нужна возможность получать картинки публикуемые в каналах/ЛС
Также желательно чтобы можно было виртуальному пользователя входить указывая ID компьютера, хочется учитывать этот параметр везде для контроля за подключаемым виртуальными пользователями
Пожалуйста!
Также очень нужна возможность получать картинки публикуемые в каналах/ЛС
Также желательно чтобы можно было виртуальному пользователя входить указывая ID компьютера, хочется учитывать этот параметр везде для контроля за подключаемым виртуальными пользователями
Пожалуйста!
Забросил, всем спасибо, исходники раздаю кому надо https://github.com/ZigZagkms
Re: Технология создания плагинов
Уважаемые админы и программеры,
немогли бы вы мне написать пример Рипитера на языке C#?
Заранее очень вам благодарен
немогли бы вы мне написать пример Рипитера на языке C#?
Заранее очень вам благодарен

-
- Сообщения: 109
- Зарегистрирован: 08:23, 11.12.2008
- Откуда: Комсомольск-на-Амуре
- Контактная информация:
Re: Технология создания плагинов
Никак не написать. Это .NET и тут нет DLL - тут есть сборки и импортировать их функционал из неуправляемого кода нельзя, за исключением COM-объектов. Не люблю я этот .NET, чтобы запустить программу требуется гора дополнительных файлов, взамен сильного упрощению написания кода теряются возможности, пишите на С++ и будет Вам счастье =)Phat D писал(а):Уважаемые админы и программеры,
немогли бы вы мне написать пример Рипитера на языке C#?
Заранее очень вам благодарен
Что такое managed и unmanaged код можно почитать тут http://www.gotdotnet.ru/forums/2/124760 ... post588378
Забросил, всем спасибо, исходники раздаю кому надо https://github.com/ZigZagkms
Re: Технология создания плагинов
Это конечно все хорошо, но вот проблема в том что я только учусь программировать, и учусь именно на системе C#...ZigZagkms писал(а):Никак не написать. Это .NET и тут нет DLL - тут есть сборки и импортировать их функционал из неуправляемого кода нельзя, за исключением COM-объектов. Не люблю я этот .NET, чтобы запустить программу требуется гора дополнительных файлов, взамен сильного упрощению написания кода теряются возможности, пишите на С++ и будет Вам счастье =)Phat D писал(а):Уважаемые админы и программеры,
немогли бы вы мне написать пример Рипитера на языке C#?
Заранее очень вам благодарен
Что такое managed и unmanaged код можно почитать тут http://www.gotdotnet.ru/forums/2/124760 ... post588378
Ну значит придется делфи вспоминать......

Re: Технология создания плагинов
Как получить адрес сервера на котором запущен плагин (или к какому серверу подключен чат)
Re: Технология создания плагинов
Думаю можно вытащить адрес сервера из канала события
Re: Технология создания плагинов
хм... точно
Re: Технология создания плагинов
Подскажите, пожалуйста, как изменить приветсвие канала и наложить ограничение
Re: Технология создания плагинов
Alawar писал(а):Подскажите, пожалуйста, как изменить приветсвие канала и наложить ограничение
Изменить приветствие канала
ID: 62
Блок данных: текст(название канала) + текст(новое приветствие)
Пользователь должен быть подключен к данному каналу и иметь право его модерирования.
Написал бы сам код но не знаю на чём вы пишите.Наложить ограничение
ID: 52
Блок данных: число(тип идентификации) + текст(объект идентификации) + число(тип ограничения) + текст(канал ограничения) + срок() + текст(причина ограничения) + число(тип анонимности)
Типы идентификации:
0 - IP-адрес
1 - диапазон IP-адресов (пример написания объекта идентификации: 192.168.0.0-192.168.0.255)
2 - ID компьютера
3 - учетная запись (по имени)
4 - учетная запись (по IP-адресу)
5 - учетная запись (по ID компьютера)
6 - учетная запись (по имени и IP-адресу)
7 - учетная запись (по имени и ID компьютера)
8 - учетная запись (по IP-адресу и ID компьютера)
9 - учетная запись (по имени и IP-адресу, и ID компьютера)
Типы ограничения:
0 - Запретить доступ к серверу
1 - Запретить приватную переписку
2 - Запретить доступ к каналу
3 - Запретить публикацию в канале
4 - Запретить публикацию картинок в канале
5 - Запретить публикацию в доске объявлений
Канал ограничения игнорируется в случае если тип ограничения соответствует значению 0, 1 или 5. Текст с нулевой длиной соответствует всем общим каналам.
Типы анонимности:
0 - обычное ограничение
1 - анонимное ограничение
Пользователь должен иметь соответствующие права для наложения ограничений.
-
- Администратор
- Сообщения: 6886
- Зарегистрирован: 09:56, 27.06.2005
Re: Технология создания плагинов
В связи с изменением структуры форума данную тему закрываем. Теперь если возникли вопросы по технологии создания плагинов - вы можете просто создать новую тему в этом разделе.