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

Здесь обсуждаются технические аспекты создания дополнений.
Аватара пользователя
SV
Сообщения: 797
Зарегистрирован: 00:11, 06.09.2010
Откуда: Киров

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

Сообщение SV »

kooos писал(а):ошибаешься! если у того человека такого же плагина стоять не будет, то зацикливания тоже не будет, а иначе вы бесконечно будете обиениваться сообщениями))
так что советую зараннее продумать данную ситуацию)
Дело в том что ситуация такая,что сообщение посылаеться когда у винды начинаеться простой допустим 5 минут,после этого если кто пишет в приват или лс то сообщение отправляеться.
Аватара пользователя
SV
Сообщения: 797
Зарегистрирован: 00:11, 06.09.2010
Откуда: Киров

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

Сообщение SV »

-=SJ=- писал(а):Пример для Delphi
Plugin_repeater.zip
Всем кто качал пример во время бета тестирования надо изменить процедуру fWriteText там была еще одна ошибка :oops:
Вот правильная процедура:

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

procedure fWriteText(bOutBuffer : PAnsiChar; var iOffset  : Integer; uValue : WideString); //вспомогательная функция для упрощения работы с записью данных
	var iLength : Integer;
begin
	iLength := Length(uValue);
	CopyMemory(bOutBuffer + iOffset, @iLength, 4);
	iOffset := iOffset + 4;

	CopyMemory(bOutBuffer + iOffSet, @uValue[1], iLength * 2);
	iOffset := iOffset + iLength * 2;
end;
Пересмотри свой исходник реально при запуске плагина сервер вырубаеться.
Аватара пользователя
-=SJ=-
Сообщения: 246
Зарегистрирован: 02:21, 06.04.2007

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

Сообщение -=SJ=- »

anonim писал(а): Пересмотри свой исходник реально при запуске плагина сервер вырубаеться.
Спасибо действительно при последней модификации взял исходник который был для ранней бета версии.
Исправил
Вложения
Plugin_repeater.zip
Плагин для Delphi
(3.21 КБ) 805 скачиваний
Аватара пользователя
SV
Сообщения: 797
Зарегистрирован: 00:11, 06.09.2010
Откуда: Киров

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

Сообщение SV »

-=SJ=- писал(а):Спасибо действительно при последней модификации взял исходник который был для ранней бета версии.
Исправил
Я уже разобрался с ним.Но всёравно спасибо.
$teelR@t
Сообщения: 348
Зарегистрирован: 19:14, 30.03.2008
Откуда: Украина
Контактная информация:

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

Сообщение $teelR@t »

Интересно увидеть обработчик события: "Список пользователей в канале, к которому подключен виртуальный пользователь" - ID: 1081.
Потому что пример работы функции CommFortGetData есть только в одном примере и то только на получение данных без передачи блока данных. А вот как получить список пользователей нигде не написано.
Если запросить размер буфера, как было в примере:
int iSize = (*CommFortGetData)(dwPluginID, 1081, NULL, NULL, NULL, NULL); //получаем объем буфера
то значение приходит iSize назначается как-то странно, при выполнении функции ShowMessage(iSize) вылетает Access Violation... Хотя как можно запрашивать размер буфера, когда ещё не передал из какого канала вообще список пользователей получать...
И как теперь быть?
KGB
Сообщения: 659
Зарегистрирован: 08:54, 13.07.2010
Откуда: Чебоксары, Россия
Контактная информация:

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

Сообщение KGB »

$teelR@t, вот пример, правда, на Delphi. Думаю, нужна идея, а не код. Надеюсь, поможет :)
Возвращает количество пользователей, а в UserList записывает список пользователей.

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

function AskUsersInChannel(Name, Channel: String; var UserList: TUsers):DWord;
var
  Buf, msg: TBytes;
  iSize, len: DWord;
  I: DWord;
  J: DWord;
begin
  len:=Length(Name)*2+Length(Channel)*2+8;
  SetLength(msg, len);
  len:=Length(Name);
  CopyMemory(@msg[0], @len, 4);
  CopyMemory(@msg[4], PChar(Name), len*2);
  i:=4+len*2;
  len:=Length(Channel);
  CopyMemory(@msg[i], @len, 4);
  CopyMemory(@msg[i+4], PChar(Channel), len*2);
  i:=i+len*2+4;
  iSize := CommFortGetData(dwPluginID, 1081, nil, 0, PChar(msg), i);
  SetLength(Buf, iSize);
  if iSize=0 then
  begin
    Result:=0;
    Exit;
  end;
  CommFortGetData(dwPluginID, 1081, Buf, iSize, PCHAR(msg), i);
  CopyMemory(@Result, @Buf[0], 4);
  I:=4;
  setLength(UserList, Result + 1);
  for J := 1 to Result do
  begin
    UserList[J].Name:=TEncoding.Unicode.GetString(Buf, I+4, Dword(Buf[I])*2);
    I:=I+Dword(Buf[I])*2+4;
    UserList[J].IP:=TEncoding.Unicode.GetString(Buf, I+4, Dword(Buf[I])*2);
    I:=I+Dword(Buf[I])*2+4;
    UserList[J].sex:=Dword(Buf[I]);
    I:=I+4;
  end;
