Компиляция ядра, создание сборки Trinity Core 3.3.5a под Win32
http://image.zone-game.info/images/1276026531.gif Сегодня мы будем компилировать ядро Trinity Core и создавать на его основе полноценную рабочую сборку. Гайд ориентирован на новичков, но все таки понимающих то, что они будут делать. Нам понадобится:
После того как мы скачали и установили весь необходимый софт, идём дальше по плану, который состоит из следующих пунктов: 1. Скачивание исходников. 2. "Накатывание" патчей на ядро. 3. Сборка компилятора. 4. Компиляция ядра. 5. Настройка ядра. 6. Работа с базами. 6.1. Создание баз.7. Запуск сервера. 8. F.A.Q. Начинаем. 1. Скачивание исходников. Создаем рабочий каталог в "корне" диска, например: Код:
D:\Trinity - Путь не должен содержать кириллицы. Но с помощью этой программы можно скачать и исходники Trinity. Нужно лишь изменить адрес вместо Код:
git clone git://github.com/mangos/mangos.git Код:
git clone git://github.com/TrinityCore/TrinityCore.git Код:
D:\work\source Скачивание исходников завершено. 2. "Накатывание" патчей на ядро. Патч - это некая модификация для ядра, написанная на CPP, которая может в корне изменить работоспособность сервера, начиная от работы спелов заканчивая Гильд-Хаусами. Установка патчей производится с помощью программы Git. Для примера "накатывания" патча, я предлагаю Вам воспользоваться патчем, который дает возможность игрокам получать различные звания за убийства игроков противоположной фракции в зависимости от количества убийств. Сам патч: # HG changeset patch -- Bitbucket.org # Project EasyCore # URL [url]http://bitbucket.org/easytrinity/easycore/overview[/url] # User easytrinity <admin@likenet.ru> # Date 1285770323 -14400 # Node ID ccb906b16695e1f93c91ea9d6f173f60968b9c45 # Parent 9696c9e8cca39bf0626faaf07240ed434d2df805 added PvP Rank system --- a/src/server/game/World/World.cpp +++ b/src/server/game/World/World.cpp @@ -862,6 +862,18 @@ void World::LoadConfigSettings(bool relo sLog.outError("MinPetitionSigns (%i) must be in range 0..9. Set to 9.", m_int_configs[CONFIG_MIN_PETITION_SIGNS]); m_int_configs[CONFIG_MIN_PETITION_SIGNS] = 9; } + rate_values[RATE_PVP_RANK_EXTRA_HONOR] = sConfig.GetFloatDefault("PvPRank.Rate.ExtraHonor", 1); + std::string s_pvp_ranks = sConfig.GetStringDefault("PvPRank.HKPerRank", "10,50,100,200,450,750,1300,2000,3500,6000,9500,15000,21000,30000"); + char *c_pvp_ranks = const_cast<char*>(s_pvp_ranks.c_str()); + for (int i = 0; i !=HKRANKMAX; i++) + { + if (i==0) + pvp_ranks[0] = 0; + else if (i==1) + pvp_ranks[1] = atoi(strtok (c_pvp_ranks, ",")); + else + pvp_ranks[i] = atoi(strtok (NULL, ",")); + } m_int_configs[CONFIG_GM_LOGIN_STATE] = sConfig.GetIntDefault("GM.LoginState", 2); m_int_configs[CONFIG_GM_VISIBLE_STATE] = sConfig.GetIntDefault("GM.Visible", 2); --- a/src/server/game/World/World.h +++ b/src/server/game/World/World.h @@ -390,9 +390,30 @@ enum Rates RATE_DURABILITY_LOSS_PARRY, RATE_DURABILITY_LOSS_ABSORB, RATE_DURABILITY_LOSS_BLOCK, + RATE_PVP_RANK_EXTRA_HONOR, RATE_MOVESPEED, MAX_RATES }; + +enum HonorKillPvPRank +{ + HKRANK00, + HKRANK01, + HKRANK02, + HKRANK03, + HKRANK04, + HKRANK05, + HKRANK06, + HKRANK07, + HKRANK08, + HKRANK09, + HKRANK10, + HKRANK11, + HKRANK12, + HKRANK13, + HKRANK14, + HKRANKMAX +}; /// Can be used in SMSG_AUTH_RESPONSE packet enum BillingPlanFlags @@ -639,6 +660,8 @@ class World void SendZoneText(uint32 zone, const char *text, WorldSession *self = 0, uint32 team = 0); void SendServerMessage(ServerMessageType type, const char *text = "", Player* player = NULL); + uint32 pvp_ranks[HKRANKMAX]; + /// Are we in the middle of a shutdown? bool IsShutdowning() const { return m_ShutdownTimer > 0; } void ShutdownServ(uint32 time, uint32 options, uint8 exitcode); --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -6770,6 +6770,7 @@ bool Player::RewardHonor(Unit *uVictim, uint64 victim_guid = 0; uint32 victim_rank = 0; + uint32 rank_diff = 0; // need call before fields update to have chance move yesterday data to appropriate fields before today data change. UpdateHonorFields(); @@ -6808,22 +6809,52 @@ bool Player::RewardHonor(Unit *uVictim, // [15..28] Horde honor titles and player name // [29..38] Other title and player name // [39+] Nothing - uint32 victim_title = pVictim->GetUInt32Value(PLAYER_CHOSEN_TITLE); - // Get Killer titles, CharTitlesEntry::bit_index + // PLAYER__FIELD_KNOWN_TITLES describe which titles player can use, + // so we must find biggest pvp title , even for killer to find extra honor value + uint32 vtitle = pVictim->GetUInt32Value(PLAYER__FIELD_KNOWN_TITLES); + uint32 victim_title = 0; + uint32 ktitle = GetUInt32Value(PLAYER__FIELD_KNOWN_TITLES); + uint32 killer_title = 0; + if (PLAYER_TITLE_MASK_ALL_PVP & ktitle) + { + for (int i = ((GetTeam() == ALLIANCE) ? 1:HKRANKMAX);i!=((GetTeam() == ALLIANCE) ? HKRANKMAX : (2*HKRANKMAX-1));i++) + { + if (ktitle & (1<<i)) + killer_title = i; + } + } + if (PLAYER_TITLE_MASK_ALL_PVP & vtitle) + { + for (int i = ((pVictim->GetTeam() == ALLIANCE) ? 1:HKRANKMAX);i!=((pVictim->GetTeam() == ALLIANCE) ? HKRANKMAX : (2*HKRANKMAX-1));i++) + { + if (vtitle & (1<<i)) + victim_title = i; + } + } + // Get Killer titles, CharTitlesEntry::bit_index // Ranks: // title[1..14] -> rank[5..18] // title[15..28] -> rank[5..18] // title[other] -> 0 if (victim_title == 0) + victim_guid = 0; // Don't show HK: <rank> message, only log.] + else if (victim_title < HKRANKMAX) + victim_rank = victim_title + 4; + else if (victim_title < (2*HKRANKMAX-1)) + victim_rank = victim_title - (HKRANKMAX-1) + 4; + else victim_guid = 0; // Don't show HK: <rank> message, only log. - else if (victim_title < 15) - victim_rank = victim_title + 4; - else if (victim_title < 29) - victim_rank = victim_title - 14 + 4; - else - victim_guid = 0; // Don't show HK: <rank> message, only log. + + // now find rank difference + if (killer_title == 0 && victim_rank>4) + rank_diff = victim_rank - 4; + else if (killer_title < HKRANKMAX) + rank_diff = (victim_rank>(killer_title + 4))? (victim_rank - (killer_title + 4)) : 0; + else if (killer_title < (2*HKRANKMAX-1)) + rank_diff = (victim_rank>(killer_title - (HKRANKMAX-1) +4))? (victim_rank - (killer_title - (HKRANKMAX-1) + 4)) : 0; - honor_f = ceil(Trinity::Honor::hk_honor_at_level_f(k_level) * (v_level - k_grey) / (k_level - k_grey)); + honor_f = 1 + sWorld.getRate(RATE_PVP_RANK_EXTRA_HONOR)*(((float)rank_diff) / 10.0f); // count the number of playerkills in one day ApplyModUInt32Value(PLAYER_FIELD_KILLS, 1, true); @@ -6832,6 +6863,7 @@ bool Player::RewardHonor(Unit *uVictim, UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_EARN_HONORABLE_KILL); UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HK_CLASS, pVictim->getClass()); UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HK_RACE, pVictim->getRace()); + UpdateKnownTitles(); } else { @@ -6905,6 +6937,30 @@ bool Player::RewardHonor(Unit *uVictim, return true; } +void Player::UpdateKnownTitles() +{ + uint32 new_title = 0; + uint32 honor_kills = GetUInt32Value(PLAYER_FIELD_LIFETIME_HONORABLE_KILLS); + uint32 old_title = GetUInt32Value(PLAYER_CHOSEN_TITLE); + RemoveFlag64(PLAYER__FIELD_KNOWN_TITLES,PLAYER_TITLE_MASK_ALL_PVP); + if (honor_kills < 0) + return; + bool max_rank = ((honor_kills >= sWorld.pvp_ranks[HKRANKMAX-1]) ? true : false); + for (int i = HKRANK01; i != HKRANKMAX; ++i) + { + if (honor_kills < sWorld.pvp_ranks[i] || (max_rank)) + { + new_title = ((max_rank) ? (HKRANKMAX-1) : (i-1)); + if (new_title > 0) + new_title += ((GetTeam() == ALLIANCE) ? 0 : (HKRANKMAX-1)); + break; + } + } + SetFlag64(PLAYER__FIELD_KNOWN_TITLES,uint64(1) << new_title); + if (old_title > 0 && old_title < (2*HKRANKMAX-1) && new_title > old_title) + SetUInt32Value(PLAYER_CHOSEN_TITLE,new_title); +} + void Player::ModifyHonorPoints(int32 value) { if (value < 0) --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -387,6 +387,27 @@ enum PlayerFlags PLAYER_FLAGS_NO_XP_GAIN = 0x02000000 }; +#define PLAYER_TITLE_MASK_ALLIANCE_PVP \ + (PLAYER_TITLE_PRIVATE | PLAYER_TITLE_CORPORAL | + PLAYER_TITLE_SERGEANT_A | PLAYER_TITLE_MASTER_SERGEANT | + PLAYER_TITLE_SERGEANT_MAJOR | PLAYER_TITLE_KNIGHT | + PLAYER_TITLE_KNIGHT_LIEUTENANT | PLAYER_TITLE_KNIGHT_CAPTAIN | + PLAYER_TITLE_KNIGHT_CHAMPION | PLAYER_TITLE_LIEUTENANT_COMMANDER | + PLAYER_TITLE_COMMANDER | PLAYER_TITLE_MARSHAL | + PLAYER_TITLE_FIELD_MARSHAL | PLAYER_TITLE_GRAND_MARSHAL) + +#define PLAYER_TITLE_MASK_HORDE_PVP \ + (PLAYER_TITLE_SCOUT | PLAYER_TITLE_GRUNT | + PLAYER_TITLE_SERGEANT_H | PLAYER_TITLE_SENIOR_SERGEANT | + PLAYER_TITLE_FIRST_SERGEANT | PLAYER_TITLE_STONE_GUARD | + PLAYER_TITLE_BLOOD_GUARD | PLAYER_TITLE_LEGIONNAIRE | + PLAYER_TITLE_CENTURION | PLAYER_TITLE_CHAMPION | + PLAYER_TITLE_LIEUTENANT_GENERAL | PLAYER_TITLE_GENERAL | + PLAYER_TITLE_WARLORD | PLAYER_TITLE_HIGH_WARLORD) + +#define PLAYER_TITLE_MASK_ALL_PVP \ + (PLAYER_TITLE_MASK_ALLIANCE_PVP | PLAYER_TITLE_MASK_HORDE_PVP) + // used for PLAYER__FIELD_KNOWN_TITLES field (uint64), (1<<bit_index) without (-1) // can't use enum for uint64 values #define PLAYER_TITLE_DISABLED UI64LIT(0x0000000000000000) @@ -1975,6 +1996,7 @@ class Player : public Unit, public GridO if (value) AddKnownCurrency(ITEM_ARENA_POINTS_ID); // Arena Points } + void UpdateKnownTitles(); //End of PvP SystemКопируем всё это содержимое, сохраняем в файл с расширением .patch, например: Код:
rank.patch Код:
D:\work\source Код:
D:\work\source\rank.patch После того как мы перенесли наш патч, жмем ПКМ по папке с исходниками, а точнее: Код:
D:\work\source http://image.zone-game.info/images/4.jpg В появившемся окне, пишем: Код:
patch -p1 < название.patch, в нашем случае: Жмем Enter. Если после завершения вы видите: http://image.zone-game.info/images/6.jpg Значит всё в порядке, можно продолжать. Вы можете продолжить установку других патчей (если они у вас имеются), но у нас он один, так что мы продолжим. Закрываем Git. 3. Сборка компилятора. Создаем новую папку в нашей рабочей директории, например: Код:
D:\work\tc - в этой папке будет хранится готовый к компиляции проект. Where is the source code - папка с исходниками, у нас это: Код:
D:\work\source Код:
D:\work\tc http://image.zone-game.info/images/7.jpg После жмем Configure и выбираем, на какой платформе будем компилировать, в моем случае это Visual Studio 10, выбираем, после чего жмем Finish: http://image.zone-game.info/images/8.jpg Ждем завершение процесса, после чего вы увидите: http://image.zone-game.info/images/9.jpg Столбец - TOOLS, позволяет нам после компилирования получить экстракторы карт. Так что ставим галочку. Больше ничего не меняем. Снова жмем Configure и видим: http://image.zone-game.info/images/17.jpg После жмем: http://image.zone-game.info/images/18.jpg. Если все прошло успешно - то мы увидим: http://image.zone-game.info/images/19.jpg Можно закрывать CMake. 4. Компиляция ядра. Наш проект теперь хранится в: Код:
D:\work\tc Код:
TrinityCore.sln После открытия VS, запускаем Диспетчер конфигураций... и меняем Активную конфигурацию решения с Debug на Release, после жмем Закрыть: http://image.zone-game.info/images/11.jpg Если мы все сделали как надо, то можно смело жать F7 (Построить решение). http://image.zone-game.info/images/12.jpg Если после компиляции мы видим результат без ошибок, значит, компиляция прошла успешно. Все, наше ядро скомпилировано, но оно ещё не работоспособно. 5. Настройка ядра. Наше скомпилированное ядро хранится в папке: Код:
D:\work\tc\bin\Release Перенесем папку Release в корень нашей рабочей папки, то есть: Код:
D:\work\Release Код:
D:\work\server Код:
libeay32.dll, ssleay32.dll и libmysql.dll Найти libeay32.dll и ssleay32.dll мы может в папке с ранее установленным OpenSSL-Win32. Копируем libeay32.dll и ssleay32.dll с директории OpenSSL-Win32 в директорию с ядром: Код:
D:\work\server Код:
C:\Program Files\MySQL\MySQL Server\bin После чего переименовываем файлы: Код:
worldserver.conf.dist в worldserver.conf Для этого открываем уже переименованный authserver.conf и настраиваем строчку: Код:
LoginDatabaseInfo = "127.0.0.1;3306;trinity;trinity;auth" Код:
127.0.0.1 - адрес БД, выставлено по умолчанию. После этого, сохраняем и закрываем authserver.conf. Открываем worldserver.conf, тут хранятся все настройки сервера, мы пока в них вникать не будем, сделаем только необходимое: Код:
LoginDatabaseInfo = "127.0.0.1;3306;trinity;trinity;auth" Закрываем worldserver.conf. После нам необходимо указать путь к папке содержащей карты для сервера, как извлечь я объясню чуть позже, а пока создаем папку в корне нашей рабочей папки с названием data: Код:
D:\work\data - тут будут храниться карты. Код:
DataDir = "." Код:
DataDir = "D:\work\data\" Код:
vmap.enableLOS = 1 Код:
vmap.enableLOS = 0 Если вы помните, в программе CMake мы ставили галочку в столбце TOOLS, впоследствии чего мы получили экстракторы карт. Карты необходимы для работы сервера. Мне известно 3 вида карт: Код:
dbc & maps - самые необходимые для работы сервера. Для этого в папке с ядром: Код:
D:\work\server Код:
mapextractor.exe ВАЖНО "Версии ядра, экстрактора и игрового клиента должны быть ИДЕНТИЧНЫ" http://image.zone-game.info/images/13.jpg После того как экстрактор закончит работу, он создаст 2 папки: Код:
dbc и maps Код:
D:\work\data На этом начальная нстройка ядра окончена. 6. Работа с базами. Trinity Core имеет три базы: auth - база аккаунтов. characters - база персонажей. world - база мира, игрового :) Сейчас мы займемся созданием этих трех баз. 6.1. Создание баз. Открываем скаченный нами ранее Navicat, жмем на Conntection, заполняем: Код:
User name: логин MySQL сервера http://image.zone-game.info/images/15.jpg После в левой части у нас появится подключение, открываем его и видим: http://image.zone-game.info/images/16.jpg Щелкаем ПКМ на нашем подключении и выбираем: Код:
New database... http://image.zone-game.info/images/20.jpg Жмем ОК, теперь мы создали одну из трех баз. Также поступаем с остальными двумя. Меняется только название. После того как мы создали все три базы, мы видим: http://image.zone-game.info/images/21.jpg Все, базы созданы. Можно пока закрыть Navicat. Наши базы ещё пусты, нам необходимо их заполнить. 6.2. Заполнение баз. Заполнение баз auth и characters не вызовет у вас лишних вопросов, а вот с world можно подумать. Но все по порядку. Сами .sql файлы с базами лежат тут: Код:
D:\work\source\sql\base Заполнение базы auth. Заливать будем через консоль. Код:
1. Открываем консоль - Пуск > Все программы > MySQL > MySQL Server > MySQL Command Line Client. И жмем Enter. По завершению процесса, меняем базу с auth на characters и выполняем: Код:
\. D:\work\source\sql\base\characters_database.sql После этого закрываем консоль, т.к. стандартную базу world_database.sql мы заливать не будем, мы будем использовать базу YTDB. Официальный сайт - http://ytdb.ru/showthread.php?t=5227 Качать необходимо последнюю FULL базу с последующими обновлениями. То есть, пройдя по ссылке http://ytdb.ru/showthread.php?t=5227, последняя FULL база: Код:
YTDB_0.14.0_R570_TC_R10316_TDBAI_335.0.1_RuDB_38.4 Код:
D:\work После чего снова запускаем консоль MySQL, вводим пароль, указываем базу world и выполняем файлы в такой последовательности: Код:
YTDB_0.14.0_R570_TC_R10316_TDBAI_335.0.1_RuDB_R38.4 6.3. Настройки баз. К настройке баз, в частности относится изменение имени Игрового мира и смены адреса сервера (Realmlist). Для того чтобы изменить имя и Realmlist сервера, открываем Navicat, открываем созданное нами ранее подключение, открываем базу auth, таблицу realmlist и меняем на наше усмотрение: http://image.zone-game.info/images/26.jpg Подтверждаем наше действие кнопкой внизу окна: http://image.zone-game.info/images/27.jpg Можно закрывать Navicat. Работа с базами окончена. 7. Запуск сервера. Для запуска сервера необходимо запустить два файла: Код:
authserver.exe - логин сервер http://image.zone-game.info/images/29.jpg После, уже игровой, кстати, после успешного запуска игрового сервера, вы услышите BEEP :) http://image.zone-game.info/images/31.jpg После необходимо удалить папки Cache и WTF с корневого каталога игрового клиента World of Warcraft во избежание ошибок LUA. Далее меняем Realmlist игрового клиента на тот, что мы указали в базе. В нашем случае, файл - World of Warcraft WotLK\Data\ruRU\realmlist.wtf будет выглядеть так: Код:
set realmlist 127.0.0.1 Но мы не сможем тестировать ядро, т.к. у нас нет аккаунта, для того чтобы его создать без web-обвязки, необходимо переключится на окно world сервера и вписать: Код:
account create zgteam test Теперь мы готовы для тестирования ядра. Запускаем World of Warcraft, вводим логин и пароль от нашего игрового аккаунта, создаем персонажа, радуемся. http://image.zone-game.info/images/zgteamdld.jpg 8. F.A.Q. Как только наберу достаточное количество информации, напишу полный F.A.Q. Пишите отзывы, пожелания, недовольства и замечания. Здоровая критика всегда полезна. "Копирование разрешено только при наличии активной, индексируемой ссылки на эту страницу" © ZG-Team 2007 - 2011 |
Re: Компиляция ядра, создание сборки Trinity Core 3.3.5a под Win32
мануал удался:plus1:
|
Re: Компиляция ядра, создание сборки Trinity Core 3.3.5a под Win32
Вообщем то остался такой вопрос - с чем на х64 платформе компилировать и собирать?
|
Re: Компиляция ядра, создание сборки Trinity Core 3.3.5a под Win32
Для х64 - Visual Studio 2010 (или 2008) Professional Edition
|
Re: Компиляция ядра, создание сборки Trinity Core 3.3.5a под Win32
ясно, снкс..
ла2 с свна проще компилируется :) |
Re: Компиляция ядра, создание сборки Trinity Core 3.3.5a под Win32
Отличный мануал, так держать ! :plus1:
|
Re: Компиляция ядра, создание сборки Trinity Core 3.3.5a под Win32
Увожаемая команда ZG-team у меня проблема с 3:Сборка кампилятора я сделал всё как нада но показывает ошыбку! я проверял 10 раз и заново всё делал но тожэ самое help :(
|
Re: Компиляция ядра, создание сборки Trinity Core 3.3.5a под Win32
Ошибки разные бывают. Укажите какая именно.
|
Re: Компиляция ядра, создание сборки Trinity Core 3.3.5a под Win32
Прям универсальный план для любого сервера! Одно добавлю - как проще всего определить какие логин и пароль вашей базы когда не указан выше...
Есть такие файлы как authserver.conf и worldserver.conf (имена значения не сильно имеют, главное чтобы расширение было .conf это данные для реалма и сервера там находятся)! Там всегда есть такие строки как realmd.conf(сам файл а в нём есть) - LoginDatabaseInfo = "127.0.0.1;3306;root;mangos;realmd" (сдесь уже прописано root - логин mangos - пароль) mangos.conf(сам файл а в нём есть) LoginDatabaseInfo = "127.0.0.1;3306;root;mangos;realmd"(аналогично к вышесказанному определяется) WorldDatabaseInfo = "127.0.0.1;3306;root;mangos;world" CharacterDatabaseInfo = "127.0.0.1;3306;root;mangos;characters" Просто чтобы не париться лишний раз и не ломать голову себе! Бывает что по 3-4 серва есть установленных то с Тринити то с Мангосом вперемешку, так проще определять логин и пароль базы! Это уже собственный опыт! Добавлено через 4 минуты Есть такой вопрос.... Высше в самой инструкции по установке есть упоминания о VMaps и MMaps! О VMaps уже знаю много чего, видел для чего нужны они, а, если не тяжело, может ктото меня просветлить по поводу MMaps? Был бы рад ещё чтото новенького узнать! |
Re: Компиляция ядра, создание сборки Trinity Core 3.3.5a под Win32
3 я ужэ решыл я остоновился на mapextractor.exe как ево создовать а то мне не понятно :( я проста noob в этом деле пока :)оч нуждаюсь в вашэи помошчи ;)
|
Текущее время: 13:21. Часовой пояс GMT +3. |
Powered by vBulletin® Version 3.8.6
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd. Перевод: zCarot