|
Патчи Если кто-то хочет выложить не свой готовый патч - не забудьте указать автора и источник.
Если кто-то хочет задать вопрос по патчу - велкам. |
|
Опции темы | Поиск в этой теме | Опции просмотра |
|
02.01.2011, 16:56 | #1 |
Модератор
|
[patch/dev] Refer-A-Friend System
Собственно, патч, реализующий оффлайк систему "Пригласи друга"
Не совершенство, скорее бета-версия, но все же, ниже поясню почему Немного теории Услуга включает в себя 3 основые фишки - призвать друга, повысить уровень и утроенный опыт. Третью часть можно отбросить, это делается целиком на сервере. Призвать друга Опция при клике на портрете друга в пати и синий шарик во френд-листе. Кстати в 3.3.5 он выставляется независимо от статуса друга, и, позволю себе поправить уважаемого TOM_RUS в посте http://ru-mangos.ru/showpost.php?p=8598&postcount=4, это не флаг, а все-таки статус, проверял в дебаге клиента на 2.4.3., тем более если структура FriendInfo соотв. близз структуре в памяти, то по смещению pointer + 1 хранится как раз таки статус Код:
struct FriendInfo { FriendStatus Status; uint32 Flags; uint32 Area; uint32 Level; uint32 Class; Проблема была вот с чем, я писал в той теме, что не мог получить гуид того, кого нужно призвать, не выделяя его. Проблема "легко" решилась, когда я подетальнее разобрал lua функцию SummonFriend - там до каста спелла, если цель не в прямой видимости, а вызывается допустим через тот же шарик, шлется пакет под номером 317 - CMSG_SET_SELECTION Код:
v8 = 0; if ( stru_BD07B0.guid_low != v3 || stru_BD07B0.guid_high != v2 ) { v8 = 1; sub_518DC0(v3, v2); } Spell_C__CastSpell(dword_BE7D88, 0, v3, v2, 0); if ( v8 ) { sub_518DC0(stru_BD07B0.guid_low, stru_BD07B0.guid_high); return 0; } Повысить уровень Основная проблема заключалась в том, что опция активировалась только при опр. условиях, и их удалось найти, опять же подебажив клиент и рассмотрев смещения полей в структурах После проходв кучи проверок доходим до такой проверки, где результат либо 0, либо 3 , 0 - это верно, 3 - вернет ошибку Код:
result = *(_BYTE *)(*((_DWORD *)v13 + 1026) + 4197) < 1u ? 3 : 0; Код:
.text:006DEB02 mov ecx, [esi+1008h] .text:006DEB08 cmp byte ptr [ecx+1065h], 1 Предлагайте свои варианты, т.к очень хотелось бы довести патч до официального репозитория Да, и я использовал отдельную таблицу для реферского(приглашающего) аккаунта и 5 реферралов(приглашенных) - мб тоже какой-то более рациональный способ есть Ниже патч и sql - работает система просто, добавляем в таблицу ID аккаунта рефера и ID аккаунтов реферралов. Вынесение опций в конфиг, высылку на почту жевры/ракеты и прочую мелкую косметику не делал, если будет необходимость, с радостью сделаю. Ну и все замечания и предложения по патчу рассмотрю внимательно А так же отписывайтесь об ошибках, я мог позабыть что-то включить в патч, а сейчас проверить не могу С Новым Годом Последний раз редактировалось MaS0n; 02.01.2011 в 17:58. |
22 пользователя(ей) сказали cпасибо: | Ambal (11.01.2011), Den (02.01.2011), Fear (03.01.2011), Fedia22 (02.01.2011), Feel the Power (03.01.2011), Gerald (02.01.2011), ghostpast (02.01.2011), KiriX (02.01.2011), Konctantin (02.01.2011), Lurker (31.01.2011), MaxXx2021 (29.01.2011), Nordway (02.01.2011), PSZ (02.01.2011), Ranger (22.03.2012), selector (09.01.2011), Shadez (02.01.2011), Sid (02.01.2011), SilverIce (29.01.2011), sven (09.01.2011), zergtmn (02.01.2011), Кот ДаWINчи (03.01.2011) |
02.01.2011, 17:43 | #2 |
Пользователь
Регистрация: 07.03.2010
Сообщений: 46
Сказал(а) спасибо: 11
Поблагодарили 17 раз(а) в 11 сообщениях
|
Код:
QueryResult *result = WorldDatabase.Query("SELECT refer_id, referral_id1, referral_id2, referral_id3, referral_id4, referral_id5, grantable_levels FROM refer_a_friend_table"); Тут учитывается такие факта: 1. уровень другу можно поднять только до 60 уровня 2. аккаунты могут быть связаны только на 3 месяца ? а вообще желательна такая таблица в БД realmd PHP код:
PHP код:
Последний раз редактировалось ghostpast; 02.01.2011 в 17:56. |
Пользователь сказал cпасибо: | MaS0n (02.01.2011) |
02.01.2011, 18:02 | #3 |
Модератор
|
Спасибо, перезалил патч, мой косяк
Нет, количество подарочных уровней должно хранится на чаре, который их зарабатывает. Уровень 60 ограничен клиентом, проверка на поднятия уровня выше 60 на сервере тоже имеется(вдруг читеры додумаются обойти клиент ) Ограничение времени связки аккаунтов не делал, если надо, то сделать не проблема Насчет таблицы - в реалмд перенести можно, но все равно надо 5 полей для френдов, т.к на оффе можно 5 друзей пригласить, или как-то хранить 5 ИД акков в одном поле, а-ля бывшая data в БД чаров ПС : чуть позже выложу еще для 2.4.3 версию, т.к отличается тем, что нужно выставлять статус во френд-листе, что в этом патче не делается, я писал выше почему Последний раз редактировалось MaS0n; 02.01.2011 в 18:06. |
02.01.2011, 18:11 | #4 | |
Пользователь
Регистрация: 07.03.2010
Сообщений: 46
Сказал(а) спасибо: 11
Поблагодарили 17 раз(а) в 11 сообщениях
|
Цитата:
с точки зрения теории нормализации моя таблица подойдет - количество друзей в ней неограничено: каждая запись соответствует одному другу. проверять их количество можно в самом коде. еще можно вынести эту опцию в конфиг (если это не ограничение клиента). ограничение времени у меня уже учтено в запросе на списке друзей, достаточно подставлять текущую дату и id приглашающего (либо проверять при запуске сервера). также можно сделать опцию в конфиге Последний раз редактировалось ghostpast; 02.01.2011 в 18:23. |
|
02.01.2011, 18:24 | #5 | |
Модератор
|
Цитата:
мой вариант (рефер и 5 френдов) 1 2 3 4 5 6 твой вариант ( рефер и 5 френдов) 1 2 1 3 1 4 1 5 1 6 Ну тогда в твоей таблице не должно быть PRIMARY KEY ('id'), этот ключ делает значение уникальным |
|
02.01.2011, 18:28 | #6 | |
Пользователь
Регистрация: 07.03.2010
Сообщений: 46
Сказал(а) спасибо: 11
Поблагодарили 17 раз(а) в 11 сообщениях
|
Цитата:
PHP код:
|
|
02.01.2011, 19:53 | #7 |
MaNGOS Dev
Регистрация: 11.03.2010
Сообщений: 468
Сказал(а) спасибо: 0
Поблагодарили 514 раз(а) в 163 сообщениях
|
FriendStatus это маска из флагов, в т.ч. и RAF
Код:
struct FriendInfo { _BYTE Connected; _BYTE Status; _BYTE f2[2]; const char *Name; _BYTE Note[512]; WGUID Guid; signed int Level; _DWORD Class; _DWORD AreaId; _DWORD dword21C; }; Код:
signed int __cdecl Lua_GetFriendInfo(int a1) { signed int result; // eax@3 FriendInfo *fInfo; // edi@6 int v3; // eax@8 char *v4; // ebx@9 int v5; // eax@10 int v6; // ebx@12 const char *v7; // eax@13 DWORD v8; // ecx@13 WGUID v9; // ST18_8@13 int v10; // eax@13 int v11; // eax@17 int v12; // ecx@19 int v13; // eax@20 int v14; // eax@23 const char *v15; // ecx@26 char status; // al@32 char *v17; // eax@33 char *v18; // eax@35 const char *v19; // [sp+4h] [bp-1Ch]@14 WGUID v20; // [sp+14h] [bp-Ch]@5 char *v21; // [sp+1Ch] [bp-4h]@9 if ( !FrameScript__IsNumber(a1, 1) && !FrameScript__IsString(a1, 1) ) { FrameScript__DisplayError(a1, "Usage: GetFriendInfo(index or name)"); return 0; } if ( FrameScript__IsNumber(a1, 1) ) { v20 = (WGUID)(signed __int64)FrameScript__ToNumber(a1, 1); if ( v20.guid_low - 1 <= 100 ) fInfo = (FriendInfo *)((char *)dword_C79F98 + 544 * (v20.guid_low - 1)); else fInfo = 0; } else { v3 = FrameScript__ToLString(a1, 1, 0); fInfo = (FriendInfo *)GetFriendInfoByName(dword_C79F98, v3); } v4 = FrameScript__GetText("UNKNOWN", -1, 0); v21 = v4; if ( !fInfo ) { FrameScript__pushnil(a1); // name FrameScript__PushNumber(a1, 0.0); // level FrameScript__PushString(a1, v4); // class FrameScript__PushString(a1, v4); // area FrameScript__pushnil(a1); // connected FrameScript__PushString(a1, &byte_9E14FF); // status FrameScript__pushnil(a1); // note FrameScript__pushnil(a1); // RAF return 8; } FrameScript__PushString(a1, fInfo->Name); // name FrameScript__PushNumber(a1, (double)fInfo->Level);// level v5 = fInfo->Class; if ( v5 < g_ChrClassesDB.minIndex || v5 > g_ChrClassesDB.maxIndex || (v6 = g_ChrClassesDB.Rows[v5 - g_ChrClassesDB.minIndex], !v6) ) { v7 = v21; goto LABEL_16; } v8 = fInfo->Guid.guid_low; v20.guid_low = 0; v20.guid_high = 0; v9.guid_high = fInfo->Guid.guid_high; v9.guid_low = v8; v10 = DbNameCache_GetInfoBlockById(&WDB_CACHE_NAME, *(_QWORD *)&v9, (int)&v20, 0, 0, 0); v7 = (const char *)sub_72AAB0(0, v10); if ( v7 ) { LABEL_16: v19 = v7; goto LABEL_17; } v19 = *(const char **)(v6 + 16); LABEL_17: FrameScript__PushString(a1, v19); // class v11 = fInfo->AreaId; if ( v11 < g_AreaTableDB.minIndex ) goto LABEL_46; if ( v11 > g_AreaTableDB.maxIndex ) goto LABEL_46; v12 = g_AreaTableDB.Rows[v11 - g_AreaTableDB.minIndex]; if ( !v12 ) goto LABEL_46; v13 = *(_DWORD *)(v12 + 8); if ( v13 ) { if ( v13 >= g_AreaTableDB.minIndex ) { if ( v13 <= g_AreaTableDB.maxIndex ) { v14 = g_AreaTableDB.Rows[v13 - g_AreaTableDB.minIndex]; if ( v14 ) v12 = v14; } } } if ( v12 ) v15 = *(const char **)(v12 + 44); else LABEL_46: v15 = v21; FrameScript__PushString(a1, v15); // area if ( fInfo->Connected ) FrameScript__PushNumber(a1, 1.0); // connected else FrameScript__pushnil(a1); // connected if ( !fInfo->Connected ) goto LABEL_36; status = fInfo->Status; if ( !(status & 4) ) { if ( status & 2 ) { v18 = FrameScript__GetText("CHAT_FLAG_AFK", -1, 0); FrameScript__PushString(a1, v18); // status goto LABEL_37; } LABEL_36: FrameScript__PushString(a1, &byte_9E14FF); // status goto LABEL_37; } v17 = FrameScript__GetText("CHAT_FLAG_DND", -1, 0); FrameScript__PushString(a1, v17); // status LABEL_37: if ( fInfo->Note[0] ) FrameScript__PushString(a1, fInfo->Note); // note else FrameScript__pushnil(a1); // note if ( fInfo->Status & 8 ) { FrameScript__PushNumber(a1, 1.0); // RAF result = 8; } else { FrameScript__pushnil(a1); // RAF result = 8; } return result; } Последний раз редактировалось TOM_RUS; 02.01.2011 в 20:18. |
Пользователь сказал cпасибо: | MaS0n (02.01.2011) |
02.01.2011, 20:25 | #8 |
Модератор
|
Большое спасибо за разьяснение, но я имел в виду это
Код:
enum FriendStatus { FRIEND_STATUS_OFFLINE = 0, FRIEND_STATUS_ONLINE = 1, FRIEND_STATUS_AFK = 2, FRIEND_STATUS_UNK3 = 3, FRIEND_STATUS_DND = 4 }; enum SocialFlag { SOCIAL_FLAG_FRIEND = 0x01, SOCIAL_FLAG_IGNORED = 0x02, SOCIAL_FLAG_MUTED = 0x04, // guessed SOCIAL_FLAG_RAF = 0x08 // Recruit-A-Friend }; Код:
enum FriendStatus { FRIEND_STATUS_OFFLINE = 0, FRIEND_STATUS_ONLINE = 1, FRIEND_STATUS_AFK = 2, FRIEND_STATUS_UNK3 = 3, FRIEND_STATUS_DND = 4, FRIEND_STATUS_RAF = 8 // Recruit-A-Friend }; enum SocialFlag { SOCIAL_FLAG_FRIEND = 0x01, SOCIAL_FLAG_IGNORED = 0x02, SOCIAL_FLAG_MUTED = 0x04, // guessed }; Код:
if ( fInfo->Status & 8 ) { FrameScript__PushNumber(a1, 1.0); // RAF result = 8; } Код:
CDataStore__GetInt64(v4, (int)&v36); // guid CDataStore__GetInt32(v4, (int)&v33); // flags CDataStore__GetString(v4, (int)&v23, 0x200u); // note if ( v33 & 1 ) // if flags & SOCIAL_FLAG_FRIEND { v28 = 0; v31 = 0; v32 = 0; CDataStore__GetInt8(v4, (int)&v37); // status v8 = v37; if ( v37 ) { CDataStore__GetInt32(v4, (int)&v28); // area CDataStore__GetInt32(v4, (int)&v31); // level CDataStore__GetInt32(v4, (int)&v32); // class v8 = v37; } Код:
data << uint64(itr->first); // player guid data << uint32(itr->second.Flags); // player flag (0x1-friend?, 0x2-ignored?, 0x4-muted?) data << itr->second.Note; // string note if(itr->second.Flags & SOCIAL_FLAG_FRIEND) // if IsFriend() { data << uint8(itr->second.Status); // online/offline/etc? if(itr->second.Status) // if online { data << uint32(itr->second.Area); // player area data << uint32(itr->second.Level); // player level data << uint32(itr->second.Class); // player class } } x & 1 - friend list update x & 2 - ignored list update x & 4 - muted list update Восьмерки там нет, и клиент такое не обрабатывает И надо дропнуть Код:
FRIEND_STATUS_UNK3 = 3 Последний раз редактировалось MaS0n; 02.01.2011 в 20:54. |
02.01.2011, 20:55 | #9 |
MaNGOS Dev
Регистрация: 11.03.2010
Сообщений: 468
Сказал(а) спасибо: 0
Поблагодарили 514 раз(а) в 163 сообщениях
|
Да, перепутаны флаги статуса и списка, FRIEND_STATUS_UNK3 вообще лишний.
|
03.01.2011, 18:26 | #10 |
Модератор
|
Выложу завтра-послезавтра с ограничением времени, а так же сделаю вариант с реалмд таблицей
TOM_RUS, закоммитили бы эти исправления |
07.01.2011, 20:01 | #11 |
Почетный флудер
Старожил
Регистрация: 08.03.2010
Адрес: Мурманск, Россия
Сообщений: 788
Сказал(а) спасибо: 55
Поблагодарили 333 раз(а) в 151 сообщениях
Записей в дневнике: 1
|
Во первых спасибо за работу.
Решил попробовать запустить этот патч. Сразу возникла куча вопросов. 1. Список слинкованных аккаунтов грузится только при старте сервера. Это по идее так? А если аптайм месяц? 2. Фичи слинкованных аккаунтов работают только в пати. Ограничение в коде патча. Так и должно быть? 3. Приглашенный уже не может быть приглашающим и наоборот? По коду либо то либо другое. 4. Почем не использован штатный SetSelectionGuid()? Есть причины, может я чего-то не понимаю? Потому что если его использовать то весь код из spell.cpp и spelleffect.cpp просто не нужен. |
07.01.2011, 20:13 | #13 |
Ученый
Регистрация: 10.03.2010
Адрес: Бобруйск
Сообщений: 284
Сказал(а) спасибо: 213
Поблагодарили 98 раз(а) в 84 сообщениях
|
|
07.01.2011, 20:55 | #14 | |
Почетный флудер
Старожил
Регистрация: 08.03.2010
Адрес: Мурманск, Россия
Сообщений: 788
Сказал(а) спасибо: 55
Поблагодарили 333 раз(а) в 151 сообщениях
Записей в дневнике: 1
|
Цитата:
Новый вопрос - бонусные уровни даются приглашающему каждый второй левел до 60? Или я неправильно понял код? То есть 80-му пару левелов на "лишней" экспе для приглашенного не набить? |
|
07.01.2011, 22:26 | #15 |
Ученый
Регистрация: 10.03.2010
Адрес: Бобруйск
Сообщений: 284
Сказал(а) спасибо: 213
Поблагодарили 98 раз(а) в 84 сообщениях
|
|
07.01.2011, 23:56 | #17 |
Почетный флудер
Старожил
Регистрация: 08.03.2010
Адрес: Мурманск, Россия
Сообщений: 788
Сказал(а) спасибо: 55
Поблагодарили 333 раз(а) в 151 сообщениях
Записей в дневнике: 1
|
вроде будет. только это дурная мысль изначально - что, ГМ будет сидеть в игре, сканить таблицу и перезагружать ее ручками как кто-то рефера поставит? да и вообще хранение линков в objectmgr изначально неэкономично, и сделанный тут поиск - кошмар системщика
я уже все это сделал вроде нормально, с конфигом и рейтами, потестирую и через пару дней тут положу... |
08.01.2011, 08:10 | #18 |
Пользователь
Регистрация: 08.03.2010
Сообщений: 43
Сказал(а) спасибо: 1
Поблагодарили 1 раз в 1 сообщении
|
Создаем твинка на 2м акке и в 2 окна его качаем с бонусными рейтами, от этого есть защита?
Или договариваемся кому надо прокачать твинка и качаем по очереди, надо проверку на отсутствие акаунта у приглашенного на сервере. У близзов каждый акк надо оплачивать, а тут наделают акков и вперед твинков качать. Последний раз редактировалось Mr.Grom; 08.01.2011 в 08:17. |
08.01.2011, 11:38 | #19 | |
Почетный флудер
Старожил
Регистрация: 08.03.2010
Адрес: Мурманск, Россия
Сообщений: 788
Сказал(а) спасибо: 55
Поблагодарили 333 раз(а) в 151 сообщениях
Записей в дневнике: 1
|
Цитата:
Крайний вопрос остался, может кто-то все же знает - приглашенный сам кого-то может пригласить? И как в таком случае ведет себя RAF система? И может ли быть у одного приглашенного несколько приглашающих? Я пока сделал ограничение по числу приглашенных и приглашающих на аккаунт через конфиг. Народ сам разберется. |
|
08.01.2011, 12:44 | #20 | |
Пользователь
Регистрация: 07.03.2010
Сообщений: 46
Сказал(а) спасибо: 11
Поблагодарили 17 раз(а) в 11 сообщениях
|
Цитата:
А - приглашающий Б - приглашенный А В - приглашенный Б когда в группе только (А и Б) или (Б и В) - работает как написано выше. случаи, когда в группе А, Б и В не встречал когда в группе только А и В - никаких бонусов нет может.на e-mail высылается ключ, который вводится вместо пробного ключа. соответственно 2 раза активировать приглашение на одном аккаунте не получится. после активиции приглашения у приглашающего количество возможных приглашений увеличивается на 1. (то есть изначально доступно 5 приглашений. когда приглашаем друга их остается 4. после ввода ключа количество приглашений снова 5) Последний раз редактировалось ghostpast; 08.01.2011 в 12:50. |
|
08.01.2011, 11:54 | #21 |
Модератор
|
Я тоже переделал загрузку информации о RAF и вынес некоторые опции в конфиг, так же реализовал истечение времени услуги через 3 месяца, но выложить пока не могу, во-первых еще тестирую, во-вторых - сессия.
Отвечаю на вопросы : - насчет нерациональности хранения и загрузки информации в курсе, моей целью было заложить основу, работу пакетов, основных аспектов, а уже потом дорабатывать для принятия в офф. репо. Там, кстати выставление дин. флагов тоже нерационально, их надо слать где-то в BuildUpdateBlockForPlayer - фичи слинкованных аккаунтов и в клиенте работают только в пати, я на всякий случай вкрутил проверки против читеров - в самом клиенте стоит ограничение в 60, опции отключаются после 60 уровня, мой код - проверки против читеров - про приглашенного и приглашающего, скорей всего нет, я руководствовался этой статьей - http://eu.blizzard.com/support/artic...rticleId=31211 - его бесполезно использовать, т.к если в пати например у нас 2 друга, при суммоне например через шарик во френд-листе, НЕ ВЫДЕЛЯЯ того, кого хотим суммонить, верный гуид отсылается ОДИН РАЗ через этот пакет (CMSG_SET_SELECTION), после чего тут же идет 0 гуид ПС : там кстати краш возможен, при выделении моба Код:
diff --git a/MiscHandler.cpp b/MiscHandler.cpp index 5be3b1e..8da1110 100644 --- a/MiscHandler.cpp +++ b/MiscHandler.cpp @@ -408,6 +408,9 @@ void WorldSession::HandleSetSelectionOpcode( WorldPacket & recv_data ) if (!unit) return; + if (_player->IsReferAFriendLinked(((Player*)unit)) && !_player->isSummonFriendNeedSelect()) + _player->SetSummonFriendGuid(guid); + if(FactionTemplateEntry const* factionTemplateEntry = sFactionTemplateStore.LookupEntry(unit->getFaction())) _player->GetReputationMgr().SetVisible(factionTemplateEntry); } Код:
diff --git a/MiscHandler.cpp b/MiscHandler.cpp index 5be3b1e..8da1110 100644 --- a/MiscHandler.cpp +++ b/MiscHandler.cpp @@ -408,6 +408,9 @@ void WorldSession::HandleSetSelectionOpcode( WorldPacket & recv_data ) if (!unit) return; + if (unit->GetTypeId() == TYPEID_PLAYER) + { + if (_player->IsReferAFriendLinked(((Player*)unit)) && !_player->isSummonFriendNeedSelect()) + _player->SetSummonFriendGuid(guid); + } + if(FactionTemplateEntry const* factionTemplateEntry = sFactionTemplateStore.LookupEntry(unit->getFaction())) _player->GetReputationMgr().SetVisible(factionTemplateEntry); } |
08.01.2011, 12:50 | #22 | |
Почетный флудер
Старожил
Регистрация: 08.03.2010
Адрес: Мурманск, Россия
Сообщений: 788
Сказал(а) спасибо: 55
Поблагодарили 333 раз(а) в 151 сообщениях
Записей в дневнике: 1
|
Цитата:
не очень понятно в чем проблема. ну нулевой, так проще его не назначать и все. у меня работает, безо всего этого геморроя в spell.cpp а вот с отсылкой флага надо что-то решать. пока флаг не проявляется пока друга "в натуре" не увидеть, а это не есть хорошо. |
|
08.01.2011, 12:59 | #23 |
Модератор
|
Ну не знаю, если не сейвить гуид игрока куда-то кроме curSelection можем получить 2 бага, первый, когда каст начинается, присылается на селект нулевой гуид, и если вы сумоните игрока, не видя его в прямой видимости, будет ересь
Второй, если тип во время каста суммона (10 секунд) захочет потыкать мышкой в мобов или других игроков, селект снова заменится черт знает чем |
08.01.2011, 13:22 | #24 | |
Почетный флудер
Старожил
Регистрация: 08.03.2010
Адрес: Мурманск, Россия
Сообщений: 788
Сказал(а) спасибо: 55
Поблагодарили 333 раз(а) в 151 сообщениях
Записей в дневнике: 1
|
Цитата:
|
|
08.01.2011, 15:36 | #25 |
Ученый
Регистрация: 03.03.2010
Адрес: Сибирь, 58°14′00″ с. ш. 92°29′00″ в. д.
Сообщений: 288
Сказал(а) спасибо: 79
Поблагодарили 37 раз(а) в 14 сообщениях
Записей в дневнике: 18
|
сумон идёт даже если человек не выбран в таргет, сумонить можно только в пати, если сумон до конца не прошёл, а я прервал каст (пробежался или ещё что либо) то вешается часовой КД...
|
08.01.2011, 16:08 | #26 |
Модератор
|
Дааа, похоже я ошибся и с шариком, и в общем, когда далеко френды друг от друга, дин. флаги не работают, и в листе шарика нету. Так что вышеприведенные правки весьма актуальны
Так же, мне удалось разыскать флаг 0x100, про который я знаю, что он является условием в пати/группе при отсутствии прямой видимости. Но только он не шлется в SMSG_GROUP_LIST, а шлется в SMSG_PARTY_MEMBER_STATS_FULL. Код:
enum GroupMemberOnlineStatus { MEMBER_STATUS_OFFLINE = 0x0000, MEMBER_STATUS_ONLINE = 0x0001, MEMBER_STATUS_PVP = 0x0002, MEMBER_STATUS_UNK0 = 0x0004, // dead? (health=0) MEMBER_STATUS_UNK1 = 0x0008, // ghost? (health=1) MEMBER_STATUS_UNK2 = 0x0010, // never seen MEMBER_STATUS_UNK3 = 0x0020, // never seen MEMBER_STATUS_UNK4 = 0x0040, // appears with dead and ghost flags MEMBER_STATUS_UNK5 = 0x0080, // never seen + MEMBER_STATUS_2_RAF = 0x0100 // RAF status in party/raid, is correct status??? or flag??? }; Покопав еще немного, я выяснил его истинное место Код:
data << uint32(mask1); // group update mask data << uint16(MEMBER_STATUS_ONLINE); // member's online status data << uint32(player->GetHealth()); // GROUP_UPDATE_FLAG_CUR_HP data << uint32(player->GetMaxHealth()); // GROUP_UPDATE_FLAG_MAX_HP data << uint8(powerType); // GROUP_UPDATE_FLAG_POWER_TYPE data << uint16(player->GetPower(powerType)); // GROUP_UPDATE_FLAG_CUR_POWER data << uint16(player->GetMaxPower(powerType)); // GROUP_UPDATE_FLAG_MAX_POWER data << uint16(player->getLevel()); // GROUP_UPDATE_FLAG_LEVEL data << uint16(player->GetZoneId()); // GROUP_UPDATE_FLAG_ZONE data << uint16(player->GetPositionX()); // GROUP_UPDATE_FLAG_POSITION data << uint16(player->GetPositionY()); // GROUP_UPDATE_FLAG_POSITION ПС - насчет селекшн я пока все равно не понимаю, сохранить корректный селект гуид для последующей активации эффекта 152 и эффекта суммона невозможно в текущих условиях, имхо Последний раз редактировалось MaS0n; 08.01.2011 в 16:11. |
Пользователь сказал cпасибо: | rsa (08.01.2011) |
08.01.2011, 16:24 | #27 | |
Почетный флудер
Старожил
Регистрация: 08.03.2010
Адрес: Мурманск, Россия
Сообщений: 788
Сказал(а) спасибо: 55
Поблагодарили 333 раз(а) в 151 сообщениях
Записей в дневнике: 1
|
Цитата:
https://github.com/rsa/mangos/commit...17c36832159e00 ладно, попробую сейчас эти флаги тоже сделать, спасибо за исследование. нормально работает без допсохранения гуидов, а насчет тыкать пока кастится - ну можно затычку сделать чтоб не менялся селект во время каста. только зачем? пускай игроки привыкают ручками не шалить. |
|
Пользователь сказал cпасибо: | MaS0n (08.01.2011) |
08.01.2011, 16:30 | #28 |
Модератор
|
вносить так и так придется без этого вне прямой видимости опции даже не появляются, тестил на 2 персах, один в Тераморе, другой в Эльвине был
Насчет шарика во френд-листе я терь совсем теряюсь, если флаги в группе верны - шарик во френд листе появляется опять-таки сам, если персы рядом и в зоне видимости, опять сам, нужен или не нужен статус я так и не понял, но раз близы его проверяют, то думаю пригодится ВОт здесь вся инфа об этом - http://ru-mangos.ru/showpost.php?p=17927&postcount=8 ПС - кажется понял, сначала проверяется прямая видимость, если ок - выход с возвратом 1, потом группа/рейд, точно так же и только потом уже френд-лист, так что лучше статус делать rsa, просмотрел коммит, отлично, спс за участие, думаю доведем патч до офф. репо Последний раз редактировалось MaS0n; 08.01.2011 в 16:34. |
08.01.2011, 16:36 | #29 | |
Почетный флудер
Старожил
Регистрация: 08.03.2010
Адрес: Мурманск, Россия
Сообщений: 788
Сказал(а) спасибо: 55
Поблагодарили 333 раз(а) в 151 сообщениях
Записей в дневнике: 1
|
Цитата:
Так. Проверил, групфлаг пашет хотя как-то странно, не до конца понял. Но в разных зонах при создании пати шарик активируется. А вот при загрузке - не всегда. Ну и так уже отлично просто. Правка: https://github.com/rsa/mangos/commit...044c681b660337 Последний раз редактировалось rsa; 08.01.2011 в 16:53. |
|
08.01.2011, 16:42 | #30 |
Модератор
|
Угу, поможет, но лучше и статус прокидывать во френд-листе - я думаю, просто на всякий случай
|
08.01.2011, 16:54 | #31 |
Почетный флудер
Старожил
Регистрация: 08.03.2010
Адрес: Мурманск, Россия
Сообщений: 788
Сказал(а) спасибо: 55
Поблагодарили 333 раз(а) в 151 сообщениях
Записей в дневнике: 1
|
Давайте нужные флаги - допишу Я не игрок и сам ничего не сниффаю, поэтому без той работы что вами проделана сам бы хрен чего сваял.
|
08.01.2011, 16:58 | #32 |
MaNGOS Dev
Регистрация: 11.03.2010
Сообщений: 468
Сказал(а) спасибо: 0
Поблагодарили 514 раз(а) в 163 сообщениях
|
Код:
enum GroupMemberFlags { MEMBER_STATUS_OFFLINE = 0x0000, MEMBER_STATUS_ONLINE = 0x0001, // Lua_UnitIsConnected MEMBER_STATUS_PVP = 0x0002, // Lua_UnitIsPVP MEMBER_STATUS_DEAD = 0x0004, // Lua_UnitIsDead MEMBER_STATUS_GHOST = 0x0008, // Lua_UnitIsGhost MEMBER_STATUS_PVP_FFA = 0x0010, // Lua_UnitIsPVPFreeForAll MEMBER_STATUS_UNK3 = 0x0020, // used in calls from Lua_GetPlayerMapPosition/Lua_GetBattlefieldFlagPosition MEMBER_STATUS_AFK = 0x0040, // Lua_UnitIsAFK MEMBER_STATUS_DND = 0x0080, // Lua_UnitIsDND MEMBER_STATUS_RAF = 0x0100, // Lua_IsReferAFriendLinked MEMBER_STATUS_UNK4 = 0x0200, // something to do with vehicles }; Код:
char __stdcall Is_RAF_Player(WGUID guid) { void *v1; // eax@1 unsigned int v2; // eax@2 GroupMemberInfo *groupInfo; // eax@3 SosialInfo *socialInfo; // eax@8 v1 = ClntObjMgrGetObjectPtr(guid, TYPEMASK_PLAYER, ".\\Player_C.cpp", 15314); if ( v1 ) { v2 = (*(_DWORD *)(*((_DWORD *)v1 + 62) + 356) >> 6) & 1;// UNIT_DYNAMIC_FLAGS & 0x40 } else { groupInfo = (GroupMemberInfo *)GetPartyMemberInfoByGuid((int)&guid); if ( (groupInfo || (groupInfo = (GroupMemberInfo *)GetRaidMemberInfoByGuid(&guid)) != 0) && groupInfo->StatusFlags & 0x100 ) { LOBYTE(v2) = 1; } else { if ( g_socialList && (socialInfo = (SosialInfo *)GetSocialInfoByGuid(g_socialList, *(_QWORD *)&guid)) != 0 ) v2 = ((unsigned int)socialInfo->SocialFlags >> 3) & 1;// SocialFlags & 0x08 else LOBYTE(v2) = 0; } } return v2; } Последний раз редактировалось TOM_RUS; 08.01.2011 в 17:36. |
Пользователь сказал cпасибо: | MaS0n (08.01.2011) |
08.01.2011, 17:07 | #33 |
Модератор
|
Для шарика/френд-листа
SocialMgr.h Код:
enum FriendStatus { FRIEND_STATUS_OFFLINE = 0, FRIEND_STATUS_ONLINE = 1, FRIEND_STATUS_AFK = 2, - FRIEND_STATUS_UNK3 = 3, FRIEND_STATUS_DND = 4, + FRIEND_STATUS_RAF = 8 }; enum SocialFlag { SOCIAL_FLAG_FRIEND = 0x01, SOCIAL_FLAG_IGNORED = 0x02, SOCIAL_FLAG_MUTED = 0x04, // guessed - SOCIAL_FLAG_RAF = 0x08 // Recruit-A-Friend }; Код:
for(PlayerSocialMap::iterator itr = m_playerSocialMap.begin(); itr != m_playerSocialMap.end(); ++itr) { sSocialMgr.GetFriendInfo(plr, itr->first, itr->second); data << uint64(itr->first); // player guid data << uint32(itr->second.Flags); // player flag (0x1-friend?, 0x2-ignored?, 0x4-muted?) data << itr->second.Note; // string note if(itr->second.Flags & SOCIAL_FLAG_FRIEND) // if IsFriend() { data << uint8(itr->second.Status); // online/offline/etc? if(itr->second.Status) // if online { data << uint32(itr->second.Area); // player area data << uint32(itr->second.Level); // player level data << uint32(itr->second.Class); // player class } } } PS - ну я не снифал, это чистые раскопки клиента Последний раз редактировалось MaS0n; 08.01.2011 в 17:10. |
08.01.2011, 17:45 | #34 |
Почетный флудер
Старожил
Регистрация: 08.03.2010
Адрес: Мурманск, Россия
Сообщений: 788
Сказал(а) спасибо: 55
Поблагодарили 333 раз(а) в 151 сообщениях
Записей в дневнике: 1
|
поскольку уже решили что статус - это маска флагов, то не перед этим а в этом. только тогда работу со статусом придется переделать...
|
08.01.2011, 17:49 | #35 |
MaNGOS Dev
Регистрация: 11.03.2010
Сообщений: 468
Сказал(а) спасибо: 0
Поблагодарили 514 раз(а) в 163 сообщениях
|
Надо
Код:
void SocialMgr::GetFriendInfo(Player *player, uint32 friend_lowguid, FriendInfo &friendInfo) |
08.01.2011, 18:19 | #36 |
Модератор
|
Угу, в этой функции хорошо статус присвоить
Кстати, а он в ней верно присваивается, не должна быть маска с онлайн статусом и афк/днд? Типа вот так Код:
friendInfo.Status = FRIEND_STATUS_ONLINE; if(pFriend->isAFK()) - friendInfo.Status = FRIEND_STATUS_AFK; + friendInfo.Status |= FRIEND_STATUS_AFK; if(pFriend->isDND()) - friendInfo.Status = FRIEND_STATUS_DND; + friendInfo.Status |= FRIEND_STATUS_DND; TOM_RUS, мне кажется что SocialInfo и FriendInfo, которую вы выкладывали чуть раньше, это одинаковые структуры, и назватся она должна именно SocialInfo. У вас SocialFlags в этой функции неверны, а та структура идеально подходит |
08.01.2011, 22:31 | #37 |
Почетный флудер
Старожил
Регистрация: 08.03.2010
Адрес: Мурманск, Россия
Сообщений: 788
Сказал(а) спасибо: 55
Поблагодарили 333 раз(а) в 151 сообщениях
Записей в дневнике: 1
|
С учетом изложенного по флагам:
https://github.com/rsa/mangos/commit...517a01e7282ddc осталась косметика, уже не принципиальная (вывод списка и тому подобное). |
09.01.2011, 00:27 | #38 |
Пользователь
|
Вопрос: если призываешь друга который выше тебя по левелу - каст должен проходить или нет?
|
09.01.2011, 07:32 | #39 | ||
Почетный флудер
Старожил
Регистрация: 08.03.2010
Адрес: Мурманск, Россия
Сообщений: 788
Сказал(а) спасибо: 55
Поблагодарили 333 раз(а) в 151 сообщениях
Записей в дневнике: 1
|
Цитата:
Добавлено через 3 минуты Цитата:
а вот с репутацией надо подумать еще... |
||
09.01.2011, 07:40 | #40 |
Ученый
|
|
|
|
Похожие темы | ||||
Тема | Автор | Раздел | Ответов | Последнее сообщение |
[patch/dev] Pet stat scaling system | rsa | Патчи | 9 | 22.01.2015 12:13 |
[10924][patch] Timer system improved | Ambal | Принятые патчи | 26 | 27.12.2010 11:27 |
[10089] Change in event system work with pool system. | newsbot | CMaNGOS Commits | 0 | 21.06.2010 05:22 |
[10052] Camera System | newsbot | CMaNGOS Commits | 10 | 16.06.2010 02:33 |
[patch] Camera system | SilverIce | Принятые патчи | 7 | 07.04.2010 11:23 |