end;
$teelR@t
Сообщения: 348
Зарегистрирован: 19:14, 30.03.2008
Откуда: Украина
Контактная информация:

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

Сообщение $teelR@t »

KGB, спасибо конечно, но я уже вчера и сам разобрался... буквально через 20 минут после написания поста :D .
KGB
Сообщения: 659
Зарегистрирован: 08:54, 13.07.2010
Откуда: Чебоксары, Россия
Контактная информация:

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

Сообщение KGB »

Вопрос касается этой ошибки. Хоть мне её повторить так ни разу и не удалось, по сообщениям пользователей заметил, что она иногда проявляется при отправке подряд нескольких сообщений (или при наложении нескольких ограничений). Вопрос не в том, как исправить ошибку, а, для начала, как её повторить :) Пробовал передавать и нулевой указатель в качестве указателя на буфер, и всякий бред в качестве буфера, и с длину тоже ставил разную - сообщения, естественно, не отправлялись, но плагин не вылетал. Что должно быть с передаваемыми данными, чтобы получить такую ошибку?
E90 [11.09.2010 14:03:54.286] Ошибка при обработке программой сообщения от плагина "Mafia.cfplug" c ID=1020. Плагин остановлен.
$teelR@t
Сообщения: 348
Зарегистрирован: 19:14, 30.03.2008
Откуда: Украина
Контактная информация:

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

Сообщение $teelR@t »

Не знаю, у меня обработка опубликования сообщения в чат работает как часы (рад что перешёл на C++ Builder) :D . Сорсы в студию 8-)
Аватара пользователя
Yaroslav
Сообщения: 846
Зарегистрирован: 03:45, 15.12.2007
Контактная информация:

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

Сообщение Yaroslav »

Из справочной файла:
Внимание! Один пользователь может одновременно находиться не более чем в 16 общих каналах.
Для чего такое ограничение в клиенте и почему оно распространяется и на плагины?
Web-интерфейс серверных логов ——> http://commfort.com/ru/forum/viewtopic.php?t=6618
Web-статистика посещаемости чата —> http://commfort.com/ru/forum/viewtopic.php?t=6546
Благодарности —> R753244967524 Z664725275810 U806184306803 ЯД:41001743355185
KGB
Сообщения: 659
Зарегистрирован: 08:54, 13.07.2010
Откуда: Чебоксары, Россия
Контактная информация:

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

Сообщение KGB »

$teelR@t писал(а):Не знаю, у меня обработка опубликования сообщения в чат работает как часы (рад что перешёл на C++ Builder) :D . Сорсы в студию 8-)

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

procedure TCommPluginC.AddMessageToChannel(Name, channel : string; regime : DWord; Text : string);
var
  msg: TBytes;
  i, len: DWord;
begin
  case PROG_TYPE of
    0:
      begin
        len:=Length(Name)*2+Length(Channel)*2+Length(Text)*2+16;
        SetLength(msg, len);
        len:=Length(Name);
        CopyMemory(@msg[0], @len, 4);
        CopyMemory(@msg[4], PChar(Name), len*2);
        i:=4+len*2;
        CopyMemory(@msg[i], @regime, 4);
        i:=i+4;
        len:=Length(Channel);
        CopyMemory(@msg[i], @len, 4);
        CopyMemory(@msg[i+4], Pchar(Channel), len*2);
        i:=i+len*2+4;
        len:=Length(Text);
        CopyMemory(@msg[i], @len, 4);
        CopyMemory(@msg[i+4], Pchar(Text), len*2);
        i:=i+len*2+4;
        CommfortProcess(dwPluginID, PM_PLUGIN_SNDMSG_PUB, PChar(msg), i);
      end;
    1:
      begin
        len:=Length(Channel)*2+Length(Text)*2+12;
        SetLength(msg, len);
        len:=Length(Channel);
        CopyMemory(@msg[0], @len, 4);
        CopyMemory(@msg[4], Pchar(Channel), len*2);
        i:=4+len*2;
        CopyMemory(@msg[i], @regime, 4);
        i:=i+4;
        len:=Length(Text);
        CopyMemory(@msg[i], @len, 4);
        CopyMemory(@msg[i+4], Pchar(Text), len*2);
        i:=i+len*2+4;
        CommfortProcess(dwPluginID, PM_CLIENT_SNDMSG_PUB, PChar(msg), i);
      end;
  end;
end;
PROG_TYPE - тип программы, получаемый при запуске плагина; PM_PLUGIN_SNDMSG_PUB=1020, PM_CLIENT_SNDMSG_PUB=50.
Один из вылетов был тут (outtype=2):

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

    
  function GetAlivePlayers(outtype: Byte):String;
  var
    i: Byte;
  begin
    Result:='';
    if outtype=2 then
      CorePlugin^.AddMessageToChannel(BOT_NAME, game_chan, 1, 'Оставшиеся игроки: ');
    for i:=1 to playerCount do
      if (PlayersArr[i]^.gamestate>0) then
        Result:=Result+intToStr(i)+' - [b]'+PlayersArr[i]^.name+'[/b]'+Chr(13)+Chr(10);
    if outtype>0 then
      CorePlugin^.AddMessageToChannel(BOT_NAME, game_chan, 1, Chr(13)+Chr(10)+Result);
  end;
