[patch/dev] Refer-A-Friend System
Вложений: 2
Собственно, патч, реализующий оффлайк систему "Пригласи друга"
Не совершенство, скорее бета-версия, но все же, ниже поясню почему Немного теории Услуга включает в себя 3 основые фишки - призвать друга, повысить уровень и утроенный опыт. Третью часть можно отбросить, это делается целиком на сервере. Призвать друга Опция при клике на портрете друга в пати и синий шарик во френд-листе. Кстати в 3.3.5 он выставляется независимо от статуса друга, и, позволю себе поправить уважаемого TOM_RUS в посте http://ru-mangos.ru/showpost.php?p=8598&postcount=4, это не флаг, а все-таки статус, проверял в дебаге клиента на 2.4.3., тем более если структура FriendInfo соотв. близз структуре в памяти, то по смещению pointer + 1 хранится как раз таки статус Код:
struct FriendInfo Проблема была вот с чем, я писал в той теме, что не мог получить гуид того, кого нужно призвать, не выделяя его. Проблема "легко" решилась, когда я подетальнее разобрал lua функцию SummonFriend - там до каста спелла, если цель не в прямой видимости, а вызывается допустим через тот же шарик, шлется пакет под номером 317 - CMSG_SET_SELECTION Код:
v8 = 0; Повысить уровень Основная проблема заключалась в том, что опция активировалась только при опр. условиях, и их удалось найти, опять же подебажив клиент и рассмотрев смещения полей в структурах После проходв кучи проверок доходим до такой проверки, где результат либо 0, либо 3 , 0 - это верно, 3 - вернет ошибку Код:
result = *(_BYTE *)(*((_DWORD *)v13 + 1026) + 4197) < 1u ? 3 : 0; Код:
.text:006DEB02 mov ecx, [esi+1008h] Предлагайте свои варианты, т.к очень хотелось бы довести патч до официального репозитория Да, и я использовал отдельную таблицу для реферского(приглашающего) аккаунта и 5 реферралов(приглашенных) - мб тоже какой-то более рациональный способ есть Ниже патч и sql - работает система просто, добавляем в таблицу ID аккаунта рефера и ID аккаунтов реферралов. Вынесение опций в конфиг, высылку на почту жевры/ракеты и прочую мелкую косметику не делал, если будет необходимость, с радостью сделаю. Ну и все замечания и предложения по патчу рассмотрю внимательно :) А так же отписывайтесь об ошибках, я мог позабыть что-то включить в патч, а сейчас проверить не могу С Новым Годом :) |
Код:
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 код:
|
Спасибо, перезалил патч, мой косяк
Нет, количество подарочных уровней должно хранится на чаре, который их зарабатывает. Уровень 60 ограничен клиентом, проверка на поднятия уровня выше 60 на сервере тоже имеется(вдруг читеры додумаются обойти клиент :)) Ограничение времени связки аккаунтов не делал, если надо, то сделать не проблема Насчет таблицы - в реалмд перенести можно, но все равно надо 5 полей для френдов, т.к на оффе можно 5 друзей пригласить, или как-то хранить 5 ИД акков в одном поле, а-ля бывшая data в БД чаров ПС : чуть позже выложу еще для 2.4.3 версию, т.к отличается тем, что нужно выставлять статус во френд-листе, что в этом патче не делается, я писал выше почему |
Цитата:
с точки зрения теории нормализации моя таблица подойдет - количество друзей в ней неограничено: каждая запись соответствует одному другу. проверять их количество можно в самом коде. еще можно вынести эту опцию в конфиг (если это не ограничение клиента). ограничение времени у меня уже учтено в запросе на списке друзей, достаточно подставлять текущую дату и id приглашающего (либо проверять при запуске сервера). также можно сделать опцию в конфиге |
Цитата:
мой вариант (рефер и 5 френдов) 1 2 3 4 5 6 твой вариант ( рефер и 5 френдов) 1 2 1 3 1 4 1 5 1 6 Ну тогда в твоей таблице не должно быть PRIMARY KEY ('id'), этот ключ делает значение уникальным |
Цитата:
PHP код:
|
Цитата:
Код:
struct FriendInfo Код:
signed int __cdecl Lua_GetFriendInfo(int a1) |
Большое спасибо за разьяснение, но я имел в виду это
Код:
enum FriendStatus Код:
enum FriendStatus Код:
if ( fInfo->Status & 8 ) Код:
CDataStore__GetInt64(v4, (int)&v36); // guid Код:
data << uint64(itr->first); // player guid x & 1 - friend list update x & 2 - ignored list update x & 4 - muted list update Восьмерки там нет, и клиент такое не обрабатывает И надо дропнуть Код:
FRIEND_STATUS_UNK3 = 3 |
Да, перепутаны флаги статуса и списка, FRIEND_STATUS_UNK3 вообще лишний.
|
Выложу завтра-послезавтра с ограничением времени, а так же сделаю вариант с реалмд таблицей
TOM_RUS, закоммитили бы эти исправления :) |
Во первых спасибо за работу.
Решил попробовать запустить этот патч. Сразу возникла куча вопросов. 1. Список слинкованных аккаунтов грузится только при старте сервера. Это по идее так? А если аптайм месяц? 2. Фичи слинкованных аккаунтов работают только в пати. Ограничение в коде патча. Так и должно быть? 3. Приглашенный уже не может быть приглашающим и наоборот? По коду либо то либо другое. 4. Почем не использован штатный SetSelectionGuid()? Есть причины, может я чего-то не понимаю? Потому что если его использовать то весь код из spell.cpp и spelleffect.cpp просто не нужен. |
Цитата:
|
Цитата:
|
Цитата:
Новый вопрос - бонусные уровни даются приглашающему каждый второй левел до 60? Или я неправильно понял код? То есть 80-му пару левелов на "лишней" экспе для приглашенного не набить? |
да даётся всего до 60 лвла, дальше уже ни как....
|
|
вроде будет. только это дурная мысль изначально - что, ГМ будет сидеть в игре, сканить таблицу и перезагружать ее ручками как кто-то рефера поставит? да и вообще хранение линков в objectmgr изначально неэкономично, и сделанный тут поиск - кошмар системщика ;)
я уже все это сделал вроде нормально, с конфигом и рейтами, потестирую и через пару дней тут положу... |
Создаем твинка на 2м акке и в 2 окна его качаем с бонусными рейтами, от этого есть защита?
Или договариваемся кому надо прокачать твинка и качаем по очереди, надо проверку на отсутствие акаунта у приглашенного на сервере. У близзов каждый акк надо оплачивать, а тут наделают акков и вперед твинков качать. |
Цитата:
Крайний вопрос остался, может кто-то все же знает - приглашенный сам кого-то может пригласить? И как в таком случае ведет себя RAF система? И может ли быть у одного приглашенного несколько приглашающих? Я пока сделал ограничение по числу приглашенных и приглашающих на аккаунт через конфиг. Народ сам разберется. |
Я тоже переделал загрузку информации о 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 Код:
diff --git a/MiscHandler.cpp b/MiscHandler.cpp |
Цитата:
А - приглашающий Б - приглашенный А В - приглашенный Б когда в группе только (А и Б) или (Б и В) - работает как написано выше. случаи, когда в группе А, Б и В не встречал когда в группе только А и В - никаких бонусов нет Цитата:
|
Цитата:
не очень понятно в чем проблема. ну нулевой, так проще его не назначать и все. у меня работает, безо всего этого геморроя в spell.cpp а вот с отсылкой флага надо что-то решать. пока флаг не проявляется пока друга "в натуре" не увидеть, а это не есть хорошо. |
Ну не знаю, если не сейвить гуид игрока куда-то кроме curSelection можем получить 2 бага, первый, когда каст начинается, присылается на селект нулевой гуид, и если вы сумоните игрока, не видя его в прямой видимости, будет ересь
Второй, если тип во время каста суммона (10 секунд) захочет потыкать мышкой в мобов или других игроков, селект снова заменится черт знает чем |
Цитата:
|
сумон идёт даже если человек не выбран в таргет, сумонить можно только в пати, если сумон до конца не прошёл, а я прервал каст (пробежался или ещё что либо) то вешается часовой КД...
|
Дааа, похоже я ошибся и с шариком, и в общем, когда далеко френды друг от друга, дин. флаги не работают, и в листе шарика нету. Так что вышеприведенные правки весьма актуальны
Так же, мне удалось разыскать флаг 0x100, про который я знаю, что он является условием в пати/группе при отсутствии прямой видимости. Но только он не шлется в SMSG_GROUP_LIST, а шлется в SMSG_PARTY_MEMBER_STATS_FULL. Код:
enum GroupMemberOnlineStatus Покопав еще немного, я выяснил его истинное место Код:
data << uint32(mask1); // group update mask ПС - насчет селекшн я пока все равно не понимаю, сохранить корректный селект гуид для последующей активации эффекта 152 и эффекта суммона невозможно в текущих условиях, имхо |
Цитата:
https://github.com/rsa/mangos/commit...17c36832159e00 ладно, попробую сейчас эти флаги тоже сделать, спасибо за исследование. нормально работает без допсохранения гуидов, а насчет тыкать пока кастится - ну можно затычку сделать чтоб не менялся селект во время каста. только зачем? пускай игроки привыкают ручками не шалить. |
вносить так и так придется :) без этого вне прямой видимости опции даже не появляются, тестил на 2 персах, один в Тераморе, другой в Эльвине был
Насчет шарика во френд-листе я терь совсем теряюсь, если флаги в группе верны - шарик во френд листе появляется опять-таки сам, если персы рядом и в зоне видимости, опять сам, нужен или не нужен статус я так и не понял, но раз близы его проверяют, то думаю пригодится ;) ВОт здесь вся инфа об этом - http://ru-mangos.ru/showpost.php?p=17927&postcount=8 ПС - кажется понял, сначала проверяется прямая видимость, если ок - выход с возвратом 1, потом группа/рейд, точно так же и только потом уже френд-лист, так что лучше статус делать :) rsa, просмотрел коммит, отлично, спс за участие, думаю доведем патч до офф. репо :) |
Цитата:
Так. Проверил, групфлаг пашет хотя как-то странно, не до конца понял. Но в разных зонах при создании пати шарик активируется. А вот при загрузке - не всегда. Ну и так уже отлично просто. Правка: https://github.com/rsa/mangos/commit...044c681b660337 |
Угу, поможет, но лучше и статус прокидывать во френд-листе - я думаю, просто на всякий случай :)
|
Давайте нужные флаги - допишу :) Я не игрок и сам ничего не сниффаю, поэтому без той работы что вами проделана сам бы хрен чего сваял.
|
Код:
enum GroupMemberFlags Код:
char __stdcall Is_RAF_Player(WGUID guid) |
Для шарика/френд-листа
SocialMgr.h Код:
enum FriendStatus Код:
for(PlayerSocialMap::iterator itr = m_playerSocialMap.begin(); itr != m_playerSocialMap.end(); ++itr) PS - ну я не снифал, это чистые раскопки клиента :) |
Цитата:
|
Надо
Код:
void SocialMgr::GetFriendInfo(Player *player, uint32 friend_lowguid, FriendInfo &friendInfo) |
Угу, в этой функции хорошо статус присвоить
Кстати, а он в ней верно присваивается, не должна быть маска с онлайн статусом и афк/днд? Типа вот так Код:
friendInfo.Status = FRIEND_STATUS_ONLINE; TOM_RUS, мне кажется что SocialInfo и FriendInfo, которую вы выкладывали чуть раньше, это одинаковые структуры, и назватся она должна именно SocialInfo. У вас SocialFlags в этой функции неверны, а та структура идеально подходит :) |
С учетом изложенного по флагам:
https://github.com/rsa/mangos/commit...517a01e7282ddc осталась косметика, уже не принципиальная (вывод списка и тому подобное). |
Вопрос: если призываешь друга который выше тебя по левелу - каст должен проходить или нет?
|
Небольшой баг-репортик.
Цитата:
Цитата:
Дальше там шла ифна о прогулочной ракете. Само собой у нас никаких тайм-карт нету и оплаты тоже. Появилась идея - при достижении приглашенного игрока 60лвл, ракета будет выдана пригласившему(в конфиге можно добавить опцию). |
Цитата:
Добавлено через 3 минуты Цитата:
а вот с репутацией надо подумать еще... |
Текущее время: 15:58. Часовой пояс GMT +3. |
ru-mangos.ru - Русское сообщество MaNGOS