Страница 26 из 26

Re: Технология создания плагинов

Добавлено: 16:12, 10.02.2011
adamix
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 байта.
Т.е. в CommfortProcess нужно передавать массив wchar_t ?

Re: Технология создания плагинов

Добавлено: 18:06, 10.02.2011
ОреЛ
adamix писал(а): Т.е. в CommfortProcess нужно передавать массив wchar_t ?
Нужно передавать wchar_t. Можно и просто wstring, но это как вам удобнее.

Re: Технология создания плагинов

Добавлено: 18:17, 10.02.2011
adamix

Код: Выделить всё

//---------------------------------------------------------------------------

//#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: Технология создания плагинов

Добавлено: 20:01, 10.02.2011
adamix
Проблема решена. Спасибо пользователю ОреЛ. Так же есть небольшая просьба, сделайте отдельный сигнал плагину при каждой итерации основного потока чата. Чтоб не приходилось прикручивать многопоточность.

Re: Технология создания плагинов

Добавлено: 13:09, 12.02.2011
supermet
dark писал(а):
@serg@ писал(а):dark, в какой среде компилишь?
NetBeans. Что использую написал выше. Последний раз вообще собрал из консольки, т.ч. среда не при чем. Результат тот же.
Нужно код переделать примерно так:

Код: Выделить всё

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;
//... дальше реализация
В настройках компилятора Mingw задать опции линкера -Wl,--kill-at чтобы убрать символы @XXX в именах функций. И проверить программой Dependency Walker чтобы было так - рисунок
А еще можно скачать мои исходники плагина под VC++ и переделать

Re: Технология создания плагинов

Добавлено: 16:17, 15.02.2011
ZigZagkms
Сделайте пожалуйста чтобы можно было считывать информацию с анкеты пользователя, очень желательно вместе с картинкой...
Также очень нужна возможность получать картинки публикуемые в каналах/ЛС
Также желательно чтобы можно было виртуальному пользователя входить указывая ID компьютера, хочется учитывать этот параметр везде для контроля за подключаемым виртуальными пользователями

Пожалуйста!

Re: Технология создания плагинов

Добавлено: 03:45, 18.02.2011
Phat D
Уважаемые админы и программеры,
немогли бы вы мне написать пример Рипитера на языке C#?


Заранее очень вам благодарен :)

Re: Технология создания плагинов

Добавлено: 08:15, 18.02.2011
ZigZagkms
Phat D писал(а):Уважаемые админы и программеры,
немогли бы вы мне написать пример Рипитера на языке C#?


Заранее очень вам благодарен :)
Никак не написать. Это .NET и тут нет DLL - тут есть сборки и импортировать их функционал из неуправляемого кода нельзя, за исключением COM-объектов. Не люблю я этот .NET, чтобы запустить программу требуется гора дополнительных файлов, взамен сильного упрощению написания кода теряются возможности, пишите на С++ и будет Вам счастье =)

Что такое managed и unmanaged код можно почитать тут http://www.gotdotnet.ru/forums/2/124760 ... post588378

Re: Технология создания плагинов

Добавлено: 10:31, 18.02.2011
Phat D
ZigZagkms писал(а):
Phat D писал(а):Уважаемые админы и программеры,
немогли бы вы мне написать пример Рипитера на языке C#?


Заранее очень вам благодарен :)
Никак не написать. Это .NET и тут нет DLL - тут есть сборки и импортировать их функционал из неуправляемого кода нельзя, за исключением COM-объектов. Не люблю я этот .NET, чтобы запустить программу требуется гора дополнительных файлов, взамен сильного упрощению написания кода теряются возможности, пишите на С++ и будет Вам счастье =)

Что такое managed и unmanaged код можно почитать тут http://www.gotdotnet.ru/forums/2/124760 ... post588378
Это конечно все хорошо, но вот проблема в том что я только учусь программировать, и учусь именно на системе C#...

Ну значит придется делфи вспоминать......:)

Re: Технология создания плагинов

Добавлено: 08:59, 21.02.2011
Cilvay
Как получить адрес сервера на котором запущен плагин (или к какому серверу подключен чат)

Re: Технология создания плагинов

Добавлено: 09:49, 21.02.2011
SV
Думаю можно вытащить адрес сервера из канала события

Re: Технология создания плагинов

Добавлено: 11:42, 21.02.2011
Cilvay
хм... точно

Re: Технология создания плагинов

Добавлено: 21:14, 24.02.2011
Alawar
Подскажите, пожалуйста, как изменить приветсвие канала и наложить ограничение

Re: Технология создания плагинов

Добавлено: 22:27, 24.02.2011
SV
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 - анонимное ограничение

Пользователь должен иметь соответствующие права для наложения ограничений.
Написал бы сам код но не знаю на чём вы пишите.

Re: Технология создания плагинов

Добавлено: 13:54, 25.02.2011
Maxim Mirgorodsky
В связи с изменением структуры форума данную тему закрываем. Теперь если возникли вопросы по технологии создания плагинов - вы можете просто создать новую тему в этом разделе.