Вылетал он и в других местах, где был просто вывод сообщений или наложение ограничений. Причём закономерность абсолютно непонятна (кроме того, что ошибка проявляется при нескольких последовательных вызовах CommFortProcess без паузы) :) Поэтому и прошу предложить способ, как заставить сервер выкинуть плагин, тогда хотя бы будет понятно, куда копать :)
$teelR@t
Сообщения: 348
Зарегистрирован: 19:14, 30.03.2008
Откуда: Украина
Контактная информация:

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

Сообщение $teelR@t »

Хммм... вроде всё красиво выглядит... странно почему вылетает... Не нравится мне этот класс TBytes...
Причины вылетов такие:
1. Указанный размер строки байт не совпадает с реальным (в итоге может прочитаться что-то лишнее или что-то не дочитаться).
2. Где-то в самой строке также могут не совпадать размеры.
3. Не освободили память от передаваемой строки байт после выполнения функции публикации.

В принципе это все что помню... может что-то забыл ещё...
KGB
Сообщения: 659
Зарегистрирован: 08:54, 13.07.2010
Откуда: Чебоксары, Россия
Контактная информация:

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

Сообщение KGB »

$teelR@t писал(а):Хммм... вроде всё красиво выглядит... странно почему вылетает... Не нравится мне этот класс TBytes...
Причины вылетов такие:
1. Указанный размер строки байт не совпадает с реальным (в итоге может прочитаться что-то лишнее или что-то не дочитаться).
2. Где-то в самой строке также могут не совпадать размеры.
3. Не освободили память от передаваемой строки байт после выполнения функции публикации.

В принципе это все что помню... может что-то забыл ещё...
TBytes = array of byte рекомендуют использовать в качестве буфера для данных :)
А теперь отвечаю по пунктам:
1,2. Проблема в том, что вылетает только в редких случаях, причем я даже на час игру запускал, у меня не вылетело ни разу. Длину, естественно, проверял, но всё совпадало. Опять же, специально посылал и большую и меньшую длину строки, чем нужно, и заполнял сами байты рандомом - и ничего, плагин не выкидывается.
3. Счётчик ссылок сам освобождает память после выхода из функции AddMessageToChannel (утечек нет, проверял через монитор ресурсов), пытался вручную освобождать - результат тот же.
Но, в любом случае, спасибо за попытку помощи :)
Аватара пользователя
HukpoFuJl
Сообщения: 90
Зарегистрирован: 15:29, 17.10.2008
Откуда: Белaрусь, Гомель
Контактная информация:

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

Сообщение HukpoFuJl »

Всем привет, так еще с 4й версии так и не понял как правильно переводить передаваемую длину текста... Например:

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

     ID       стиль   время     тип      длина        текст
0x 64000000 02000000 01000000 01000000 04000000 7400650073007400
Тут действие, которое напишет в Events стилем ошибки, без времени, без записи в лог текст "test".
Работает всё это счастье отлично, только вот хотелось бы узнать как правильно эти четыре байта переводить в цифру... Ну вот длина текста: 04000000, наглядно понятно, что это 4 символа, но если программно преобразовать это из НЕХ значения в цифру - то получится 16777216, если преобразовывать по-байтово и складывать - тоже по сути выйдет не верно... Объясните как правильно?
В принципе касается не только длины текста, но в основном её =)
KGB
Сообщения: 659
Зарегистрирован: 08:54, 13.07.2010
Откуда: Чебоксары, Россия
Контактная информация:

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

Сообщение KGB »

HukpoFuJl писал(а):Всем привет, так еще с 4й версии так и не понял как правильно переводить передаваемую длину текста... Например:

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

     ID       стиль   время     тип      длина        текст
0x 64000000 02000000 01000000 01000000 04000000 7400650073007400
Тут действие, которое напишет в Events стилем ошибки, без времени, без записи в лог текст "test".
Работает всё это счастье отлично, только вот хотелось бы узнать как правильно эти четыре байта переводить в цифру... Ну вот длина текста: 04000000, наглядно понятно, что это 4 символа, но если программно преобразовать это из НЕХ значения в цифру - то получится 16777216, если преобразовывать по-байтово и складывать - тоже по сути выйдет не верно... Объясните как правильно?
В принципе касается не только длины текста, но в основном её =)
Дело в том, что в такой записи младший байт идёт впереди, а старший - сзади. Как именно записать в буфер - зависит от того, какой язык используете. Если хотите преобразовывать побайтово, то формула будет такая:

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

Result=Byte1+Byte2*256+Byte3*256*256+Byte4*256*256*256
Но проще использовать сразу четырёхбайтный тип, зачем что-то преобразовывать? :)
Закрыто