Русское сообщество по скриптингу

Полученние данных сообщений через MessageBegin

Все вопросы по скриптингу для Metamod, помощь в редактировании плагинов.
Правила форума
1. Запрещено материться и оскорблять других участников форума.
2. Запрещен флуд, оффтоп, дабл постинг во всех разделах форума, кроме раздела "Болтовня".
3. Запрещено взламывать сайт/форум или наносить любой вред проекту.
4. Запрещено рекламировать другие ресурсы.
5. Запрещено создавать темы без информативного названия. Название темы должно отображать ее смысл.

В данном разделе форума разрешено создавать темы, касающие только скриптинга для
Metamod.


Правила при создании новой темы:
1. При вставке кода плагина необходимо использовать тег [pawn], в противном случае, если тег [pawn] не отображает ваш код, можно использовать тег [code].
2. Любые изображения должны быть загружены, как вложения к вашему сообщению.
3. При описании проблемы или запросе на помощь в редактировании плагина обязательно выкладывайте исходник плагина.

Полученние данных сообщений через MessageBegin

Сообщение Dekart » 23 май 2012, 10:35

Собственно вопрос: как можно получить данные конкретного сообщения перехваченного через MessageBegin в engine api в metamod плагине?

В частности меня интересует сообщение TeamScore, согласно Вы должны зарегистрироваться, чтобы видеть ссылки. через amxmodx можно добраться до двух его параметров "TeamName" и "Score".

А как это можно сделать в metamod плагине?
Аватара пользователя
Dekart
 
Сообщения: 16
Зарегистрирован: 04 май 2012, 09:45
Благодарил (а): 5 раз.
Поблагодарили: 0 раз.

Re: Полученние данных сообщений через MessageBegin

Сообщение DJ_WEST » 23 май 2012, 14:52

Фильтровать сообщение можно с помощью:
[pawn]
  1. if (msg_type == GET_USER_MSG_ID(PLID, "TeamScore", NULL))
[/pawn]

[pawn]
  1. #define GET_USER_MSG_ID (*gpMetaUtilFuncs->pfnGetUserMsgID)
[/pawn]

Note the PLID keyword passed to each function. This is
basically a "plugin id" to indicate to Metamod which plugin is calling the
function (else it's difficult to tell), and is a macro that should be
specified verbatim with each call. (Currently, the macro is merely the
plugin_info struct pointer returned by the plugin via Meta_Query;
in the future this could change to some other identifier.)


Тебе еще нужно поставить хуки на WriteByte, WriteChar и т.д. С помощью них эти аргументы и передаются. TeamName - string, Score - short. Значит тебе нужны pfnWriteShort и pfnWriteString.

В pfnMessageBegin делаешь фильтрацию нужного сообщения и передаешь там же указатель на свою функцию, где будет обработка этих аргументов, то есть создаешь к примеру:
[pawn]
  1. void (*Msg_Function) (void *) = NULL;

  2. void Hook_TeamScore(void *p);
[/pawn]

В pfnMessageBegin делаешь проверки, если получили TeamScore, то прописываешь:
[pawn]
  1. Msg_Function = Hook_TeamScore;
[/pawn]

Сама функция Hook_TeamScore:
[pawn]
  1. void Hook_TeamScore(void *p)

  2. {

  3.         // В i_Arg храним индекс аргумента в сообщении

  4.         static int i_Arg = 0;

  5.        

  6.         // В i_Score будем хранить значение аргумента Score

  7.         static int i_Score;

  8.        

  9.         // TeamName

  10.         if (i_Arg == 0)

  11.         {

  12.                 char c_TeamName[20];

  13.                

  14.                 i_Arg++;

  15.                 memset(c_TeamName, 0, sizeof(c_TeamName));

  16.                 strcpy(c_TeamName, (char *)p);

  17.         }

  18.         // Score

  19.         else if (i_Arg == 1)

  20.         {

  21.                 i_Arg = 0;

  22.                 i_Score = *(int *) p;

  23.         }

  24. }
[/pawn]

В pfnWriteShort получаем значение i_Value и передаем в нашу функцию Hook_TeamScore:
[pawn]
  1. void pfnWriteShort(int i_Value)

  2. {

  3.     if (Hook_TeamScore)

  4.         (*Hook_TeamScore) ((void *) &i_Value);

  5.  

  6.   RETURN_META (MRES_IGNORED);

  7. }
[/pawn]

Точно также и для pfnWriteString:
[pawn]
  1. void pfnWriteString(const char *c_String)

  2. {

  3.         if (Hook_TeamScore)

  4.                 (*Hook_TeamScore) ((void *) c_String);

  5.  

  6.         RETURN_META (MRES_IGNORED);

  7. }
[/pawn]

И напоследок делаем хук на конец отправленного сообщения pfnMessageEnd:
[pawn]
  1. void pfnMessageEnd(void)

  2. {

  3.         if (Hook_TeamScore)

  4.         {

  5.                 (*Hook_TeamScore) (NULL);

  6.  

  7.                 Hook_TeamScore = NULL;

  8.         }

  9.  

  10.         RETURN_META (MRES_IGNORED);

  11. }
[/pawn]
Не пишите мне в ЛС: если вам нужна помощь на бесплатной основе. Любые вопросы на форум.
Аватара пользователя
DJ_WEST
Администратор
 
Сообщения: 3641
Зарегистрирован: 22 авг 2009, 00:38
Благодарил (а): 48 раз.
Поблагодарили: 2209 раз.
Опыт программирования: Больше трех лет
Языки программирования: Counter-Strike 1.6
Counter-Strike: Source
Left 4 Dead
Left 4 Dead 2

Re: Полученние данных сообщений через MessageBegin

Сообщение Dekart » 24 май 2012, 11:12

Спасибо за столь развернутый ответ. В целом механизм понятен, я сделал немного иначе.

[pawn]
  1. bool isTeamScoreMessage;

  2. void MessageBegin(int msg_dest, int msg_type, const float *pOrigin, edict_t *ed)

  3. {

  4.         if (msg_type == 87) //TeamScore

  5.         {

  6.                 isTeamScoreMessage = true;

  7.                 UTIL_LogPrintf("BEGIN TeamScore Message:\n");

  8.         }

  9.         else

  10.         {

  11.                 isTeamScoreMessage = false;

  12.         }

  13.  

  14.         RETURN_META (MRES_IGNORED);

  15. }

  16. void MessageEnd(void)

  17. {

  18.         if (isTeamScoreMessage)

  19.         {

  20.                 this->isTeamScoreMessage = false;

  21.                 UTIL_LogPrintf("END TeamScore Message.\n");

  22.         }

  23.         RETURN_META (MRES_IGNORED);

  24. }

  25. void WriteShort(int i_Value)

  26. {

  27.         if (isTeamScoreMessage)

  28.         {

  29.                 UTIL_LogPrintf("   SCORE = %d\n",i_Value);

  30.         }

  31.         RETURN_META (MRES_IGNORED);

  32. }

  33. void WriteString(const char *c_String)

  34. {

  35.         if (isTeamScoreMessage)

  36.         {

  37.                 UTIL_LogPrintf("   TEAM = %s\n",c_String);

  38.         }

  39.         RETURN_META (MRES_IGNORED);

  40. }
[/pawn]
Аватара пользователя
Dekart
 
Сообщения: 16
Зарегистрирован: 04 май 2012, 09:45
Благодарил (а): 5 раз.
Поблагодарили: 0 раз.


Вернуться в Скриптинг

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 6