Jump to content

Search the Community

Showing results for tags 'Клиент'.



More search options

  • Search By Tags

    Type tags separated by commas.
  • Search By Author

Content Type


Forums

  • Russian section
    • Новости и объявления
    • Пиратия: Документация
    • Пиратия: Релизы
    • Пиратия: Разработка
    • Пиратия: Web
    • Пиратия: Помощь
    • Совместные проекты / набор команды
    • Доска объявлений
    • Программирование
    • Оффтопик
    • Корзина
  • English Section
    • News & Announcements
    • Guides
    • Releases
    • Development
    • Web
    • Questions & Help
    • Shared Projects / Team search
    • Paid services & Requests
    • Programming
    • Offtopic
    • Recycle bin
  • Servers
    • Russian servers
    • English servers

Find results in...

Find results that contain...


Date Created

  • Start

    End


Last Updated

  • Start

    End


Filter by number of...

Joined

  • Start

    End


Group


Found 35 results

  1. [Твик] Скриншоты в одной папке Всем привет! В этой теме я хочу рассказать о небольшом твике клиента, который позволит сохранять скриншоты игрового процесса непосредственно в папке "screenshot". Изначально клиент создает скриншоты в подпапках "screenshot\1", "screenshot\2", "screenshot\3" ... "screenshot\N", что может быть не очень удобно для поиска и просмотра скриншотов. Собственно, с этой проблемой к сообществу и обратился пользователь @dragontechi: Чтобы устранить текущее неудобство хранения скриншотов, необходимо выполнить следующие изменения клиента: 1) Откройте DLL-библиотеку движка игры "MindPower3D_D8R.dll" (находится в папке "system") в любом HEX-редакторе, например, в HxD; 2) Найдите строку: screenshot\%d\ и замените её на следующую: screenshot\%d_ 3) Далее найдите последовательность байт: E8 83 2C F9 FF и замените их на: 90 90 90 90 90 4) Теперь найдите байты: C7 85 74 FF FF FF 00 00 00 00 B8 01 00 00 00 85 C0 74 53 8B 85 74 FF FF FF 50 и замените их: 6A 00 E8 84 E9 16 00 83 C4 04 50 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 5) Сохраните проделанные изменения в файле "MindPower3D_D8R.dll". В итоге получится следующий результат: Все скриншоты теперь хранятся в одной папке "screenshot". Дополнительно, в названии каждого скриншота записывается метка времени, когда он был сделан (в контексте времени системы, на которой был запущен клиент в момент создания скриншота). Благодарю за внимание!
  2. Установка сервера Пиратии (Tales of Pirates, Pirate King Online) Всем привет! В данном гайде я расскажу как установить и настроить сервер Пиратии шаг за шагом на примере серверных файлов версии 1.3х. Под версией 1.3x подразумеваются самые распространенные версии игры, которые сегодня используются большинством проектов: 1.35, 1.36, 1.38 и 1.39. Это деление условно и все версии 1.3x совместимы между собой. Например, клиент версии 1.36 может работать с сервером версии 1.39. Также существуют серверные файлы версии 2.x и скомпилированные из исходных кодов, например, файлы Corsairs Online. Их так же можно установить и настроить следуя настоящей инструкции, но процесс установки может в определенной мере отличаться. Гайд предназначен для новичков в нашем Сообществе администраторов и разработчиков серверов Пиратии и содержит подробную инструкцию с изображениями, которая позволит установить сервер с нуля. По прочтении статьи читатель сможет запустить свой игровой мир и войти в него используя игровой клиент. Содержание гайда: 1. Вам понадобится; 2. Архитектура сервера Пиратии; 3. Установка Microsoft SQL Server и SQL Server Management Studio; 4. Установка и настройка серверных файлов; 5. Запуск сервера; 6. Проверка соединения с игровым сервером; 7. Остановка игрового сервера; 8. Подключение игрового клиента к серверу; 9. Распространенные ошибки и их исправление. Приступим к установке и настройке нового игрового мира. Первым шагом определим инструменты, которые понадобятся для успешного выполнения поставленной задачи. 1. Вам понадобится 0. Теоретическая подготовка. Основы работы с операционной системой семейства Windows, базовые знания архитектуры "клиент-сервер", понимание терминов "База данных (БД)" и "Система управления базами данных (СУБД)". Поскольку те или иные программы, а также сообщения об ошибках могут быть на английском языке, то понадобится знание английского языка начального уровня. 1. Компьютер под управлением операционной системы семейства Windows (серверные редакции Server и пользовательские XP/Vista/7/8/10). Исполняемые файлы сервера скомпилированы под архитектуру x86 (Win32), поэтому система должна поддерживать 32-разрядный режим работы. К аппаратной части предъявляются следующие требования: многоядерный процессор с частотой от 2.0 ГГц; от 4 Гб оперативной памяти; 2 Гб свободного места на диске для серверных файлов, баз данных и файлов журнала ("логов"); сетевое подключение со скоростью от 10 Мбит/с на 1000 клиентов. Таким образом, исходя из современных реалий, можно сделать вывод, что игровой сервер предъявляет невысокие требования к железу, поэтому вышеприведенные характеристики носят скорее рекомендательный и условный характер. Например, Вы можете запустить игровой сервер и на более слабом компьютере, но это, в свою очередь, может привести к замедлению его работы, а значит и к задержкам у игроков, что отразится на комфорте процесса игры. Если же Вы планируете запустить сервер только для себя (одиночная игра, проведение различных тестов, написание скриптов), то Вам не нужно заботиться о производительности сервера, а требования к железу будут менее строгими. 2. Система управления базами данных (СУБД) Microsoft SQL Server. Именно такую СУБД выбрали разработчики игрового сервера Пиратии для хранения состояния игрового процесса: учетных записей пользователей, персонажей, гильдий, кораблей и других объектов. Существует много версий Microsoft SQL Server. В гайде я буду использовать бесплатную версию Microsoft SQL Server 2017 Express, которую можно скачать с официального сайта Microsoft. Несмотря на ограничения Express редакции, её возможностей вполне хватит для обеспечения работы игрового сервера. Для управления SQL-сервером Вам понадобится SQL Server Management Studio, который также можно найти на сайте Microsoft. 3. Серверные файлы ("сборка"). Это приложения, файлы и скрипты, которые служат для создания и поддержания игрового процесса. В минимальной конфигурации должны включать в себя серверные приложения AccountServer.exe, GroupServer.exe, GameServer.exe и GateServer.exe. Функции и задачи данных приложений будут рассмотрены далее. Найти сборку сервера можно в разделе "Сборки серверов" на нашем форуме или в Архиве полезных файлов для сервера и клиента. В качестве примера я буду использовать серверные файлы Pirate King Online 1.38. 4. Базы данных. В соответствии с пунктом (2) определяют структуру хранения игровых объектов на диске и используются игровым сервером для хранения информации о состоянии игрового мира. Представлены файлами GameDB_Data.mdf, GameDB_log.ldf, AccountServer_Data.mdf и AccountServer_log.ldf. Как правило, поставляются вместе с серверными файлами. Если в скачанных Вами серверных файлах нет баз данных, то их можно найти в другой сборке, либо в Архиве полезных файлов для сервера и клиента. 5. Генератор паролей для .cfg. Кроме прочих настроек, в конфигурационных файлах сервера (.cfg) указываются данные для подключения к SQL-серверу, в том числе и пароли пользователей баз данных GameDB и AccountServer. В целях безопасности пароли в конфигурационных файлах должны быть зашифрованы специальным алгоритмом, для чего служит данная программа. 6. Текстовый редактор для редактирования конфигурационных файлов сервера. Подойдет стандартный блокнот (notepad.exe), но я рекомендую программу Notepad++, которая на порядок удобнее обычного блокнота. 7. Игровой клиент для подключения к установленному игровому серверу и его тестирования. Вы можете подобрать игровой клиент к выбранной сборке сервера в теме "Официальные клиенты" на нашем форуме. 8. IP Changer. Перед подключением к серверу игровому клиенту необходимо задать сетевой адрес по которому подключаться. Данная программа предназначена для настройки адреса игрового сервера в клиенте. 9. Программа для создания аккаунтов. Для того, чтобы войти в игровой мир, Вам нужна учетная запись игрока или администратора, которую можно зарегистрировать с помощью приведенной программы. После того, как мы сформулировали основные требования и определили необходимые инструменты для установки сервера Пиратии и подключения к нему клиента, проведем небольшой экскурс по архитектуре игрового сервера, чтобы получить понимание процесса его настройки и запуска в будущем. 2. Архитектура сервера Пиратии Архитектура сервера приведена на рисунке ниже. Она позволяет понять как в общем случае устроены серверные файлы и каковы взаимосвязи между серверным программным обеспечением: что в него входит, что является сервером и что является клиентом по отношению друг к другу. Как видно из схемы в состав системы входят AccountServer, GameServer, GroupServer, GateServer, Microsoft SQL Server с базами данных AccountServer и GameDB, а также игровой клиент (Client). Всё клиент-серверное взаимодействие между приложениями осуществляется с помощью сетевых пакетов по протоколу TCP. Изучим для чего нужен каждый элемент системы. 1. Игровой клиент (Client) - приложение с которым взаимодействует конечный пользователь (игрок). Визуализирует состояние игрового мира вокруг персонажа игрока, полученное от сервера через сеть Интернет. Под визуализацией понимается отрисовка игровой карты с объектами на ней (например, суша и море, деревья, здания, дороги), персонажей других игроков, монстров, неигровых персонажей (NPC) и так далее - всего того, что на своем мониторе видит игрок в процессе игры. Кроме визуализации клиент посредством графического интерфейса пользователя (GUI) предоставляет последнему возможность влиять на состояние игрового мира и процесс игры с помощью клавиатуры и мыши, отправляя на сервер различные действия, например, создание персонажа, перемещение персонажа в игровом мире, атака монстров, взаимодействие с NPC, отправка сообщений в чат и другие действия, которые разрешены на сервере правилами игры. Для пользователя клиент является игрой в обычном понимании. В рассматриваемой системе игровых клиентов может быть от 1 до нескольких тысяч. Подключается через 1973 порт к GateServer. 2. GateServer - принимает входящие соединения через 1973 порт от игровых клиентов и выступает в роли шлюза, через который игровой клиент взаимодействует с GroupServer, AccountServer и GameServer. Является сервером на 1971 порту по отношению к GameServer и клиентом на 1975 порту по отношению к GroupServer. Для распределения нагрузки в системе может быть несколько GateServer. Например, можно настроить сервер таким образом, что игроки из России подключаются к GateServer, который расположен в Москве, а игроки из Европы подключается к GateServer, который запущен на хостинге в дата-центре, расположенном в Германии, что позволит снизить задержки (пинг) при передаче сетевых пакетов от клиента на сервер и обратно. В целях безопасности игрового процесса GateServer шифрует весь сетевой трафик, который передается между сервером и клиентами. 3. GroupServer - отвечает за создание и удаление персонажей с аккаунта пользователя, систему друзей и отрядов, общение между игроками в чатах (мировой, торговый, отряд, гильдия, ЛС) и диалогах. GroupServer также участвует в процессе аутентификации игроков на сервере, передавая пакеты аутентификации, полученные от GateServer, далее в AccountServer. Является сервером на 1975 порту по отношению GateServer и клиентом по отношению к AccountServer на 1978 порту. Кроме того, подключается в роли клиента через 1433 порт к Microsoft SQL Server для работы с базой данных GameDB. Как и в случае с GateServer, в системе может быть несколько GroupServer для распределения нагрузки, но, как правило, в реальных проектах используется один экземпляр GroupServer. 4. AccountServer - нужен для аутентификации игроков на сервере путем сравнения полученных от пользователя логина и пароля с соответствующими логином и паролем в базе данных. Если игрок ввел верные логин и пароль, то он допускается к игре на сервере, в противном случае получает сообщение об ошибке авторизации и отключается от сервера. Является сервером по отношению к GroupServer на порту 1978. Работает с базой данных AccountServer, поэтому является клиентом Microsoft SQL Server на порту 1433. Как и в случае с GateServer, в системе может быть несколько AccountServer для распределения нагрузки, но обычно в реальных проектах используется один экземпляр AccountServer. 5. GameServer - основной игровой сервер, где осуществляется вся логика игры. Обеспечивает игровой процесс и синхронизацию состояния игрового мира с игровыми клиентами: является клиентом на 1971 порту по отношению к GateServer, через который принимает действия от игровых клиентов, проверяет их корректность, и, в случае соблюдения установленных правил игры, вносит изменения в состояние игрового мира, после чего оповещает об этом все остальные игровые клиенты. Параллельно с обработкой действий игровых клиентов, с определенной частотой (обычно 20 Гц) обновляет игровой мир, например, для создания погодных явлений или управления монстрами с помощью искусственного интеллекта (AI). Для сохранения состояния игрового мира использует базу данных GameDB и является клиентом Microsoft SQL Server на порту 1433. GameServer является самым высоконагруженным элементом в системе и потребляет больше всего вычислительных ресурсов и памяти, поэтому в реальных проектах нагрузка распределяется между от 3 до 5 GameServer. В игре существует три основные локации: Аскарон, Магический Океан и Великий Синий Океан размером 4096 x 4096 условных единиц - это самые большие локации в игре. Помимо того факта, что они будут занимать много памяти в ОЗУ, в этих локациях одновременно могут быть тысячи игроков, монстров и NPC, следовательно, целесообразно распределить нагрузку между несколькими экземплярами GameServer и запускать основные локации по одной вместе с частью второстепенных на разных GameServer. 6. Microsoft SQL Server и базы данных AccountServer, GameDB - Microsoft SQL Server является механизмом, с помощью которого AccountServer работает с одноименной базой данных AccountServer, а GameServer и GroupServer работают с базой данных GameDB, используя язык SQL. Является сервером на порту 1433 по отношению к AccountServer, GameServer и GroupServer. В базе данных AccountServer хранятся игровые аккаунты и различная служебная информация, например, логи. В базе данных GameDB хранятся персонажи, предметы, гильдии, корабли, списки друзей и менторов, дублируется список аккаунтов для их связи с персонажами, кроме того, каждому аккаунту здесь присваивается уровень GM и секретный код, так же присутствует и служебная информация. Следует отметить, что рассмотренная архитектура является самой распространенной и применяется в большинстве проектов, но Вы можете перестраивать её под свои нужды: 1. Вы можете изменить стандартные порты 1433, 1971, 1973, 1975, 1978 на любые другие не зарезервированные порты; 2. Вы можете переименовывать базы данных AccountServer и GameDB (потребуется редактирование некоторых исполняемых файлов сервера); 3. Вы можете запускать несколько экземпляров Microsoft SQL Server, GateServer, GroupServer, AccountServer, GameServer и настраивать взаимосвязи между ними в целях распределения нагрузки и повышения производительности игрового процесса; 4. В систему могут быть добавлены новые элементы, например, сервер встроенного в клиент магазина игровых предметов (IGS), сервер для фильтрации исходящих от клиентов пакетов (FilterServer), сервер "оффлайн" ларьков (StallServer), который позволяет игрокам торговать в ларьках не находясь в игре. Теперь, когда Вы получили представление об архитектуре и основных элементах сервера Пиратии, приступим к его установке и настройке. Начнем с установки Microsoft SQL Server. 3. Установка Microsoft SQL Server и SQL Server Management Studio 3.1 Установка Microsoft SQL Server Перейдите на страницу загрузки Microsoft SQL Server 2017 Express и нажмите кнопку "Скачать". На Ваш компьютер будет загружен дистрибутив SQLServer2017-SSEI-Expr.exe. Запустите дистрибутив SQLServer2017-SSEI-Expr.exe от имени администратора и выберите тип установки "Пользовательский". Выберите директорию на диске, куда будет загружен пакет установки, необходимый для установки экземпляра Microsoft SQL Server, и нажмите кнопку "Установить". Начнется процесс загрузки и распаковки пакета установки. Дождитесь его окончания. После загрузки и распаковки пакета установки должно открыться окно "Центр установки SQL Server". Если оно по какой-либо причине не открылось, перейдите в директорию, которую Вы указали в процессе загрузки пакета установки (расположение носителя), и запустите центр установки SQL Server вручную (файл SETUP.exe). В окне центра установки SQL Server на вкладке "Установка" выберите пункт меню "Новая установка изолированного экземпляра SQL Server или добавление компонентов к существующей установке". Начнется процесс установки экземпляра SQL Server 2017. Примите условия лицензионного соглашения и нажмите кнопку "Далее". Убедитесь, что в системе соблюдены все условия для успешной установки SQL Server на вкладке "Глобальные правила", после чего нажмите кнопку "Далее". При возникновении проблем примите меры для их устранения и продолжите установку. На странице "Центр обновления Майкрософт" по Вашему усмотрению установите флажок "Использовать Центр обновления Майкрософт для проверки наличия обновлений" и нажмите кнопку "Далее". Программа установки проверит наличие обновлений и при необходимости их установит. Далее программа установки еще раз проведет диагностику системы на наличие потенциальных проблем, которые могут возникнуть в процессе установки Microsoft SQL Server 2017. Убедитесь, что потенциальных проблем не обнаружено. Правило "Брандмауэр Windows" может быть в состоянии "Предупреждение", если включен Брандмауэр Windows. Для продолжения установки это не критично, но могут возникнуть проблемы в будущем, если Вы захотите обеспечить удаленный доступ к экземпляру SQL Server. Чтобы их избежать, Вам нужно будет открыть порт для подключения к SQL Server (по умолчанию 1433) в фаерволе Windows. Нажмите кнопку "Далее". На странице "Выбор компонентов" отметьте только компонент "Службы ядра СУБД" и укажите корневой каталог экземпляра. Нажмите кнопку "Далее". Затем Вам будет предложено указать имя и идентификатор экземпляра SQL Server. Выберите флажок "Экземпляр по умолчанию", а в поле "Идентификатор экземпляра" введите название экземпляра SQL Server по Вашему усмотрению. Нажмите кнопку "Далее". Страницу "Конфигурация сервера" оставьте без изменений и нажмите кнопку "Далее". При настройке ядра СУБД выберите флажок "Режим проверки подлинности Windows" и убедитесь, что в список администраторов SQL Server добавлен текущий пользователь. На остальных вкладках страницы "Настройка ядра СУБД" изменения не требуются. Нажмите кнопку "Далее". Далее начнется процесс копирования файлов, требующихся для работы экземпляра SQL Server, и их конфигурирование. Дождитесь окончания данного процесса. В результате экземпляр SQL Server должен быть успешно установлен. Закройте Программу установки SQL Server 2017. 3.2 Установка SQL Server Management Studio Перейдите на страницу загрузки Microsoft SQL Server Management Studio и нажмите ссылку "Скачайте SQL Server Management Studio (SSMS)". На Ваш компьютер будет загружен дистрибутив SSMS-Setup-RUS.exe. Запустите дистрибутив SSMS-Setup-RUS.exe от имени администратора. Появится окно программы установки среды Microsoft SQL Server Management Studio. Выберите директорию, в которую будет установлена среда, и нажмите кнопку "Установить". Начнется процесс загрузки и установки требуемых пакетов и компонентов, а также непосредственная установка SQL Server Management Studio. Дождитесь окончания процесса. После завершения процесса необходимо перезагрузить компьютер. 3.3 Проверка работоспособности Microsoft SQL Server и его настройка После перезагрузки компьютера установленный экземпляр SQL Server должен автоматически начать работу. Запустите программу Microsoft SQL Server Management Studio 18 от имени администратора и подключитесь ко вновь установленному экземпляру используя проверку подлинности Windows. Соединение должно быть успешно установлено, и в окне "Обозреватель объектов" появится текущий экземпляр SQL Server. Запомните название текущего экземпляра (1), оно понадобится далее при настройке конфигурационных файлов сервера (.cfg). Название экземпляра SQL Server: DESKTOP-XXXXXXX Кликните по серверу правой кнопкой мыши и в контекстном меню выберите пункт "Свойства". В появившемся окне "Свойства сервера" перейдите на страницу "Безопасность" и в группе "Серверная проверка подлинности" выберите "Проверка подлинности SQL Server и Windows". Нажмите кнопку "ОК". Для того, чтобы произведенные изменения вступили в силу, необходимо перезапустить SQL Server. Для этого снова кликните по серверу правой кнопкой мыши в окне "Обозреватель объектов" и в контекстном меню выберите пункт "Перезапустить". На вопрос о перезапуске службы SQL Server ответьте "Да". Экземпляр сервера будет перезапущен. Установка и настройка Microsoft SQL Server завершена. Далее установим и настроим серверные файлы игры. 4. Установка и настройка серверных файлов Выбор серверных файлов Скачайте интересующие Вас серверные файлы на Ваш компьютер и распакуйте их в любое удобное для Вас место на диске. Прикрепление баз данных к Microsoft SQL Server Вместе с серверными файлами должны поставляться базы данных AccountServer и GameDB. Если в загруженной Вами сборке сервера базы данных не обнаружены, то найдите их в другой сборке или в Архиве полезных файлов для сервера и клиента. Эти базы данных необходимо прикрепить к ранее установленному экземпляру SQL Server перед настройкой и запуском исполняемых файлов сервера Пиратии. Для этого запустите программу Microsoft SQL Server Management Studio 18 от имени администратора и подключитесь к Вашему экземпляру SQL Server используя проверку подлинности Windows. В обозревателе объектов кликните правкой кнопкой по папке "Базы данных" и в контекстном меню выберите задачу "Присоединить...". Появится окно "Присоединение баз данных", в котором Вам необходимо по очереди указать пути до баз данных AccountServer и GameDB (1), убедиться, что очередная база данных добавлена в список для присоединения (2) и нажать кнопку "ОК" (3). В папке "Базы данных" текущего экземпляра SQL Server в окне "Обозреватель объектов" должны появиться AccountServer и GameDB. Создание пользователей для баз данных Теперь необходимо создать пользователей баз данных AccountServer и GameDB для приложений AccountServer, GroupServer и GameServer. С помощью этих пользователей GroupServer и GameServer будут подключаться к Microsoft SQL Server и работать с базой данных GameDB, а AccountServer будет работать с одноименной базой данных AccountServer. В рамках гайда создадим двух пользователей: одного для базы данных GameDB, второго для базы данных AccountServer. Из-за особенностей шифрования паролей пользователей баз данных в конфигурационных файлах сервера Пиратии, пароль каждого пользователя должен быть длиной ровно 9 символов. Придумаем данные пользователей: GameDB База данных: GameDB Логин: PKODev_Game Пароль: pkodevnet AccountServer База данных: AccountServer Логин: PKODev_Account Пароль: netpkodev Далее по очереди добавим этих пользователей в экземпляр SQL Server и делегируем им доступ к соответствующим базам данных. Кликните правой кнопкой мыши по папке "Безопасность" текущего экземпляра SQL Server в окне "Обозреватель объектов" и в контекстном меню выберите команду "Создать - Вход..." (либо папка "Имена для входа" и команда "Создать имя для входа..."). В окне "Создание имени для входа" на странице "Общие" введите имя пользователя (1), выберите переключатель "Проверка подлинности SQL Server" (2), введите пароль и подтверждение пароля (3), снимите флажок "Требовать использование политики паролей" (4). Выберите базу данных по умолчанию: для пользователя PKODev_Game база данных GameDB и для пользователя PKODev_Account база данных AccountServer (5). Далее перейдите на страницу "Сопоставление пользователей" (6). На странице "Сопоставление пользователей" отметьте флажком базу данных GameDB для пользователя PKODev_Game или базу данных AccountServer для пользователя PKODev_Account (1). В списке "Членство в роли базы данных для: GameDB (AccountServer)" снимите флажок с db_owner (2) и установите флажки db_datawriter, db_datareader, db_ddladmin (3). На этом создание очередного пользователя завершено. Нажмите кнопку "ОК" (4). В подпапке "Имена для входа" папки "Безопасность" текущего экземпляра SQL Server в окне обозревателя объектов должны появиться два новых пользователя: PKODev_Game и PKODev_Account. В результате мы прикрепили базы данных GameDB и AccountServer к экземпляру SQL Server и создали для них пользователей PKODev_Game и PKODev_Account соответственно. Сейчас сервер Пиратии может работать с базами данных, поэтому приступаем к его настройке. Шифрование паролей пользователей баз данных для конфигурационных файлов (.cfg) сервера Как было отмечено выше, пароли пользователей баз данных указываются в конфигурационных файлах сервера (.cfg) в зашифрованном виде, соответственно их необходимо зашифровать. Скачайте Генератор паролей для .cfg, распакуйте загруженный архив и откройте файл passgen.ini в любом текстовом редакторе. Присвойте параметру "pass" пароль для пользователя базы данных GameDB и сохраните файл: pass=pkodevnet Запустите приложение passgen.exe. В консольном окне Вы получите зашифрованный пароль. Скопируйте зашифрованный пароль и сохраните его в текстовом файле. Он понадобится далее в процессе настройки конфигурационных файлов игрового сервера. Повторите операцию шифрования пароля для пользователя базы данных AccountServer: pass=netpkodev В итоге мы получили данные серверного программного обеспечения Пиратии для подключения к Microsoft SQL Server: Название экземпляра SQL Server: DESKTOP-XXXXXXX База данных: GameDB Пользователь: PKODev_Game Зашифрованный пароль для .cfg: SUOh8nJKCe125gImJdapNA== Название экземпляра SQL Server: DESKTOP-XXXXXXX База данных: AccountServer Пользователь: PKODev_Account Зашифрованный пароль для .cfg: 7y2CBBN+se+T5+9Lzp7IIw== Настройка AccountServer Начнем настройку игрового сервера с настройки AccountServer. Откройте конфигурационный файл AccountServer.cfg в любом текстовом редакторе. Найдите секцию db, которая отвечает за подключение к Microsoft SQL Server, и заполните соответствующие параметры: dbserver - адрес или название экземпляра Micrososft SQL Server; db - название базы данных для хранения информации об игровых аккаунтах. По умолчанию AccountServer; userid - Логин пользователя базы данных AccountServer; passwd - Зашифрованный пароль пользователя базы данных AccountServer. [db] dbserver = DESKTOP-XXXXXXX db = AccountServer userid = PKODev_Account passwd = 7y2CBBN+se+T5+9Lzp7IIw== В секции net укажите адрес и порт, на которых AccountServer будет принимать входящие соединения от GroupServer: listen_ip - IP-адрес AccountServer по отношению к GroupServer. Если AccountServer и GroupServer будут запускаться на одном и том же компьютере, то введите IP-адрес 127.0.0.1; listen_port - Сетевой TCP порт, на котором AccountServer будет принимать входящие соединения от GroupServer. По умолчанию 1978. [net] listen_port = 1978 listen_ip = 127.0.0.1 Сохраните файл AccountServer.cfg. Более изменений данного файла не требуется. Настройка GroupServer Откройте конфигурационный файл GroupServer.cfg в любом текстовом редакторе. По аналогии с AccountServer.cfg в данном конфигурационном файле необходимо настроить подключение к серверу баз данных. Для этого используется секция Database со следующими параметрами: IP - адрес или название экземпляра Micrososft SQL Server; DB - название базы данных для хранения информации о состоянии игрового мира. По умолчанию GameDB; Login - Логин пользователя базы данных GameDB; Password - Зашифрованный пароль пользователя базы данных GameDB. [Database] IP = DESKTOP-XXXXXXX DB = GameDB Login = PKODev_Game Password = SUOh8nJKCe125gImJdapNA== Настройте параметры подключения GroupServer к AccountServer в секции AccountServer: IP - IP-адрес AccountServer; Port - Сетевой TCP порт AccountServer. [AccountServer] IP = 127.0.0.1 Port = 1978 Как Вы помните, GroupServer является сервером по отношению к GateServer. В секции Main указываются адрес и порт, через которые GroupServer будет принимать входящие соединения от GateServer: Listen_IP - IP-адрес GroupServer по отношению к GateServer. Если GroupServer и GateServer будут запускаться на одном и том же компьютере, то введите IP-адрес 127.0.0.1; Listen_Port - Сетевой TCP порт, на котором GroupServer будет принимать входящие соединения от GateServer . По умолчанию 1975. [Main] Listen_Port = 1975 Listen_IP = 127.0.0.1 Сохраните файл GroupServer.cfg. Настройка GroupServer завершена. Настройка GateServer Откройте конфигурационный файл GateServer.cfg в любом текстовом редакторе. Настройте параметры подключения GateServer к GroupServer в секции GroupServer: IP - IP-адрес GroupServer; Port - Сетевой TCP порт GroupServer. [GroupServer] IP = 127.0.0.1 Port = 1975 В секции ToClient необходимо указать параметры подключения игровых клиентов к GateServer: IP - IP-адрес GateServer и соответственно адрес Вашего сервера, через который будут подключаться игровые клиенты (игроки). Введите адрес 0.0.0.0, который обозначает все IP-адреса данного компьютера. Например, к серверу можно будет подключиться одновременно через локальный адрес 127.0.0.1, локальную сеть 192.168.0.99 и внешний IP-адрес 54.36.6.113 через сеть Интернет (адреса выдуманы для примера); Port - Сетевой TCP порт, на котором GateServer будет принимать входящие соединения от игровых клиентов, то есть внешний порт Вашего сервера. По умолчанию 1973. Данный порт должен быть открыт в Брандмауэре Windows (и иных программах-межсетевых экранах), а также на стороне Вашего Интернет-провайдера или поставщика услуг хостинга. Если Ваш компьютер подключен к Интернету через маршрутизатор, то в маршрутизаторе необходимо пробросить внешний порт на Ваш компьютер для доступа к игровому серверу из сети Интернет. CommEncrypt - параметр, который отвечает за шифрование входящего и исходящего трафика, то есть сетевых пакетов данных, которые передаются от GateServer к игровым клиентам и от игровых клиентов к GateServer. При значении 1 шифрование включено, при значении 0 - выключено. Рекомендуется включить шифрование для повышения уровня защищенности сервера по отношению к различным вредоносным программам (боты, программы для редактирования и флуда пакетами типа WPE Pro/RPE, твики позволяющие отдельным игрокам получать преимущество над другими и так далее). [ToClient] IP = 0.0.0.0 Port = 1973 CommEncrypt = 1 Настройте адрес и порт, через которые GateServer будет принимать входящие соединения от GameServer в секции ToGameServer: IP - IP-адрес GateServer по отношению к GameServer. Если GateServer и GameServerбудут запускаться на одном и том же компьютере, то введите IP-адрес 127.0.0.1; Port - Сетевой TCP порт, на котором GateServer будет принимать входящие соединения от GameServer. По умолчанию 1971. [ToGameServer] IP = 127.0.0.1 Port = 1971 В секции Main в параметре Version укажите версию клиента, которая допускается для подключения к серверу. На стороне клиента данная версия "зашита" в Game.exe и передается двумя байтами в пакете аутентификации. Самое распространенное значение версии клиента 136: [Main] Version = 136 При несовпадении версии сервера и клиента пользователь получит сообщение об ошибке "Неверная версия игры": Сохраните файл GateServer.cfg. Настройка GateServer завершена. Настройка GameServer Первоначальная настройка GameServer сводится к указанию его уникального имени (идентификатора), параметров подключения к GateServer, параметров подключения к Micrososft SQL Server и списка локаций, которые будут запущены на текущем экземпляре GameServer. В начале данного гайда мы сделали вывод, что GameServer должно быть в системе от 3 до 5 экземпляров для распределения между ними нагрузки, поэтому необходимо создать несколько конфигурационных файлов (.cfg) - для каждого экземпляра GameServer отдельный .cfg-файл. В качестве примера создадим 3 конфигурационных файла: GameServer.cfg, GameServer2.cfg и GameServer3.cfg. Чтобы получить новые .cfg-файлы, скопируйте GameServer.cfg два раза и переименуйте копии в GameServer2.cfg и GameServer3.cfg. По очереди настройте каждый конфигурационный файл GameServer используя текстовый редактор. Так как к GateServer подключается более одного GameServer, GateServer необходимо однозначно различать подключенные GameServer для маршрутизации сетевых пакетов данных от игровых клиентов. Для этого у каждого GameServer есть свой уникальный идентификатор, который указывается в секции ID в виде произвольной текстовой строки. Для GameServer.cfg задайте идентификатор, который Вы можете выбрать по своему усмотрению: [ID] name = GameServer00 Для GameServer2.cfg: [ID] name = GameServer01 Для GameServer3.cfg: [ID] name = GameServer02 Далее настройте параметры подключения к GateServer в секции Gate, которые указываются с помощью ключа gate в виде строки "<IP-адрес>, <порт>", где <IP-адрес> это адрес GateServer, а <порт> соответственно порт, на котором GateServer принимает входящие соединения от GameServer: [Gate] gate = 127.0.0.1, 1971 Затем необходимо указать параметры подключения к Microsoft SQL Server в секции DB с помощью следующих параметров: db_ip - адрес или название экземпляра Micrososft SQL Server; db_usr - Логин пользователя базы данных GameDB; db_pass - Зашифрованный пароль пользователя базы данных GameDB. [DB] db_ip = DESKTOP-XXXXXXX db_usr = PKODev_Game db_pass = SUOh8nJKCe125gImJdapNA== Осталось указать список локаций в секции Map, которые будут запущены на текущем экземпляре GameServer. В отличие от игрового наименования локаций, в серверных файлах локации носят кодовые имена. К примеру, Аскарон называется garner, Магический Океан это magicsea, а Великий Синий Океан - darkblue. Очередная локация включается ключом map c новой строки: [Map] map = <локация 1> map = <локация 2> . . . map = <локация N> Например, следующая секция Map запустит карты Аскарон, Арену для командных сражений, Мир демонов и Мир демонов 2: [Map] map = garner map = teampk map = puzzleworld map = puzzleworld2 Полный список наименований игровых локаций, который связывает их с кодовыми именами, приведен ниже: garner - Аскарон magicsea - Магический Океан darkblue - Великий Синий Океан lonetower - Одинокая башня eastgoaf - Серебрянные шахты, заброшенные шахты, логово черного дракона, логово черного дракона 2 secretgarden - Сад Эдель darkswamp - Темная топь abandonedcity - Забытый Город abandonedcity2 - Забытый Город 2 abandonedcity3 - Забытый Город 3 puzzleworld - Мир Демонов puzzleworld2 - Мир Демонов 2 teampk - Арена jialebi - Небеса, база флота, остров сокровищ, остров скелетов garner2 - Серебряный Хаос hell(2-5) - Абаддон (2-5) guildwar - Священная война guildwar2 - Маленькая священная война leiting2 - Мираж Громограда shalan2 - Мираж Шайтана binglang2 - Мираж Ледыни yschurch - Церковь 07xmas - Новогодняя деревня 2007 07xmas2 - Снежная война prisonisland - Тюрьма winterland - Остров Зимы mjing1 - 1-ый край Авроры mjing2 - 2-ой край Авроры mjing3 - 1-ый край Тьмы mjing4 - 2-ой край Тьмы starena* - Арены heilong - Сундук черного дракона darkhouse - Дом тьмы mingyun - Комната судьбы Примечание: карты garner, magicsea и darkblue необходимо запускать на разных экземплярах GameServer. Определите для каждого конфигурационного файла GameServer набор локаций. Локации garner, maigcsea и darkblue в соответствии с примечанием должны быть записаны в разных конфигурационных файлах. Для примера можно настроить конфигурационные файлы таким образом: GameServer.cfg map = garner map = garner2 map = teampk map = lonetower map = puzzleworld map = puzzleworld2 map = eastgoaf map = leiting2 map = shalan2 map = binglang2 GameServer2.cfg [Map] map = magicsea map = abandonedcity map = abandonedcity2 map = abandonedcity3 map = darkswamp map = secretgarden map = guildwar map = guildwar2 GameServer3.cfg [Map] map = darkblue map = jialebi map = hell map = hell2 map = hell3 map = hell4 map = hell5 Сохраните очередной конфигурационный файл (.cfg) GameServer. После внесения изменений в последний конфигурационный файл, настройка экземпляров GameServer окончена. Процесс установки и настройки серверного программного обеспечения Пиратии завершен. Далее приступим к запуску игрового мира. 5. Запуск сервера Общие принципы и порядок запуска исполняемых файлов сервера Поскольку игровой сервер состоит из нескольких исполняемых файлов (AccountServer.exe, GateServer.exe, GameServer.exe, GroupServer.exe), то их необходимо запускать в определенном порядке: 1. AccountServer; 2. Экземпляры GameServer; 3. GroupServer; 4. GateServer. Для запуска AccountServer, GroupServer и GateServer достаточно запустить их исполняемые файлы из проводника. Если таким же образом запустить GameServer, то он будет использовать конфигурационный файл по умолчанию GameServer.cfg, поэтому при запуске очередного экземпляра GameServer необходимо дополнительно указать в параметрах его запуска конфигурационный файл, который необходимо использовать экземпляру для работы: GameServer.exe <Конфигурационный файл> Это можно сделать из Командной строки (cmd.exe), либо с помощью пакетного .bat-файла. Запуск GameServer из Командной строки (cmd.exe) cd C:\PKO Server\GameServer GameServer GameServer2.cfg Данная последовательность команд запустит исполняемый файл GameServer.exe с конфигурационным файлом GameServer2.cfg, которые находятся на диске в директории C:\PKO Server\GameServer. Запуск GameServer с помощью .bat-файла start GameServer.exe GameServer3.cfg Данный .bat-файл запустит исполняемый файл GameServer с конфигурационным файлом GameServer3.cfg при условии, что GameServer.exe и .bat-файл находятся в одной и той же директории. Чтобы запустить сразу несколько экземпляров GameServer с различными конфигурационными файлами, можно написать простой .bat-скрипт: @echo off start GameServer.exe GameServer.cfg start GameServer.exe GameServer2.cfg start GameServer.exe GameServer3.cfg По аналогии можно сделать .bat-файл, который запустит весь игровой сервер, например, с рабочего стола: @echo off cd C:\PKO Server\AccountServer start AccountServer.exe cd C:\PKO Server\GameServer start GameServer.exe GameServer.cfg start GameServer.exe GameServer2.cfg start GameServer.exe GameServer3.cfg cd C:\PKO Server\GroupServer start GroupServer.exe cd C:\PKO Server\GateServer start GateServer.exe Примечание: в данном примере исполняемые файлы сервера находятся в соответствующих папках в директории C:\PKO Server\. Запуск AccountServer Запустите исполняемый файл AccountServer.exe любым удобным для Вас способом. В результате должно появиться два окна: форма со служебной информацией и консольное окно. В консольном окне не должно быть никаких ошибок. После запуска GroupServer, в окне со служебной информацией в списке GroupServer должен быть отображен подключенный GroupServer (поле Status имеет значение connected). Запуск экземпляров GameServer Запустите исполняемый файл GameServer.exe для каждого конфигурационного файла (.cfg) удобным для Вас способом. Появится несколько консольных окон и начнется процесс подключения к Microsoft SQL Server и загрузки каждого экземпляра GameServer. В процессе загрузки очередного экземпляра не должны возникать ошибки в виде записей в консоли или окон сообщений. Соединение с Microsoft SQL Server должно быть успешно установлено, что подтверждается соответствующей записью в консоли: "Database Connected!". После успешного завершения загрузки GameServer должно появиться окно со служебной информацией: ID процесса (PID), частота обновления игрового мира (FPS), число персонажей игроков в игре (Player), загруженный конфигурационный файл (Config) и другая. Проверьте, что напротив каждой карты в списке "Map List" стоит надпись "ok", которая говорит об успешной загрузке локации. После запуска GateServer в списке "Gate" появится IP-адрес GateServer с надписью напротив "connected", к которому подключился данный экземпляр GameServer. Запуск GroupServer Запустите исполняемый файл GroupServer.exe. Появится консольное окно GroupServer. В окне не должно быть никаких сообщений об ошибках. После запуска AccountServer и GateServer появятся сообщения об успешном установлении соединения с данными приложениями. Запуск GateServer Запустите исполняемый файл GateServer.exe. Появится консольное окно GateServer в котором должно быть сообщение об успешном запуске приложения. Игровой сервер Пиратии успешно запущен! Проверим его доступность для подключения к нему игровых клиентов. 6. Проверка соединения с игровым сервером Для определения возможности подключения к Вашему игровому серверу из сети Интернет можно воспользоваться сервисами в Интернете, которые позволяют выполнить проверку внешнего порта сервера на доступность, например, 2ip - Проверка порта. В поле "Порт" введите внешний порт GateServer из секции ToClient конфигурационного файла GateServer.cfg. По умолчанию это порт 1973. Нажмите кнопку "Проверить". При этом, исполняемый файл GateServer.exe должен быть запущен. Вы увидите сообщение "Порт открыт" если сервер доступен для подключения к нему, либо "Порт закрыт" в противном случае. Еще одним способом проверки доступности игрового сервера является подключение к нему используя клиент Telnet. Для этого запустите клиент Telnet, например, встроенный в операционную систему Windows (сочетание клавиш Windows + R, открыть telnet.exe) и выполните в нем команду для подключения к игровому серверу: open <IP-адрес> <Порт> <IP-адрес> - это IP-адрес игрового сервера, подключение через который Вы хотите проверить; <Порт> - внешний порт игрового сервера. При доступности игрового сервера по указанному адресу Вы увидите строку с датой и временем подключения к серверу. 7. Остановка игрового сервера Для корректного отключения игроков и сохранения состояния игрового мира в базах данных на диске, рекомендуется останавливать сервер в следующей последовательности: 1. Все экземпляры GameServer; 2. GroupServer; 3. GateServer; 4. AccountServer. Отключать сервер через Диспетчер задач нельзя - можно потерять несохранённые игровые данные в памяти, что приведет к откату состояния игрового мира в прошлое при следующем запуске сервера. Перед остановкой сервера считается хорошим тоном предупредить игроков о предстоящем отключении. Чтобы завершить работу всех экземпляров GameServer, откройте служебное окно очередного экземпляра и введите в поле ввода команд (1) команду Stop(X), где X - время в секундах, через которое текущий GameServer будет остановлен, после чего нажмите кнопку "Execute" (2). Когда все экземпляры GameServer завершат свою работу, остановите поочередно GroupServer, затем GateServer и после AccountServer с помощью сочетания клавиш CTRL + C в консольном окне. Процесс завершения работы очередного сервера может занять время, то есть приложения закроются не сразу. 8. Подключение игрового клиента к серверу Чтобы войти во вновь созданный игровой мир, Вам понадобится игровой клиент, который можно скачать в данной теме на нашем форуме: Выберите из списка доступных клиентов тот, который подойдет по версии к Вашим серверным файлам. Например, для сборки Pirate King Online 1.38 подойдет официальный русский клиент версии 1.38.1: Скачайте выбранный дистрибутив (архив) и установите (распакуйте) его на Ваш диск. Перейдите в корневую директорию игрового клиента и создайте там .bat-файл с названием start.bat. Он будет необходим для запуска клиента в обход программы автообновления. start system\Game.exe startgame Затем скачайте программу IP Changer, с помощью которой нужно задать игровому клиенту IP-адрес для подключения к серверу. Поместите IPChanger.exe в корневую директорию игрового клиента и запустите. В поля ввода текста "Server Name" (1) и "Server Region" (2) введите название Вашего сервера и регион соответственно. В поле "Server Address" (3) укажите IP-адрес игрового сервера, через который клиент будет к нему подключаться. Выпадающий список "Client Version" оставьте без изменений. Нажмите кнопку "ОК" (4) и после сообщения "Address of server was successfully changed!" закройте программу. Первичная настройка клиента завершена. Для подключения к серверу необходим игровой аккаунт, который можно создать с помощью специальной программы. Скачайте и запустите программу Создать учетную запись. Нажмите кнопку "Настройки" (1) на главной форме приложения. В окне "Настройки" укажите адрес или имя экземпляра Microsoft SQL Server (1), отметьте флажок "Использовать проверку подлинности Windows" и проверьте подключение (3). При успешном подключении к Microsoft SQL Server нажмите кнопку "ОК" (4). Далее введите желаемые логин (2) и пароль (3) для новой учетной записи, а также выберите уровень доступа к системе (4). После заполнения всех полей нажмите кнопку "Создать" (5). Вы увидите сообщение о том, что учетная запись была успешно создана. Запустите игровой клиент с помощью .bat-файла start.bat и подключитесь к серверу используя созданную учетную запись. После успешного входа в учетную запись, создайте нового персонажа и убедитесь что создание персонажей работает исправно. Войдите вновь созданным персонажем в игровой мир. На этом этапе задача установки игрового сервера выполнена, и гайд подходит к своему логическому завершению, но в процессе Вы могли столкнуться с различными ошибками. В следующем разделе будут рассмотрены самые распространенные ошибки сервера и клиента, а также методы их устранения. 9. Распространенные ошибки и их исправление В процессе установки сервера и подключения к игровому миру могут возникнуть различные ошибки. Далее рассмотрим самые распространенные и исправим их. GameServer.exe сразу закрывается после запуска Заполните все данные для подключения к Microsoft SQL Server в конфигурационном файле GameServer.cfg (секция DB). [DB] db_ip = db_usr = db_pass = Ошибки GameServer "Database [GameDB] Connect Failed!", GroupServer "Unable to connect database", AccountServer "Main database handler create failed, AccountServer hang!" Данные ошибки говорят о том, что серверное программное обеспечение (GameServer, GroupServer, AccountServer) не может установить соединение с Microsoft SQL Server и получить доступ к соответствующим базам данных. Возможные пути решения: 1. Проверьте, что Microsoft SQL Server запущен и Вы указали его верный адрес или имя экземпляра в конфигурационных файлах игрового сервера; 2. Проверьте, что в настройках безопасности Microsoft SQL Server Вы включили проверку подлинности SQL Server и Windows и перезапустили после этого SQL Server; 3. Убедитесь, что Вы используете верные логин и пароль пользователей для соответствующей базы данных в конфигурационных файлах игрового сервера. Пользователям баз данных должны быть выданы следующие права: db_datareader, db_datawriter, db_ddladmin, public. Пароли пользователей должны быть указаны в конфигурационных файлах в зашифрованном виде; 4. Убедитесь, что названия баз данных совпадают в Micrososft SQL Server и в конфигурационных файлах сервера, а так же в исполняемом файле GameServer.exe Ошибка GameServer "SubMap::LoadNpc: Obtain Map [<название локации>] ID fail!" Данная ошибка может возникнуть в процессе загрузки локаций игрового мира при запуске экземпляра GameServer. Чтобы её исправить откройте файл GameServer\resource\script\MisScript\ScriptDefine.lua и добавьте в конец строку: AddMap("<Кодовое название локации>", "<Игровое название локации>") Например: AddMap("yschurch", "Церковь") Ошибка игрового клиента "Соединение прервано" Такая ошибка возникает в случае, когда игровой клиент не может установить сетевое соединение с сервером. Возможные пути решения: 1. Проверьте, что GateServer запущен. Если Вы подключаетесь к серверу через сеть Интернет, то проверьте доступность GateServer. Внешний порт игрового сервера (по умолчанию 1973) должен быть открыт, а в конфигурационном файле GateServer.cfg должен быть указан соответствующий внешний IP-адрес (0.0.0.0 или адрес выделенного сервера). Внешний IP-адрес сервера должен быть публичным ("белым"); 2. Убедитесь, что игровой клиент настроен на верный адрес игрового сервера: с помощью программы IPChanger (а также иных способов настройки клиента) указан верный IP-адрес GateServer, а в Game.exe "зашит" верный порт GateServer (по умолчанию 1973). Чтобы убедиться в последнем, можно взять Game.exe из официального русского клиента без каких-либо модификаций, либо использовать специальную программу; 3. Соединению клиента с сервером могут препятствовать различные программы-фаерволы, брандмауэр Windows, а также сетевые маршрутизаторы (роутеры), в которых не был проброшен внешний порт GateServer на компьютер с игровым сервером. Ошибка игрового клиента "Account server has encountered a malfunction" Запустите AccountServer и убедитесь что к нему успешно подключился GroupServer. Ошибка игрового клиента "Discovered exceptional line error on GateServer" Запустите GroupServer и убедитесь что к нему успешно подключился GateServer. Ошибка игрового клиента "Неверная версия игры" Убедитесь, что версии в конфигурационном файле GateServer.cfg (секция Main, параметр Version) и в Game.exe совпадают. Обычно в Game.exe "зашита" версия 136. Узнать версию Game.exe можно с помощью специальной программы на нашем форуме. Ошибка игрового клиента "illegal birth place" при создании персонажа Откройте файл игрового клиента Клиент\scripts\table\StringSet.txt и замените строки [39] "Аргент" [40] "Шайтан" [41] "Ледынь" на [39] "Argent City" [40] "Shaitan City" [41] "Icicle Castle" Значения Argent City, Shaitan City и Icicle Castle определяются соответствующими значениями в конфигурационном файле GroupServer.cfg игрового сервера. [bird] Argent City = garner Shaitan City = magicsea Icicle Castle = darkblue Ошибка игрового клиента "target map cannot be reached" при входе в игровой мир Выбранный персонаж находится на локации, которая не запущена на сервере. Запустите все экземпляры GameServer с полным набором локаций и убедитесь, что в каждом служебном окне текущего экземпляра GameServer отображается успешно загруженный список карт игрового мира (список Map List). Если вы столкнулись с проблемой, которой нет в рассмотренном выше списке ошибок, то воспользуйтесь разделом "Пиратия: Помощь", в котором Вам придут на помощь более опытные администраторы и разработчики серверов Пиратии. Также за много лет на нашем форуме накоплен большой пласт опыта Ваших предшественников, поэтому целесообразно воспользоваться поиском по форуму: с большой долей вероятности Ваша проблема уже обсуждалась и решена в прошлом. Благодарю Вас за внимание и надеюсь, что статья действительно была Вам интересна и помогла в установке сервера! Я был рад поделиться с Вами своим опытом. Гайд написал V3ct0r специально для форума PKODev.NET Копирование статьи в том или ином виде на сторонние ресурсы без согласования с автором ЗАПРЕЩЕНО!
  3. Система "оффлайн" ларьков Одним из игровых аспектов игры является торговля между персонажами посредством особых ларьков (лавок), которые могут открывать игроки изучив специальное умение. Игрок выставляет свои предметы за определенную цену, а остальные игроки могут покупать их. Однако, для такой торговли игрок должен находиться в игре, то есть быть подключенным к серверу, что вынуждает его оставлять свой компьютер постоянно включенным и держать игровой клиент свернутым. Это очень неудобно, поэтому была придумана система "оффлайн" ларьков, которая позволяет игрокам отключаться от сервера и при этом оставаться торговать в ларьках. Возможно несколько способов реализации такой системы, но наиболее распространена система "оффлайн" ларьков через прокси-сервер: 1) Игровой клиент (Game.exe) подключается к прокси-серверу; 2) Прокси-сервер, в свою очередь, открывает соединение с GateServer.exe; 3) Далее, прокси-сервер передает все пакеты между Game.exe и GateServer.exe, при этом анализируя их; 4) Когда игрок открывает торговый ларек, прокси-сервер фиксирует это (GateServer.exe отправил Game.exe пакет успешного открытия ларька); 5) Если игрок отключается от сервера будучи в торговом ларьке, то прокси-сервер закрывает соединение с Game.exe, но при этом сохраняет соединение с GateServer.exe и начинает имитировать Game.exe. Таким образом, GateServer.exe не подозревает о факте отключения Game.exe и персонаж игрока остается торговать в ларьке на сервере. Game.exe | Game.exe | <---------> pkodev.stallserver.exe <---------> GateServer.exe Game.exe | В данной теме обсуждается разработка такого прокси-сервера - PKOdev.NET Stall Server. Внимание! Сервер находится на стадии разработки и не предназначен для применения в "продакшене". Это означает что приложение полностью не протестировано и может содержать ошибки, баги и критические уязвимости. Возможности 1) Система оффлайн ларьков; 2) Ограничение количества оффлайн ларьков с одного IP-адреса; 3) Ограничение времени торговли в оффлайн-ларьке; 4) Автоматическое отключение аккаунта, торгующего в оффлайн ларьке, при подключении игрока с использованием того же аккаунта; 5) Оповещение игроков в чат о том, что персонаж находится в оффлайн ларьке и в данный момент не в сети (при обращении в ЛС); 6) Исправление SQL-инъекций в пакетах авторизации и создания (смены) секретного кода; 7) Установка максимального числа подключений к серверу с одного IP-адреса и интервала между подключениями. To-do: 1) Перевод комментариев в файлах Server.h and Server.cpp на английский язык; 2) Исправление падения сервера при обработке пакетов от клиента; 3) Исправление падения сервера при запуске, когда локальный порт занят; 4) Исправление зависания моста при блокировке пакета при включенном шифровании (спасибо @small666 за обнаруженный баг); 5) Синхронизация между потоками при обработке пакетов; 6) Закрытие оффлайн ларька, если все предметы проданы; 7) Модификация GateServer.exe для определения IP-адресов клиентов, которые находятся за сервером оффлайн ларьков. В данный момент в логах и базе данных IP-адреса всех клиентов будут записываться как 127.0.0.1 (если GateServer.exe и pkodev.stallserver.exe запущены на одной машине). 8 ) Совместимость с исходным кодом Corsairs Online (CO). Сборка и запуск 1) Выполните клонирование репозитория с проектом сервера к себе на диск (ссылка будет ниже); 2) Откройте файл решения pkodev.stallserver.sln в Visual Studio 2022 Community; 3) Соберите решение. Исполняемые файлы сервера появятся в папке bin; 4) Поместите конфигурационный файл pkodev.stallserver.cfg из папки cfg в одну директорию с исполняемым файлом сервера pkodev.stallserver.exe; 5) Настройте конфигурационный файл pkodev.stallserver.cfg по своему усмотрению (файл хорошо прокомментирован); 6) Для подключения игрового клиента (Game.exe) к серверу оффлайн ларьков нужно установить мод pkodev.mod.stallserver; 7) Для подключения сервера оффлайн ларьков к GateServer.exe, последний должен быть без каких-либо модификаций ("чистым"), например, из сборки PKO 1.38; 8 ) Запустите исполняемый файл сервера оффлайн ларьков pkodev.stallserver.exe. Репозиторий Git https://github.com/V3ct0r1024/pkodev.stallserver
  4. Загрузчик модов для сервера и клиента (PKOdev.NET mod loader) Проблема Многим разработчикам и администраторам серверов Пиратии в нашем сообществе известно, что функциональность клиента и сервера можно изменять так называемыми модами (аддонами, плагинами, дополнениями, патчами). Например: 1) Исправление SQL-инъекций в AccountServer.exe и GroupServer.exe; 2) Увеличение лимитов для .txt/.bin файлов (ItemInfo, CharacterInfo, SkillInfo и других); 3) Обработка сообщений в канал местного чата с помощью lua функции HandleChat(); 4) Трансформация персонажей с помощью lua функции TransformCha(); 5) Панель наложенных на персонажа эффектов; 6) Отображение уровня ЖЗ и МН под персонажами и монстрами. Таким образом, с помощью модов можно исправлять критические баги и уязвимости, изменять настройки, добавлять новый функционал и возможности. Изначально появление модов было вызвано отсутствием в открытом доступе исходных кодов клиента и сервера: разработчикам ничего не оставалось, кроме того, как редактировать исполняемые .exe файлы, развивая и применяя навыки реверс-инжиниринга. После публикации "исходников" популярность модов по-прежнему остается на высоком уровне. Этому способствует ряд причин: 1) Низкое качество полученных исходных кодов, отсутствие опыта их использования. Чтобы ими пользоваться, администратору нужно обладать широкими знаниями языка программирования C++, разбираться в клиент-серверной архитектуре, понимать как устроен сервер и клиент. Кроме того, исходные коды требуют длительного изучения и исследования на предмет багов и уязвимостей, включая процесс тестирования; 2) Существующие официальные сборки сервера и клиента в полной мере удовлетворяют требованиям большинства администраторов и игроков, кроме того, их работоспособность и надежность подтверждена годами практического применения. Для них было создано множество программ, скриптов и модов, которые могут быть несовместимы с исполняемыми файлами сервера и клиента, собранными из исходных кодов; 3) Изучение исходных кодов позволяет лучше понять устройство исполняемых файлов сервера и клиента Пиратии. Такие полученные знания делают возможным создавать моды повышенной сложности. Администраторы и разработчики при реализации своих игровых проектов могут пойти по двум путям: использовать старые, официальные сборки сервера и клиента, и изменять их функционал с помощью модов, либо развиваться в направлении разработки исходных кодов. Как уже должно быть понятно, данная тема поддерживает первый путь. В настоящий момент разработка модов связана с некоторыми проблемами: 1) В нашем сообществе отсутствует четкий стандарт и культура написания модов. Кто-то внедряет код непосредственно в исполняемый .exe файл методом "патчинга", другие предпочитают писать DLL-библиотеки. Некоторые моды могут конфликтовать друг с другом, что приводит к ошибкам и трудноуловимым багам; 2) Как следствие, установка модов сопряжена с определенными трудностями: например, как перенести мод из одного GameServer.exe в другой? Каждый раз необходимо заниматься редактированием ("патчингом") исполняемых .exe файлов, а для этого нужно обладать специальными знаниями и навыками. Если моды выполнены в виде DLL-библиотек, то каждый мод необходимо вручную вносить в таблицу импорта исполняемого .exe файла. Все это неудобно, отнимает много времени и создает вероятность совершения ошибок в процессе установки и появления багов; 3) Существует некоторое множество версий GameServer.exe и Game.exe (остальные серверные исполняемые .exe файлы не принимаем во внимание), которые имеют различную двоичную структуру. Иными словами, разработанный мод для GameServer.exe версии 1.36 не будет работать с GameServer.exe версии 1.38 – Вам необходимо разрабатывать мод под конкретный .exe файл. Вследствие этого возникает путаница с версиями исполняемых файлов. Яркий пример – адреса лимитов для .txt/.bin: думаю, многие заметили что они разные для разных .exe. Исходя из вышесказанного, было принято решение создать систему, которая исправит текущее положение вещей в отношении модов и упростит их использование – Загрузчик модов для клиента и сервера. Загрузчик модов Загрузчик модов выполняет несколько задач: 1) Унификация процесса создания, установки и запуска модов; 2) Определение типа и версии исполняемого .exe файла, который подлежит модификации; 3) Поиск установленных модов, определение их версии и совместимости с целевым исполняемым .exe файлом, подключение модов к исполняемому .exe файлу клиента или сервера. Представляет собой DLL-библиотеку, которая единоразово подключается к исполняемому .exe файлу клиента или сервера . Моды так же являются DLL-библиотеками, которые помещаются в определенную директорию и автоматически запускаются загрузчиком при запуске клиента или сервера. Перед запуском исполняемого .exe файла клиента или сервера управление передается загрузчику. Загрузчик определяет тип и версию .exe файла, к которому он привязан, и начинает процесс поиска DLL-библиотек в директории "mods" из корневой папки клиента/сервера. Текущая найденная DLL-библиотека динамически подключается к процессу клиента/сервера, после чего загрузчик запрашивает у библиотеки информацию о моде: название мода, тип и версия целевого .exe файла, версия мода, имя автора модификации. Если тип и версия .exe файла с загрузчиком совпадает с типом и версией .exe файла, полученными из DLL-библиотеки мода, то загрузчик дает моду команду на запуск. Далее мод вносит изменения в код процесса исполняемого файла, тем самым осуществляя модификацию. Перед завершением процесса клиента/сервера управление снова передается загрузчику, который по очереди отключает от процесса все моды. Текущая версия загрузчика может работать с официальными 1.3x версиями Game.exe (клиент) и GameServer.exe (сервер). Определение типа исполняемого файла (GameServer.exe или Game.exe) и его версии производится по метке времени компиляции (linker timestamp), которая записана в COFF-заголовке каждого исполняемого файла. Поддерживаемые Game.exe и GameServer.exe ---------------------+----+----------------+-------------- Название | ID | Обозначение | Метка времени ---------------------+----+----------------+-------------- GameServer.exe 1.36 | 1 | GAMESERVER_136 | 1204708785 ---------------------+----+----------------+-------------- GameServer.exe 1.38 | 2 | GAMESERVER_138 | 1204708785 ---------------------+---+----------------+-------------- Game.exe | 3 | GAME_13X_0 | 1222073761 ---------------------+----+----------------+-------------- Game.exe | 4 | GAME_13X_1 | 1243412597 ---------------------+----+----------------+-------------- Game.exe | 5 | GAME_13X_2 | 1252912474 ---------------------+----+----------------+-------------- Game.exe | 6 | GAME_13X_3 | 1244511158 ---------------------+----+----------------+-------------- Game.exe | 7 | GAME_13X_4 | 1585009030 ---------------------+----+----------------+-------------- Game.exe | 8 | GAME_13X_5 | 1207214236 ---------------------+----+----------------+-------------- GateServer.exe 1.38 | 101| GATESERVER_138 | 1224838480 ---------------------+----+----------------+-------------- Установка загрузчика модов 1) В корневой директории исполняемого .exe файла, к которому подключается загрузчик модов, создайте папку с названием "mods"*. В этой папке будут храниться DLL-библиотеки модов; 2) Откройте исполняемый .exe файл в программе CFF Explorer. Перейдите на вкладку "Import adder" (1); 3) Нажмите кнопку "Add" (2) и выберите файл pkodev.mod.loader.dll; 4) В списке "Exported functions" выберите "ExportedFunction" (3); 5) Нажмите кнопку "Import By Name" (4); 6) Снимите флажок "Rebuild OFTs" (5); 7) Нажмите кнопку "Rebuild Import Table" (6); 8 ) Сохраните файл (7). 9) Запустите исполняемый .exe файл. В окне консоли вы должны увидеть следующее сообщение: [pkodev.mod.loader] ----------------------------------------------- [pkodev.mod.loader] PKOdev.NET mod loader ver. 1.0 by V3ct0r [pkodev.mod.loader] ----------------------------------------------- Если у исполняемого файла нет окна консоли, например, у Game.exe, то запустите его следующим образом: system\Game.exe startgame > output.txt Теперь вывод в консоль будет перенаправлен в текстовый файл output.txt. * Примечание: для Game.exe папка "mods" должна находиться в корневой директории игрового клиента, а не в папке system. Установка модов Чтобы установить мод достаточно поместить его DLL-библиотеку в папку "mods". Для удобства каждый мод можно помещать в отдельную папку. Пример структуры папок для GameServer.exe: GameServer | -> Mods | -> .disabled | -> .priority | -> pkodev.mod.example1.server.138.dll | -> pkodev.mod.example2 | -> pkodev.mod.example2.server.138.dll | -> pkodev.mod.example3 | -> pkodev.mod.example3.server.138.dll После запуска исполняемого .exe файла Вы должны увидеть новый мод в списке загруженных модов: Удаление модов Чтобы удалить мод, необходимо удалить его DLL-библиотеку из папки "mods". Временное отключение модов Чтобы отменить загрузку тех или иных модов, создайте в корневой директории с модами (папка "mods") файл ".disabled" и запишите в него названия модов, которые необходимо временно отключить, с новой строки. Например: // Файл: mods\.disabled // Запишите ниже названия модов, которые необходимо отключить pkodev.mod.fullmap pkodev.mod.tablelimit Таким образом, моды "pkodev.mod.fullmap" и "pkodev.mod.tablelimit" будут проигнорированы загрузчиком. Приоритет загрузки модов Загрузчик модов позволяет загружать те или иные моды в указанном порядке. Для этого создайте в корневой директории с модами (папка "mods") файл ".priority" и запишите в него названия модов в порядке убывания приоритета. Моды, не записанные в данном файле, будут загружены после модов с приоритетом, в случайном порядке. Например: // Файл mods\.priority // Запишите ниже названия модов в порядке убывания приоритета загрузки pkodev.mod.power pkodev.mod.tablelimit pkodev.mod.fullmap Моды будут загружены в следующем порядке: 1. pkodev.mod.power; 2. pkodev.mod.tablelimit; 3. pkodev.mod.fullmap; 4. Далее - все остальные обнаруженные в папке "mods" моды в случайном порядке. Создание мода Для того, чтобы мод мог быть загружен загрузчиком, он должен соответствовать следующим требованиям: 1) Название DLL-библиотеки мода должно быть вида: pkodev.mod.<название мода>.<client или server>.<обозначение версии.exe >.dll Например: pkodev.mod.tablelimit.client.13x_0.dll pkodev.mod.mobspawn.server.138.dll 2) DLL-библиотека мода должна экспортировать 3 функции: __declspec(dllexport) void __cdecl GetModInformation(mod_info& info) Заполнить структуру типа mod_info. Данная структура содержит основную информацию о моде: название, версию, имя автора, ID типа и версии исполняемого .exe файла, для которого предназначен мод. // Mod information structure struct mod_info { // Название мода char name[128]; // Версия мода char version[64]; // Имя автора char author[64]; // Тип и версия целевого .exe файла (см. таблицу) unsigned int exe_version; }; __declspec(dllexport) void __cdecl Start(const char* path) Запустить мод и произвести модификацию процесса исполняемого файла. В переменной path содержится путь до корневой директории мода. В данной функции мод должен выполнить свою инициализацию, загрузить необходимые настройки и произвести модификацию процесса исполняемого файла. __declspec(dllexport) void __cdecl Stop() Остановить мод. В данной функции мод должен сохранить свои настройки, откатить модификацию процесса (необязательно) и освободить ресурсы. 3) Тип и версия исполняемого файла, указанная в DLL-библиотеке мода (структура modinfo, поле exe_version), должны совпадать с типом и версией исполняемого файла, для которого он предназначен. Если загрузчик определил тип и версию исполняемого файла как GameServer.exe 1.38 (GAMESERVER_138) с ID 2 (см. таблицу выше), то DLL-библиотека мода должна записывать в поле exe_version значение 2. Пример разработки мода Для разработки мода можно использовать любой язык программирования, который поддерживает создание DLL-библиотек. Я буду использовать язык C++ и среду разработки Visual Studio 2019 Community. В качестве примера создадим мод для GameServer.exe версии 1.38 (ID 2), который будет выводить в его окно сообщение "Hello world!". 1) Определим название мода, пусть оно будет: pkodev.mod.helloworld Тогда название DLL-библиотеки мода будет: pkodev.mod.helloworld.server.138.dll 2) Создадим проект динамически подключаемой библиотеки .DLL; 3) Подключаем к проекту файл loader.h (см. вложения в конце данного сообщения); 4) Реализуем функцию GetModInformation(): void GetModInformation(mod_info& info) { strcpy_s(info.name, "pkodev.mod.helloworld"); strcpy_s(info.version, "1.0"); strcpy_s(info.author, "V3ct0r"); info.exe_version = GAMESERVER_138; } 5) Реализуем функцию Start(): void Start(const char* path) { std::cout << "Hello world!" << std::endl; std::cout << "path = " << path << std::endl << std::endl; } 6) Реализуем функцию Stop(): void Stop() { } 7) Скомпилируем проект. В результате мы получим файл pkodev.mod.helloworld.server.138.dll; 8 ) Устанавливаем и тестируем мод. В окне GameServer.exe мы должны увидеть сообщение "Hello world!" и путь до корневой директории мода: Проект примера мода можно найти во вложении. Скачать 1) Загрузчик модов; 2) Исходный код загрузчика модов для Visual Studio 2019 Community (C++); 3) Интерфейс для создания модов (файл loader.h); 4) Проект примера мода "Hello world!" для Visual Studio 2019 Community (C++); 5) Образцы исполняемых файлов клиента и сервера из таблицы (7.3 Мб); 6) Шаблон проекта мода PKOdev.NET loader для Visual Studio 2019 Community (C++). Доступные моды 1) Подключение Game.exe к Stall Server (сервер "оффлайн" ларьков); 2) Исправление мгновенного возрождения убитых монстров после перезапуска сервера; 3) Редактирование лимитов .txt таблиц; 4) Система рейтинга игроков; 5) Система ежедневных наград за вход в игру; 6) Отображение времени отката ("кулдауна") умений; 7) Отображение координат под NPC; 8 ) Автоматическое подключение к серверу / вход в игру; 9) Социальные кнопки (Discord, Youtube, Twitch и др.); 10) Медали (ожерелья) со званиями; 11) Отображение уровня персонажа игрока рядом с его именем; 12) Отображение дополнительных параметров на форме с характеристиками персонажа (frmState); 13) Время сервера; 14) Антибот; 15) Отображение уровня предметов на иконках ("умные иконки"); 16) Отображение названия предмета в аппарели; 17) Изменение размера персонажей; 18) Отображение времени отклика ("пинг") на форме выбора сервера; 19) Система контрактов; 20) Отключение проверки пароля при входе во внутриигровой Интернет-магазин; 21) Отключение сообщений об ошибках при компиляции .txt-таблиц (table_bin); 22) Очистка чатов; 23) Исправление сброса профессии персонажей при переподключении к серверу ("слёт профессии"); 24) Цветные GM-сообщения (GM notice); 25) 60 кадров в секунду (60 FPS); 26) Эффект полета для крыльев; 27) Полная карта местности для региона; 28) Выделение друзей и врагов цветом. (Обновлено 18.02.2022) Если у Вас есть какие-либо вопросы или возникли проблемы, то смело спрашивайте в данной теме!
  5. [Мод] Система ежедневных наград за вход в игру Данный мод реализует систему ежедневных наград за вход в игру. Игрокам необходимо каждый день заходить в игру, чтобы получить очередную награду - с каждым новым днем награда становится ценнее. Если игрок пропускает день, то цепочка сбрасывается и начинается заново с первого дня. Каждую неделю цепочка так же сбрасывается. Цепочка наград настраивается администратором в специальной lua функции и рассчитывается на неделю вперед, после чего сохраняется в базе данных сервера. Требования Установленный Загрузчик модов для сервера и клиента (PKOdev.NET mod loader). Информация о моде Название: pkodev.mod.reward; Версия: 1.0; Автор: V3ct0r; Тип: для клиента и сервера (Game.exe и GameServer.exe); Поддерживаемые исполняемые .exe файлы: GAME_13X_0, GAME_13X_1, GAME_13X_2, GAME_13X_3, GAME_13X_4, GAME_13X_5, GAMESERVER_136 и GAMESERVER_138. Установка Сервер: 1) В директории "GameServer\mods" Вашего сервера создайте папку "pkodev.mod.reward"; 2) Поместите в неё файл DLL-библиотеки мода "pkodev.mod.reward.server.13<x>.dll" для Вашей версии GameServer.exe; 3) В файл functions.lua ("GameServer\resource\script\calculate\") запишите следующий скрипт: -- Daily reward system (pkodev.mod.reward) -- Transfer the list of items to the system function GetRewardArrayAdapter(role) -- Get a list of items for daily reward local arr = GetRewardArray(role) -- Transfer the list to the system return arr[1].id, arr[1].number, arr[2].id, arr[2].number, arr[3].id, arr[3].number, arr[4].id, arr[4].number, arr[5].id, arr[5].number, arr[6].id, arr[6].number, arr[7].id, arr[7].number end -- Daily reward system (pkodev.mod.reward) -- Get a list of items for daily reward function GetRewardArray(role) -- Select an item depending on character race local hairstyle_book = function(role) -- List of items -- ID: 931 Lance Trendy Hairstyle Book -- ID: 932 Carsise Trendy Hairstyle Book -- ID: 933 Phyllis Trendy Hairstyle Book -- ID: 934 Ami Trendy Hairstyle Book local items = {931, 932, 933, 934} -- Get character type ID local id = GetChaTypeID(role) -- Return item id depending on the type ID return items[id] or 0 end -- Make a list of items for daily reward local items = { -- Day 1 (Short Sword x 1 or Long Sword x 1 or Fencing Sword x 1) {id = math.random(1, 3), number = 1}, -- Day 2 (Apple x 99 or Bread x 99 or Cake x 99) {id = math.random(1847, 1849), number = 99}, -- Day 3 (Fairy Coin x 50) {id = 855, number = 50}, -- Day 4 (Random fairy ID 183 ... 193 x 1) {id = math.random(183, 193), number = 1}, -- Day 5 (Hairstyle Book x 1) {id = hairstyle_book(role), number = 1}, -- Day 6 (Fairy Ration x 10) {id = 227, number = 10}, -- Day 7 (Refining Gem x 1) {id = 885, number = 1} } -- We have to return an array of items to caller function return items end 4) В MSSQL Management Studio выполните SQL-запрос: USE GameDB ALTER TABLE character ADD reward VARCHAR(128) NOT NULL DEFAULT '0' WITH VALUES Клиент: 1) В директории "mods" Вашего клиента создайте папку "pkodev.mod.reward"; 2) Поместите в неё файл DLL-библиотеки мода "pkodev.mod.reward.client.13x_<x>.dll" для Вашей версии Game.exe; 3) Поместите файлы текстур формы "main.png" и "buttons.tga" в директорию "texture\mods\pkodev.mod.reward" Вашего клиента; 4) В файл скриптов "main.clu" ("scripts\lua\forms") добавьте код формы ежедневной награды: ---------------------------------------------------------------------------------------------------- -- Daily login reward form ---------------------------------------------------------------------------------------------------- -- The form frmReward = UI_CreateForm( "frmReward", FALSE, 366, 158, 150, 200, TRUE, FALSE ) UI_SetFormStyle( frmReward , 0 ) UI_AddFormToTemplete( frmReward, FORM_MAIN ) UI_FormSetIsEscClose( frmReward, FALSE ) UI_SetIsDrag( frmReward, TRUE ) -- Form background frmRewardImg = UI_CreateCompent( frmReward, IMAGE_TYPE, "frmRewardImg", 366, 158, 0, 0 ) UI_LoadImage( frmRewardImg, "texture/mod/pkodev.mod.reward/main.png", NORMAL, 366, 158, 0, 0 ) -- Form title labTitle = UI_CreateCompent( frmReward, LABELEX_TYPE, "labTitle", 400, 150, 10, 7 ) UI_SetCaption( labTitle, "\197\230\229\228\237\229\226\237\224\255 \237\224\227\240\224\228\224!") UI_SetTextColor( labTitle, COLOR_WHITE ) -- Reward button btnGetReward = UI_CreateCompent( frmReward, BUTTON_TYPE, "btnGetReward", 67, 24, 150, 120 ) UI_LoadButtonImage( btnGetReward, "texture/mod/pkodev.mod.reward/main.png", 67, 24, 0, 158, TRUE ) -- Close button btnClose = UI_CreateCompent( frmReward, BUTTON_TYPE, "btnClose", 21, 21, 343, 2 ) UI_LoadButtonImage( btnClose, "texture/mod/pkodev.mod.reward/buttons.tga", 21, 21, 270, 0, TRUE ) UI_SetButtonModalResult( btnClose, BUTTON_CLOSE ) -- Item slots cmdItemSlot0 = UI_CreateCompent( frmReward, COMMAND_ONE_TYPE, "cmdItemSlot0", 32, 32, 20, 73 ) UI_SetIsDrag( cmdItemSlot0, FALSE ) cmdItemSlot1 = UI_CreateCompent( frmReward, COMMAND_ONE_TYPE, "cmdItemSlot1", 32, 32, 69, 73 ) UI_SetIsDrag( cmdItemSlot1, FALSE ) cmdItemSlot2 = UI_CreateCompent( frmReward, COMMAND_ONE_TYPE, "cmdItemSlot2", 32, 32, 118, 73 ) UI_SetIsDrag( cmdItemSlot2, FALSE ) cmdItemSlot3 = UI_CreateCompent( frmReward, COMMAND_ONE_TYPE, "cmdItemSlot3", 32, 32, 167, 73 ) UI_SetIsDrag( cmdItemSlot3, FALSE ) cmdItemSlot4 = UI_CreateCompent( frmReward, COMMAND_ONE_TYPE, "cmdItemSlot4", 32, 32, 216, 73 ) UI_SetIsDrag( cmdItemSlot4, FALSE ) cmdItemSlot5 = UI_CreateCompent( frmReward, COMMAND_ONE_TYPE, "cmdItemSlot5", 32, 32, 265, 73 ) UI_SetIsDrag( cmdItemSlot5, FALSE ) cmdItemSlot6 = UI_CreateCompent( frmReward, COMMAND_ONE_TYPE, "cmdItemSlot6", 32, 32, 314, 73 ) UI_SetIsDrag( cmdItemSlot6, FALSE ) ---------------------------------------------------------------------------------------------------- Настройка мода 1) В функции GetRewardArray(role) запишите код, который будет генерировать цепочку наград для персонажа role на следующие семь дней. Функция должна вернуть таблицу из 7 элементов с полями id и number, где id - это ID предмета, который выдается в качестве награды, а number - количество предметов. Каждый элемент соответствует своему дню (1-й элемент - первый день, 2-ой элемент - второй день и так далее). Пример: function GetRewardArray(role) local items = { -- День 1: Яблоко x 20 {id = 1847, number = 20}, -- День 2: Хлеб x 40 {id = 1848, number = 40}, -- День 3: Кекс x 60 {id = 1849, number = 60}, -- День 4: Монета феи x 55 {id = 855, number = 55}, -- День 5: Питание для феи x 15 {id = 227, number = 15}, -- День 6: Хлеб x 99 {id = 1848, number = 99}, -- День 7: Кекс x 99 {id = 1849, number = 99} } return items end ID предметов и их количество можно генерировать случайным образом или в зависимости от расы персонажа, его профессии и тому подобного. 2) По умолчанию период награды составляет 24 часа. Вы можете изменить это значение в исходном коде серверной части мода (проект pkodev.mod.reward.server, файл structure.h), после чего скомпилируйте проект: // Reward interval in seconds static const unsigned int interval{ 24 * 60 * 60 }; // 24 hours 3) Настройка на стороне клиента не требуется. Старая версия GUI (большое спасибо пользователю @Masuka00!) Скачать текстуру В main.clu нужно записать новый код для кнопки "Apply": -- Close button btnClose = UI_CreateCompent( frmReward, BUTTON_TYPE, "btnClose", 14, 14, 342, 4 ) UI_LoadButtonImage( btnClose, "texture/mods/pkodev.mod.reward/main.png", 14, 14, 271, 174, TRUE ) UI_SetButtonModalResult( btnClose, BUTTON_CLOSE ) Скачать 1) Бинарные файлы мода (.dll); 2) Исходный код мода для Visual Studio 2019 Community (C++). Если Вы столкнулись с какой-либо проблемой, багом или у Вас возникли вопросы, то пишите в данной теме.
  6. Программа для сжатия .map файлов При работе с редактором карт YAMMI может возникнуть проблема, которая заключается в том, что выходной файл .map будет очень большого размера. Например, если открыть в YAMMI карту darkblue.map (Великий Синий Океан) и сохранить её на диск, то размер карты будет порядка 240 Мб, вместо изначальных 46 Мб! Это связано с тем, что большую часть карты darkblue занимает море, т.е. по сути одинаковые клетки, которые друг от друга ничем не отличаются, и такие клетки необязательно записывать в .map файл - игровой клиент автоматически заменит их на воду при отрисовке, но YAMMI не использует эту оптимизацию и все равно записывает "пустые" клетки в выходной .map файл. Данная программа решает описанную выше проблему и позволяет существенно уменьшить размер .map файлов на диске после их редактирования в YAMMI. Для этого она ищет в .map файле "пустые" клетки и удаляет их из файла. Скачать 1) Программа (pkodev.tool.mapcompressor.exe); 2) Исходный код (C++). Программа консольная, поэтому пути до исходного и выходного .map файлов передаются через параметры запуска: > pkodev.tool.mapcompressor darkblue.map darkblue_c.map darkblue.map - это несжатый .map файл, который требуется уменьшить; darkblue_c.map - это сжатый .map файл после обработки программой. Вывод программы будет примерно следующий: PKOdev.NET .map file compressor program Version: v1.0.0 (03/01/2022) Author: V3ct0r Input .map file: darkblue.map Output .map file: darkblue_c.map Input .map file information: * Width: 4096 * Height: 4096 * Section width: 8 * Section height: 8 * Sections number: 262144 Please wait . . . Done! * Sections compressed: 222007 * Percentage: 84.69% * Bytes freed: 213126720 Как видно из вывода, размер .map файла был уменьшен примерно на 203 Мб! Внимание! На данный момент программа еще не была протестирована должным образом, поэтому после сжатия на картах могут возникать те или иные ошибки. Учитывайте это при работе и храните резервные копии исходных .map файлов.
  7. Программа для просмотра информации о Game.exe С помощью данной программы Вы можете просматривать и редактировать информацию исполняемого файла игрового клиента (Game.exe), необходимую для его запуска и подключения к серверу: 1) Параметр запуска ("startgame") Game.exe; 2) Сетевой TCP-порт сервера; 3) Версию игры, которая передается в пакете аутентификации при подключении к серверу; 4) Идентификатор исполняемого файла игры в системе PKOdev.NET mod loader и время сборки (build timestamp) из COFF-заголовка (только чтение). Поддерживаются только Game.exe версии 1.3x. Так же можно просматривать время сборки и MD5-хэш любого исполняемого .exe файла. Скачать
  8. [Мод] Изменение размера персонажей Данный мод позволяет редактировать масштаб персонажей (см. скриншот выше). Требования Установленный Загрузчик модов для сервера и клиента (PKOdev.NET mod loader). Информация о моде Название: pkodev.mod.mobsize; Версия: 1.0; Авторы: @VItal13, V3ct0r; Тип: для клиента (Game.exe); Поддерживаемые исполняемые .exe файлы: GAME_13X_0, GAME_13X_1, GAME_13X_2, GAME_13X_3, GAME_13X_4 и GAME_13X_5. Установка 1) В директории "mods" Вашего клиента создайте папку "pkodev.mod.mobsize"; 2) Поместите в неё файл DLL-библиотеки мода "pkodev.mod.mobsize.client.13x_<x>.dll" для Вашей версии Game.exe. 3) Поместите в неё файл настроек мода "pkodev.mod.mobsize.cfg" и запишите в него список масштабов* персонажей в следующем формате: <ID монстра>{<Масштаб X>;<Масштаб Y>;<Масштаб Z>} Например, для "Лесного духа" ID 103: 103{2.5;2.5;2.5} * Каждый новый персонаж записывается с новой строки. Скачать 1) Бинарные файлы мода (.dll); 2) Исходный код мода для Visual Studio 2019 Community (C++). Если Вы столкнулись с какой-либо проблемой, багом или у Вас возникли вопросы, то пишите в данной теме.
  9. [Мод] Редактирование лимитов .txt таблиц С помощью данного мода для системы "PKODev.NET mod loader" можно легко редактировать лимиты для .txt/.bin файлов клиента и сервера без необходимости редактирования Game.exe и GameServer.exe соответственно в HEX-редакторе. Лимиты редактируются в текстовом файле pkodev.mod.tablelimit.cfg: areaset = 300 character_lvup = 120 characterinfo = 2500 forgeitem = 12 hairs = 500 int_cha_item = 32 iteminfo = 6000 lifelvup = 1000 saillvup = 1000 shipinfo = 120 shipiteminfo = 500 skilleff = 240 skillinfo = 500 characterposeinfo = 100 chaticons = 100 elfskillinfo = 100 eventsound = 30 itempre = 100 itemrefineeffectinfo = 5000 itemrefineinfo = 20000 itemtype = 100 magicgroupinfo = 10 magicsingleinfo = 100 mapinfo = 100 musicinfo = 500 notifyset = 100 objevent = 10 resourceinfo = 3000 sceneffectinfo = 14000 sceneobjinfo = 800 selectcha = 60 serverset = 100 shadeinfo = 14000 stoneinfo = 100 terraininfo = 100 Необязательно перечислять все таблицы, если требуется отредактировать лимиты только некоторых: iteminfo = 12000 characterinfo = 6000 mapinfo = 500 Таблицы GameServer.exe (13) Таблицы Game.exe (31) Требования Установленный Загрузчик модов для сервера и клиента (PKOdev.NET mod loader). Информация о моде Название: pkodev.mod.tablelimit; Версия: 1.0; Автор: V3ct0r; Тип: для клиента и сервера (Game.exe и GameServer.exe); Поддерживаемые исполняемые .exe файлы: GAME_13X_0, GAME_13X_1, GAME_13X_2, GAME_13X_3, GAME_13X_4, GAME_13X_5, GAMESERVER_136 и GAMESERVER_138. Установка 1) В директории "mods" Вашего сервера или клиента создайте папку "pkodev.mod.tablelimit"; 2) Поместите в неё файл DLL-библиотеки мода "pkodev.mod.tablelimit.<client/server>.<x>.dll" для Вашей версии Game.exe или GameServer.exe; 3) Поместите в неё файл настроек мода "pkodev.mod.tablelimit.cfg"; 4) Отредактируйте файл "pkodev.mod.tablelimit.cfg" по своему усмотрению - укажите требуемые значения лимитов для каждого файла .txt/.bin таблиц: <Название таблицы> = <Значение лимита> Скачать 1) Бинарные файлы мода (.dll); 2) Исходный код мода для Visual Studio 2019 Community (C++). Если Вы столкнулись с какой-либо проблемой, багом или у Вас возникли вопросы, то пишите в данной теме.
  10. [Мод] Время сервера Мод добавляет в игру текстовую метку с часами - текущее время сервера. Время сервера берется из пакета ID: 940, который сервер отправляет клиенту при подключении, например: [01-17 10:44:47:879] Метка с часами привязывается к форме миникарты "frmMinimap" из файла GUI-скриптов "\scripts\lua\forms\minimap.clu". Требования Установленный Загрузчик модов для сервера и клиента (PKOdev.NET mod loader). Информация о моде Название: pkodev.mod.clock; Версия: 1.0; Автор: V3ct0r; Тип: для клиента (Game.exe); Поддерживаемые исполняемые .exe файлы: GAME_13X_0, GAME_13X_1, GAME_13X_2, GAME_13X_3, GAME_13X_4 иGAME_13X_5). Установка 1) В директории "mods" Вашего клиента создайте папку "pkodev.mod.clock"; 2) Поместите в неё файл DLL-библиотеки мода "pkodev.mod.clock.client.13x_<x>.dll" для Вашей версии Game.exe. 3) Поместите в неё файл настроек мода "pkodev.mod.clock.cfg" и запишите в него желаемый формат вывода времени сервера в соответствии с документацией на функцию strftime(). Например, формат: Время сервера: %H:%M:%S %d.%m.%y Может дать следующий вывод: Время сервера: 10:51:20 17.01.2022 4) В файл GUI-скриптов "\scripts\lua\forms\minimap.clu" добавьте код для текстовой метки "labClock", которая будет отвечать за вывод времени сервера: ------------------------------------------------------------------------------------------ -- Clock label ------------------------------------------------------------------------------------------ labClock = UI_CreateCompent(frmMinimap, LABELEX_TYPE, "labClock", 20, 15, 20, 220) UI_SetCaption(labClock, "Clock") UI_SetTextColor(labClock, COLOR_WHITE) UI_SetLabelExFont(labClock, DEFAULT_FONT, TRUE, COLOR_BLACK) ------------------------------------------------------------------------------------------ Скачать 1) Бинарные файлы мода (.dll); 2) Исходный код мода для Visual Studio 2019 Community (C++). Если Вы столкнулись с какой-либо проблемой, багом или у Вас возникли вопросы, то пишите в данной теме.
  11. [Мод] Система контрактов Данная система представляет собой импровизированный квест типа "Охота на монстров", целью которого является убийство некоторого числа определенных монстров. Игроку выдается специальный предмет - "Контракт", в котором написано на какого монстра необходимо охотиться. Так же в нем записывается число монстров и текущий прогресс. После убийства необходимого числа монстров контракт считается выполненным, а игрок получает награду. Некоторые особенности системы: 1) Тип предмета для контракта должен быть 99. Для предмета также выбирается уникальный ID; 2) Контракт можно подобрать, выбросить, передать другому игроку, положить в банк или продать; 3) Для получения награды после завершения контракта, игрок должен использовать предмет контракта двойным кликом. Если контракт не был завершен, то игрок увидит соответствующее сообщение в систему; 4) Состав и количество награды определяется администратором в специальной функции в скрипте системы; 5) Если у игрока в инвентаре несколько контрактов на убийство одного и того же монстра, то при убийстве данного монстра тот или иной контракт выбирается случайным образом. Установка Все необходимые файлы и скрипты можно скачать в конце темы. Сервер 1) Добавьте в файл ItemInfo.txt предмет для контракта: XXXX Contract n0184 10130005 0 0 0 0 0 00 99 0 0 0 0 0 1 1 1 1 1 1 0 -1 0 -1 0 0 -1 -1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0,0 0,0 0,0 0,0 0,0 0,0 0,0 0,0 0,0 0,0 0,0 0,0 0,0 0,0 0,0 0,0 0,0 0,0 0,0 0,0 0,0 0,0 0 10,10 0,0 0 0 0 0 0 0 0 0 0 ItemUse_PKOdevContract 0 0 0 0 0 0 After completion you will receive a reward! где XXXX - любой незанятый ID. 2) Создайте файл с названием "pkodev.contract.lua" в директории "GameServer\resource\script\calculate\mods"; 3) Поместите в данный файл следующий код: -------------------------------------------------------------- -- The contract system script -- -- Author: V3ct0r from PKOdev.NET -- Version: 1.0 (01/12/2022) -- -- How to install the system: -- 1) Put this file to '\GameServer\resource\script\calculate\mods' folder -- 2) Put the following line at the beginning of 'SkillEffect.lua' file: -- dofile(GetResPath("script\\calculate\\mods\\pkodev.contract.lua")) -- 3) Add the contract item in the ItemInfo.txt file -- XXXX Contract n0184 10130005 0 0 0 0 0 00 99 0 0 0 0 0 1 1 1 1 1 1 0 -1 0 -1 0 0 -1 -1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0,0 0,0 0,0 0,0 0,0 0,0 0,0 0,0 0,0 0,0 0,0 0,0 0,0 0,0 0,0 0,0 0,0 0,0 0,0 0,0 0,0 0,0 0 10,10 0,0 0 0 0 0 0 0 0 0 0 ItemUse_PKOdevContract 0 0 0 0 0 0 Upon completion, you are entitled to a reward -- 4) Specify the item ID in 'contract.conf.item_id' table below: -- item_id = XXXX -- 5) Write the code for issuing a reward for completing a contract in the 'contract.conf.reward_cb' function -- 6) To create a new contract use the function 'contract.create': -- local <result (0 or 1)>, <item_descriptor>, <slot (from 0 to bag_size - 1)> -- = contract.create(<character_descriptor>, <monster_id>, <monster_number>) -- For example: -- local ret, item, slot = contract.create(role, 103, 7) -- 7) Done! -------------------------------------------------------------- -- Print a log print("Loading pkodev.contract.lua") -- The contract system contract = contract or {} --------------------------------------- -- Settings --------------------------------------- contract.conf = { -- Contract item ID item_id = XXXX, -- User-defined function for reward reward_cb = function(role, item) -- Give 1,000 gold AddMoney (role, 0, 1000) -- Give an random item local arr = { -- Refining Gem x 1 {id = 885, count = 1}, -- or Gem of Rage x 2 {id = 863, count = 2}, -- or Cake x 60 {id = 1849, count = 60}, -- or Fairy of Luck x 1 {id = 231, count = 1} } local r = math.random(1, table.getn(arr)) GiveItem(role, 0, arr[r].id , arr[r].count, 4) -- Launch fireworks PlayEffect(role, 361) end } --------------------------------------- -- Constants --------------------------------------- contract.const = { item_type = 99, -- Contract item type target_id = ITEMATTR_VAL_STR, -- Item attribute ID with the ID of target monster target_max = ITEMATTR_VAL_AGI, -- Item attribute ID with the total amount of monsters to hunt target_cur = ITEMATTR_VAL_DEX -- Item attribute ID with the total amount of monsters already hunted } --------------------------------------- -- Hooks --------------------------------------- -- Adding an item to inventory event contract.Creat_Item__original = Creat_Item Creat_Item = function(item, item_type, item_lv, item_event) -- Check the item type if ( item_type == contract.const['item_type'] ) then -- Reset the previous attrbiutes Reset_item_add() -- Add new attributes to the item Add_Item_Attr(contract.const['target_id'], 0) Add_Item_Attr(contract.const['target_max'], 0) Add_Item_Attr(contract.const['target_cur'], 0) return item_add.cnt, item_add.attr[1][1], item_add.attr[1][2], item_add.attr[2][1], item_add.attr[2][2], item_add.attr[3][1], item_add.attr[3][2], item_add.attr[4][1], item_add.attr[4][2], item_add.attr[5][1], item_add.attr[5][2], item_add.attr[6][1], item_add.attr[6][2], item_add.attr[7][1], item_add.attr[7][2] end -- Call the original function Creat_Item(item, item_type, item_lv, item_event) return contract.Creat_Item__original(item, item_type, item_lv, item_event) end -- Player killed monster event contract.GetExp_PKM__original = GetExp_PKM GetExp_PKM = function(monster, role) -- Call the original function GetExp_PKM(dead, atk) contract.GetExp_PKM__original(monster, role) -- Get the main character's descriptor role = TurnToCha(role) -- Number of contracts in the player's bag local ret = CheckBagItem(role, contract.conf['item_id']) -- Check that player has contracts if ( ret > 0 ) then -- Monster ID local id = GetChaTypeID(monster) -- List of contracts in the bag local arr = {} local k = 0 -- Build the list of contracts for i = 0, ( GetKbCap(role) - 1 ), 1 do -- Get the item descriptor local item = GetChaItem(role, 2, i) -- Check the item ID if ( GetItemID(item) == contract.conf['item_id'] ) then -- Get the monster ID from contract local target_id = GetItemAttr(item, contract.const['target_id']) -- Check the monster ID if ( id == target_id ) then -- Get amount of monsters to hunt local target_cur = GetItemAttr(item, contract.const['target_cur']) local target_max = GetItemAttr(item, contract.const['target_max']) -- Check that the contract is not completed if ( target_cur < target_max ) then -- Add the item to the list k = k + 1 arr[k] = { item_ = item, cur_ = target_cur, max_ = target_max } end end end end -- Check that matching contracts have been found if ( k > 0 ) then -- Randomly select a contract local r = math.random(1, k) -- Increase the number of hunted monsters arr[r].cur_ = arr[r].cur_ + 1 -- Update amount of hunted monsters SetItemAttr(arr[r].item_, contract.const['target_cur'], arr[r].cur_) -- Synchronize the bag SynChaKitbag(role, 13) -- Check that the contract is not completed if ( arr[r].cur_ < arr[r].max_ ) then -- Write a message BickerNotice( role, string.format( "Contract: Remaining '%s' to hunt: %d / %d!", GetMonsterName(id), arr[r].cur_, arr[r].max_ ) ) else -- Write a message BickerNotice( role, string.format( "Contract: All '%s' are killed! The contract is completed.", GetMonsterName(id) ) ) end end end end --------------------------------------- -- Useful functions --------------------------------------- -- Create a contract contract.create = function(role, target_id, number) -- Get the main character's descriptor role = TurnToCha(role) -- Check that the bag is not locked if ( KitbagLock(role, 0) == LUA_FALSE ) then -- Error LG("pkodev.contract", "Can't create the contract item (id:", contract.conf['item_id'], ") because the bag is locked!") return LUA_FALSE, nil, 0 end -- Check that the bag has one free slot if ( GetChaFreeBagGridNum(role) == 0 ) then -- Error LG("pkodev.contract", "Can't create the contract item (id:", contract.conf['item_id'], ") because there are no free slots in the bag!") return LUA_FALSE, nil, 0 end -- Create an item local r1, r2 = MakeItem(role, contract.conf['item_id'], 1, 4) -- Check the result if ( r1 == 0 ) then -- Error LG("pkodev.contract", "Can't create the contract item (id:", contract.conf['item_id'], ")!") return LUA_FALSE, nil, 0 end -- Get the item descriptor local item = GetChaItem(role, 2, r2) -- Set contract data local a1 = SetItemAttr(item, contract.const['target_id'], target_id) local a2 = SetItemAttr(item, contract.const['target_max'], number) local a3 = SetItemAttr(item, contract.const['target_cur'], 0) -- Check that the data is set if ( (a1 == 0) or (a2 == 0) or (a3 == 0) ) then -- Error LG("pkodev.contract", "Can't set the contract data! a1 = ", a1, ", a2 = ", a2, ", a3 = ", a3) return LUA_FALSE, item, r2 end -- Synchronize the kitbag SynChaKitbag(role, 13) -- Write a message to the player SystemNotice(role, string.format("You received a monster hunt contract [%s] x %d!", GetMonsterName(target_id), number)) -- The contract is successfully created! return LUA_TRUE, item, r2 end -- Contract item use event ItemUse_PKOdevContract = function(role, item) -- Get the main character's descriptor role = TurnToCha(role) -- Get contract data local target_id = GetItemAttr(item, contract.const['target_id']) local target_max = GetItemAttr(item, contract.const['target_max']) local target_cur = GetItemAttr(item, contract.const['target_cur']) -- Check that the contract is not completed if ( target_cur < target_max ) then -- Print a message SystemNotice( role, string.format("You have to kill [%s] x %d more to complete this contract!", GetMonsterName(target_id), (target_max - target_cur) ) ) -- Cancel the item usage UseItemFailed(role) else -- Print a message SystemNotice(role, "You have successfully completed the contract, congratulations!") -- Call user-defined reward function if ( contract.conf['reward_cb'] ~= nil ) then contract.conf['reward_cb'](role, item) end end end 5) Запишите в скрипт системы ID предмета контракта из ItemInfo.txt: contract.conf = { -- Contract item ID item_id = XXXX, . . . 6) Запишите в функцию reward_cb() код для выдачи награды за выполнение контракта: -- User-defined function for reward reward_cb = function(role, item) -- Give 1,000 gold AddMoney (role, 0, 1000) -- Give an random item local arr = { -- Refining Gem x 1 {id = 885, count = 1}, -- or Gem of Rage x 2 {id = 863, count = 2}, -- or Cake x 60 {id = 1849, count = 60}, -- or Fairy of Luck x 1 {id = 231, count = 1} } local r = math.random(1, table.getn(arr)) GiveItem(role, 0, arr[r].id , arr[r].count, 4) -- Launch fireworks PlayEffect(role, 361) end 7) Откройте файл "GameServer\resource\script\calculate\SkillEffect.lua" и в самом начале запишите строку: dofile(GetResPath("script\\calculate\\mods\\pkodev.contract.lua")) Клиент 1) Установите загрузчик модов PKOdev.NET mod loader; 2) Поместите файл DLL-библиотеки мода "pkodev.mod.contract.client.13x_<ID>.dll" для Вашей версии Game.exe в папку "mods" игрового клиента; 3) Добавьте в файл ItemInfo.txt предмет для контракта (см. пункт 1 инструкции по установке системы на сервер). Создание и выдача контрактов Каждый контракт должен быть создан только с использованием функции contract.create(). Использовать функции GiveItem(), MakeItem(), либо GM-команду &make и другие способы создания предметов не допускается. Синтаксис: local <Результат LUA_TRUE|LUA_FALSE>, <Дескриптор предмета>, <Ячейка предмета> = contract.create(<Дескриптор персонажа>, <ID монстра>, <Число монстров>) Пример: local ret, item, pos = contract.create(role, 103, 7) В результате будет создан контракт на убийство семи "Лесных духов" как на изображении из шапки темы. Выдавать контракты можно, например, через специального NPC или с помощью другого предмета. Скачать 1) Бинарные файлы мода (.dll); 2) Исходный код мода для Visual Studio 2019 Community (C++). Если Вы столкнулись с какой-либо проблемой, багом или у Вас возникли вопросы, то пишите в данной теме.
  12. Архив полезных файлов для сервера и клиента В данном архиве содержится много полезных файлов, которые могут Вам пригодится: Сборки серверов; Базы данных; Клиенты; Карты; Скрипты; Утилиты и вспомогательные программы; Веб-обвязки; Аппарели; и т.д. Архив был создан пользователем @Lucky, за что ему большое спасибо. Также спасибо @Foxseiz за обновление архива. Вход в архив
  13. Официальные клиенты Особая благодарность пользователю alex1999! В данной теме собираются официальные клиенты пиратии. Если у Вас имеются таковые, то присылайте нам ссылку на них и мы опубликуем её здесь! Русский официальный сервер (Пиратия) Piratia_Setup.exe - установщик клиента Пиратии версии 1.35, тот самый с знаменитого диска игромании. Piratia_Setup.exe - установщик клиента Пиратии версии 1.38.1 (спасибо ϟAlсаtrаzϟ). Piratia_Setup.exe - установщик клиента Пиратии версии 1.39 (спасибо Ginetik). Piratia2_Setup.exe - установщик клиента Пиратии версии 2.0+. Последний ехешник от майлов. Пиратия II Online.zip - архив c клиентом Пиратии версии 2.0+ из предыдущего пункта, но еще и с всеми последующими скачиваемыми патчами. Tales of Pirates top2_setup_1.0.70.exe - установщик клиента Tales of Pirates II. Последний ехешник от IGG. Pirate King Online PKOII.zip - архив с клиентом PKO версии 2.0+. Какой-то страшный архив с пко-клиентом, взят откуда-то из инета. Однако полностью совместим с гулящими в паблике файлами 2.5, работает фишка с просмотром экипировки другого игрока и т.д., чем и ценен. XHDW XHDW_3.0.1_Setup.exe - установщик клиента XHDW версии 3.0+. Сам установщик какой-то битый и не устанавливается до конца привычным способом, однако вскрывается простым 7-зипом, после чего совершенно безвозмездно отдает все свои ресурсы.
  14. [Мод] 60 кадров в секунду (60 FPS) Данный мод увеличивает скорость отрисовки графики игровым клиентом с 30 до 60 кадров в секунду. У мода есть несколько проблем: 1) При быстром беге персонажа игрока может отбрасывать назад; 2) При быстром беге могут не успевать прогружаться карта, NPC, монстры и игроки; 3) Анимации персонажей и объектов проигрываются слишком быстро. Требования Установленный Загрузчик модов для сервера и клиента (PKOdev.NET mod loader). Информация о моде Название: pkodev.mod.60fps; Версия: 1.0; Автор: V3ct0r, BotPRO; Тип: для клиента (Game.exe); Поддерживаемые исполняемые .exe файлы: GAME_13X_0, GAME_13X_1, GAME_13X_2, GAME_13X_3, GAME_13X_4, GAME_13X_5. Установка 1) В директории "mods" игрового клиента создайте папку "pkodev.mod.60fps"; 2) Поместите файл DLL-библиотеки мода "pkodev.mod.60fps.client.13x_<ID>.dll" для Вашей версии Game.exe в папку "mods\pkodev.mod.60fps" игрового клиента; 3) Поместите файл DLL-библиотеки мода "pkodev.mod.60fps.impl_<ID>.dll" для Вашей версии Game.exe в папку "mods\pkodev.mod.60fps\impl" игрового клиента. Скачать 1) Бинарные файлы мода (.dll); 2) Исходный код мода для Visual Studio 2019 Community (C++). Если Вы столкнулись с какой-либо проблемой, багом или у Вас возникли вопросы, то пишите в данной теме.
  15. [Мод] Эффект полета для крыльев Мод позволяет добавлять к любым крыльям (предметам с типом 44) эффект полета. Требования Установленный Загрузчик модов для сервера и клиента (PKOdev.NET mod loader). Информация о моде Название: pkodev.mod.wings; Версия: 1.0; Автор: V3ct0r; Тип: для клиента (Game.exe); Поддерживаемые исполняемые .exe файлы: GAME_13X_0, GAME_13X_1, GAME_13X_2, GAME_13X_3, GAME_13X_4 и GAME_13X_5. Установка 1) В директории "mods" Вашего клиента создайте папку "pkodev.mod.wings"; 2) Поместите в неё файл DLL-библиотеки мода "pkodev.mod.wings.client.13x_<x>.dll" для Вашей версии Game.exe. 3) Поместите в неё файл настроек мода "pkodev.mod.wings.cfg" и запишите в него список ID крыльев (из ItemInfo.txt) с эффектом полета. Каждый новый ID записывается с новой строки: 935 936 937 Скачать 1) Бинарные файлы мода (.dll); 2) Исходный код мода для Visual Studio 2019 Community (C++). Если Вы столкнулись с какой-либо проблемой, багом или у Вас возникли вопросы, то пишите в данной теме.
  16. [Мод] Медали (ожерелья) со званиями Модификация позволяет создавать медали (ожерелья) с различными званиями, которые отображаются в скобках перед именем персонажа (см. скриншот). Так же такие ожерелья позволяют менять цвет имен персонажей. Текст, цвет звания и цвет имени персонажей указываются в ItemInfo.txt для предметов с типом 25 (ожерелье). 1) Текст звания указывается в описании предмета. Максимальная длина звания составляет 15 символов. 2) Цвет звания в формате FFRRGGBB - вместо модели на Ланса в 5-ом поле. 3) Цвет имени персонажа в формате FFRRGGBB - вместо модели на Карциза в 6-ом поле. Примеры медалей со званиями: XXXX Medal 1 (Red Admin) l0005 10130005 FFFF0000 0 0 0 0 0 25 0 0 0 0 0 1 1 1 1 1 1 32 -1 1 -1 0 0 5 -1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0,0 0,0 0,0 0,0 0,0 0,0 0,0 0,0 0,0 0,0 0,0 0,0 0,0 0,0 0,0 0,0 0,0 0,0 0,0 0,0 0,0 0,0 0 0,1000 10000,10000 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 Admin XXXX Medal 2 (Green maindev) l0005 10130005 FF00FF00 0 0 0 0 0 25 0 0 0 0 0 1 1 1 1 1 1 32 -1 1 -1 0 0 5 -1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0,0 0,0 0,0 0,0 0,0 0,0 0,0 0,0 0,0 0,0 0,0 0,0 0,0 0,0 0,0 0,0 0,0 0,0 0,0 0,0 0,0 0,0 0 0,1000 10000,10000 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 maindev XXXX Medal 3 (Blue PkoDEV) l0005 10130005 FF0000FF 0 0 0 0 0 25 0 0 0 0 0 1 1 1 1 1 1 32 -1 1 -1 0 0 5 -1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0,0 0,0 0,0 0,0 0,0 0,0 0,0 0,0 0,0 0,0 0,0 0,0 0,0 0,0 0,0 0,0 0,0 0,0 0,0 0,0 0,0 0,0 0 0,1000 10000,10000 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 PkoDEV Пример ожерелья со званием и цветным именем: XXXX Medal 2 l0005 10130005 FF00FF00 FFFF8000 0 0 0 0 25 0 0 0 0 0 1 1 1 1 1 1 32 -1 1 -1 0 0 5 -1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0,0 0,0 0,0 0,0 0,0 0,0 0,0 0,0 0,0 0,0 0,0 0,0 0,0 0,0 0,0 0,0 0,0 0,0 0,0 0,0 0,0 0,0 0 0,1000 10000,10000 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 PKOdev.NET Требования Установленный Загрузчик модов для сервера и клиента (PKOdev.NET mod loader). Информация о моде Название: pkodev.mod.title; Версия: 1.0; Автор: V3ct0r; Тип: для клиента (Game.exe); Поддерживаемые исполняемые .exe файлы: GAME_13X_0, GAME_13X_1, GAME_13X_2, GAME_13X_3, GAME_13X_4, GAME_13X_5. Установка 1) В директории "mods" Вашего клиента создайте папку "pkodev.mod.title"; 2) Поместите в неё файл DLL-библиотеки мода "pkodev.mod.title.13x_<ID>.dll" для Вашей версии Game.exe; 3) Добавьте в ItemInfo.txt сервера и клиента новые медали (ожерелья) со званиями в соответствии с примером из шапки темы. Скомпилируйте ItemInfo.txt для клиента. Скачать 1) Бинарные файлы мода (.dll); 2) Исходный код мода для Visual Studio 2019 Community (C++). Если Вы столкнулись с какой-либо проблемой, багом или у Вас возникли вопросы, то пишите в данной теме.
  17. [Мод] Отображение названия предмета в аппарели В описании предмета-аппарели появляется название экипировки, которая в нем находится. Требования Установленный Загрузчик модов для сервера и клиента (PKOdev.NET mod loader). Информация о моде Название: pkodev.mod.apparel; Версия: 1.0; Автор: V3ct0r; Тип: для клиента (Game.exe); Поддерживаемые исполняемые .exe файлы: GAME_13X_0, GAME_13X_1, GAME_13X_2, GAME_13X_3, GAME_13X_4 и GAME_13X_5. Установка Поместите файл DLL-библиотеки мода "pkodev.mod.apparel.client.13x_<ID>.dll" для Вашей версии Game.exe в папку "mods" игрового клиента. Скачать 1) Бинарные файлы мода (.dll); 2) Исходный код мода для Visual Studio 2019 Community (C++). Если Вы столкнулись с какой-либо проблемой, багом или у Вас возникли вопросы, то пишите в данной теме.
  18. [Мод] Отображение уровня предметов на иконках ("умные иконки") На иконках определенных предметов появляется некоторая информация: 1) Для предметов со вставленными самоцветами отображается уровень "заточки"; 2) Для самоцветов отображается их уровень; 3) Для фей отображается их уровень; 4) Для аппарелей отображается надпись "App" (от англ. "Apparel"); Требования Установленный Загрузчик модов для сервера и клиента (PKOdev.NET mod loader). Информация о моде Название: pkodev.mod.itemlv; Версия: 1.0; Автор: V3ct0r; Тип: для клиента (Game.exe); Поддерживаемые исполняемые .exe файлы: GAME_13X_0, GAME_13X_1, GAME_13X_2, GAME_13X_3, GAME_13X_4 и GAME_13X_5. Установка Поместите файл DLL-библиотеки мода "pkodev.mod.itemlv.client.13x_<ID>.dll" для Вашей версии Game.exe в папку "mods" игрового клиента. Скачать 1) Бинарные файлы мода (.dll); 2) Исходный код мода для Visual Studio 2019 Community (C++). Если Вы столкнулись с какой-либо проблемой, багом или у Вас возникли вопросы, то пишите в данной теме.
  19. [Мод] Система рейтинга игроков Данный мод реализует систему рейтинга игроков, которая позволяет игрокам сравнивать своих персонажей по какому-либо критерию в зависимости от того, как администратор настроит систему. Например, можно определить рейтинг как сумму всех базовых характеристик персонажа (см. скриншот выше), тогда с помощью рейтинга можно понять насколько силен персонаж относительно другого. Либо можно выводить в рейтинге количество убитых игроков или монстров. Так же можно выводить количество золота, очков репутации и тому подобное. Система очень гибкая и зависит от фантазии администратора. Рейтинг отображается над именем персонажей и выделяется цветом. После выхода персонажа из игры, рейтинг сохранятся в базе данных, таким образом, можно выводить рейтинг игроков на Вашем сайте. Требования Установленный Загрузчик модов для сервера и клиента (PKOdev.NET mod loader). Информация о моде Название: pkodev.mod.power; Версия: 1.1; Автор: V3ct0r; Тип: для клиента и сервера (Game.exe и GameServer.exe); Поддерживаемые исполняемые .exe файлы: GAME_13X_0, GAME_13X_1, GAME_13X_2, GAME_13X_3, GAME_13X_4, GAME_13X_5, GAMESERVER_136 и GAMESERVER_138. Обновление мода от 17.01.2022 + Исправлен баг, когда при убийстве монстра у персонажа игрока не обновлялось количество опыта (спасибо @Rewind и @Tera за обнаружение бага); + Формат вывода количества очков рейтинга вынесен в файл настроек pkodev.mod.power.cfg на стороне клиента: - [{:power:}] - Установка Сервер: 1) В директории "GameServer\mods" Вашего сервера создайте папку "pkodev.mod.power"; 2) Поместите в неё файл DLL-библиотеки мода "pkodev.mod.power.server.13<x>.dll" для Вашей версии GameServer.exe; 3) В файл functions.lua ("GameServer\resource\script\calculate\") запишите следующий скрипт: -- Power system (pkodev.mod.power) -- Calculate player's character power amount function CalculatePower(role) -- Get some character attributes local str = GetChaAttr(role, ATTR_STR) local agi = GetChaAttr(role, ATTR_AGI) local con = GetChaAttr(role, ATTR_CON) local spr = GetChaAttr(role, ATTR_STA) local acc = GetChaAttr(role, ATTR_DEX) -- Power formula local formula = ( str + agi + con + spr + acc ) -- Return calculated power amount and color return formula, GetPowerColor(formula) end -- Power system (pkodev.mod.power) -- Get color of power value function GetPowerColor(power) -- Green color (0xFF00FF00) return 4278255360 end 4) В MSSQL Management Studio выполните SQL-запрос: USE GameDB ALTER TABLE character ADD power INT NOT NULL DEFAULT (0) Клиент: 1) В директории "mods" Вашего клиента создайте папку "pkodev.mod.power"; 2) Поместите в неё файл DLL-библиотеки мода "pkodev.mod.power.client.13x_<x>.dll" для Вашей версии Game.exe. 3) Поместите в неё файл настроек мода "pkodev.mod.power.cfg" и запишите в него желаемый формат вывода количества очков рейтинга персонажей (маркер {:power:}), например: - [{:power:}] - Настройка мода 1) В файле functions.lua, в функции CalculatePower(role) запишите код, который будет вычислять рейтинг персонажа игрока. На вход функции подается переменная role - дескриптор текущего персонажа. На выходе функция должна вернуть рейтинг в виде целого числа. В примере выше, скрипт вычисляет рейтинг как сумму базовых характеристик персонажа; 2) В файле functions.lua, в функции GetPowerColor(power), запишите код, который будет определять цвет рейтинга в зависимости от его числа - power. Например, можно сделать, чтобы рейтинг менее 50 выделялся желтым цветом, от 50 до 100 - зеленым, выше 100 - красным. Цвет необходимо записывать в формате 0xFFRRGGBB, в десятичной системе счисления. Пример: зеленый цвет = 0xFF00FF00, переводим в десятичную ССч и получим число 4278255360, его и нужно записать в скрипт; 3) Мод предусматривает сохранение рейтинга персонажа в базе данных после выхода из игры. Например, для вывода на сайте в различных ТОПах. Если Вам не нужна эта возможность, её можно отключить. Для этого пропустите пункт 4 раздела "Установка - Сервер" и закомментируйте следующие строки в исходном коде серверной части мода (проект pkodev.mod.power.server, файл dllmain.cpp, функции Start() и Stop()), после чего скомпилируйте проект: DetourAttach(&(PVOID&)pkodev::pointer::CTableCha__SaveAllData, pkodev::hook::CTableCha__SaveAllData); и DetourDetach(&(PVOID&)pkodev::pointer::CTableCha__SaveAllData, pkodev::hook::CTableCha__SaveAllData); 4) Чтобы получить рейтинг персонажа из базы данных, выполните SQL-запрос: SELECT power FROM GameDB.dbo.character WHERE cha_name = '<Имя персонажа>' 5) Настройка на стороне клиента не требуется. Скачать 1) Бинарные файлы мода (.dll); 2) Исходный код мода для Visual Studio 2019 Community (C++). Если Вы столкнулись с какой-либо проблемой, багом или у Вас возникли вопросы, то пишите в данной теме.
  20. [Мод] Социальные кнопки (Discord, Youtube, Twitch и др.) Мод позволяет добавить в игру социальные кнопки, нажимая на которые игрок будет направлен на соответствующий ресурс в сети Интернет по указанной в настройках мода ссылке, например, на сервер Discord, на канал Youtube, в группу ВКонтакте. Кнопки привязываются к форме мини-карты ("frmMinimap"). Требования Установленный Загрузчик модов для сервера и клиента (PKOdev.NET mod loader). Информация о моде Название: pkodev.mod.social; Версия: 1.0; Автор: V3ct0r; Тип: для клиента (Game.exe); Поддерживаемые исполняемые .exe файлы: GAME_13X_0, GAME_13X_1, GAME_13X_2, GAME_13X_3, GAME_13X_4, GAME_13X_5. Установка 1) В директории "mods" Вашего клиента создайте папку "pkodev.mod.social"; 2) Поместите в неё файл DLL-библиотеки мода "pkodev.mod.social.13x_<ID>.dll" для Вашей версии Game.exe; 3) Поместите в неё файл настроек мода "pkodev.mod.social.cfg"; 4) В GUI-скриптах игрового клиента добавьте на форму мини-карты (форма "frmMinimap" из файла "minimap.clu") требуемые социальные кнопки, например: btnFacebook = UI_CreateCompent(frmMinimap, BUTTON_TYPE, "btnFacebook", 24, 24, 0, 180) UI_LoadButtonImage(btnFacebook, "texture/mods/pkodev.mod.social/social.png", 24, 24, 0, 0, FALSE ) btnDiscord = UI_CreateCompent(frmMinimap, BUTTON_TYPE, "btnDiscord", 24, 24, 28, 180) UI_LoadButtonImage(btnDiscord, "texture/mods/pkodev.mod.social/social.png", 24, 24, 24, 0, FALSE ) btnYoutube = UI_CreateCompent(frmMinimap, BUTTON_TYPE, "btnYoutube", 24, 24, 56, 180) UI_LoadButtonImage(btnYoutube, "texture/mods/pkodev.mod.social/social.png", 24, 24, 48, 0, FALSE ) btnTwitch = UI_CreateCompent(frmMinimap, BUTTON_TYPE, "btnTwitch", 24, 24, 84, 180) UI_LoadButtonImage(btnTwitch, "texture/mods/pkodev.mod.social/social.png", 24, 24, 72, 0, FALSE ) btnTwitter = UI_CreateCompent(frmMinimap, BUTTON_TYPE, "btnTwitter", 24, 24, 112, 180) UI_LoadButtonImage(btnTwitter, "texture/mods/pkodev.mod.social/social.png", 24, 24, 96, 0, FALSE ) 5) Добавьте в файл настроек мода "pkodev.mod.social.cfg" социальные кнопки в следующем формате: <название_кнопки> = <ссылка_на_ресурс> Для кнопок из примера выше: btnFacebook = https://facebook.com/ btnDiscord = https://discord.com/ btnYoutube = https://www.youtube.com/ btnTwitch = https://www.twitch.tv/ btnTwitter = https://twitter.com/ Скачать 1) Бинарные файлы мода (.dll); 2) Исходный код мода для Visual Studio 2019 Community (C++). Если Вы столкнулись с какой-либо проблемой, багом или у Вас возникли вопросы, то пишите в данной теме.
  21. [Гайд] Пример создания модификации: Вывод дополнительных характеристик персонажа Привет! В данной статье я расскажу как создать мод для клиента игры, который позволит выводить дополнительные характеристики персонажа на форме "Персонаж" (см. скриншот выше). Благодарю участника нашего форума @Graf за идею мода и гайда: Вам понадобится 1) Game.exe для которого будет создаваться модификация; 2) OllyDbg v1.10; 3) IDA Pro (необязательно, можно пользоваться только OllyDbg); 4) Visual Studio 2022 Community Edition и библиотека MS Detours; 5) Исходный код клиента; 6) Знание основ программирования на C/C++ и ассемблере. Навыки написания DLL-библиотек. Опыт работы с вышеуказанными программами. Создание мода В качестве примера реализуем вывод трех дополнительных характеристик: удача (ATTR_LUK ), шанс критического удара (ATTR_CRT ) и шанс дропа (ATTR_MF). 1) Поместим на форму с характеристиками (frmState) персонажа 3 текстовые метки: удача (labLukShow), шанс критического удара (labCriticalShow), шанс дропа (labMfShow). preperty.clu: -- Lucky labLukShow = UI_CreateCompent( frmState, LABELEX_TYPE, "labLukShow", 26, 8, 16, 370 ) UI_SetCaption( labLukShow, "L" ) UI_SetTextColor( labLukShow, COLOR_PURPLE ) UI_SetLabelExFont( labLukShow, DEFAULT_FONT, TRUE, COLOR_WHITE ) -- Critical chance labCriticalShow = UI_CreateCompent( frmState, LABELEX_TYPE, "labCriticalShow", 26, 8, 80, 370 ) UI_SetCaption( labCriticalShow, "C" ) UI_SetTextColor( labCriticalShow, COLOR_PURPLE ) UI_SetLabelExFont( labCriticalShow, DEFAULT_FONT, TRUE, COLOR_WHITE ) -- Drop chance labMfShow = UI_CreateCompent( frmState, LABELEX_TYPE, "labMfShow", 26, 8, 144, 370 ) UI_SetCaption( labMfShow, "M" ) UI_SetTextColor( labMfShow, COLOR_PURPLE ) UI_SetLabelExFont( labMfShow, DEFAULT_FONT, TRUE, COLOR_WHITE ) 2) Изучив исходный код клиента, находим функцию void CStateMgr::RefreshStateFrm(), в которой происходит обновление меток с характеристиками персонажа. Далее нам будет необходимо перехватывать её вызов и обновлять наши новые метки. Так же есть функция void CStateMgr::_evtMainShow(CGuiData *pSender), она вызывается при открытии формы характеристик персонажа и её можно использовать для получения указателей на объекты текстовых меток в памяти игры. Параметр pSender это указатель на форму frmState, объекта класса CCompent, у которого есть метод CCompent* CForm::Find(const char* str), этот метод понадобится для получения указателей на метки по их именам, указанных в lua скриптах GUI клиента. Чтобы установить текст меток, нам будет нужен метод void CLabel::SetCaption(const char * str). Наконец, для доступа к параметрам нашего персонажа, нам будет нужен указатель на персонажа, которым управляет игрок. 3) Для поиска адресов в Game.exe будем использовать программу IDA Pro. void CStateMgr::RefreshStateFrm(). Данный метод можно найти по какой-либо уникальной строке, например, "%4.2f%%". Ищем эту строку в IDA Pro и находим её использование только в одной функции по адресу 0x0047F190 - это и есть искомый метод. void CStateMgr::_evtMainShow(CGuiData *pSender). Это обработчик события открытия формы характеристик персонажа, значит он где-то "вешается" на объект в формы. Проверим в исходном коде клиента игры в методе инициализации формы frmState: bool CStateMgr::Init() { CFormMgr &mgr = CFormMgr::s_Mgr; frmState = _FindForm("frmState"); if( !frmState ) return false; frmState->evtShow = _evtMainShow; labStateName = dynamic_cast<CLabelEx*>(frmState->Find("labStateName")); if( !labStateName ) return Error( g_oLangRec.GetString(45), frmState->GetName(), "labStateName" ); labStateName->SetIsCenter(true); Теперь необходимо найти этот код в Game.exe. Для этого выполняем поиск по строке "frmState". В этот раз нам повезло меньше, найдено 3 использования такой строки: Смотрим первое использование: Рядом так же видно использование строк "btnState", "btnSkill", и "frmSkill". Но в искомом коде таких строк рядом нет. Очевидно, этот адрес нам не подходит. Смотрим второе использование: Строка находится в самом начале функции и рядом есть строка "labStateName". Судя по всему, это наш искомый метод инициализации. Здесь видно, как загружается указатель на форму frmState в регистр EAX, а далее по смещению 0x78, относительно адреса в регистре EAX, помещается какая-то функция. Наверняка, это и есть метод void CStateMgr::_evtMainShow(CGuiData *pSender). Итак, адрес метода void CStateMgr::_evtMainShow(CGuiData *pSender) - 0x0047F7F0. CCompent* CForm::Find(const char* str). Этот метод скорее всего находится в функции инициализации формы, такую мы уже видели: bool CStateMgr::Init(). Просмотрев исходный код, видим следующее: labStateName = dynamic_cast<CLabelEx*>(frmState->Find("labStateName")); if( !labStateName ) return Error( g_oLangRec.GetString(45), frmState->GetName(), "labStateName" ); labStateName->SetIsCenter(true); Это код получения указателя на метку labStateName, нам предстоит сделать то же самое с нашими новыми метками. Идем по адресу 0x0047F9F0 метода bool CStateMgr::Init() в IDA Pro и видим следующий код: .text:0047FA25 push offset aLabstatename ; "labStateName" .text:0047FA2A call dword ptr [eax+48h] Похоже на вызов метода CCompent* CForm::Find(const char* str) для получения указателя на метку labStateName, но его адрес не указан явно. Это говорит о том, что метод виртуальный. Проверим это в исходном коде: virtual CCompent* Find( const char* str ) { return _frmOwn->Find( str ); } Метод действительно является виртуальным. Как же получить его адрес? Как вариант, открыть Game.exe в отладчике, поставить точку останова на адрес 0x0047FA2A и проверить адрес вызываемой функции, но есть проблема - мы не можем запустить клиент напрямую через отладчик, а после запуска эта функция уже не вызывается. Есть второй вариант: поставить точку останова на метод void CStateMgr::_evtMainShow(CGuiData *pSender) (его адрес мы уже знаем), получить адрес формы frmState через параметр pSender, прибавить к нему смещение 0x48 и посмотреть адрес искомого метода. Идем в игру и открываем форму характеристик персонажа: На стеке смотрим адрес параметра pSender - 0x109D5568. По этому адресу находится адрес объекта CStateMgr - 0x006089B4. Прибавляем к этому адресу смещение 0x48, получаем адрес 0x006089FC и переходим по данному адресу в окне отображения памяти процесса: Итак, адрес метода CCompent* CForm::Find(const char* str) равен 0x004941F0. void CLabel::SetCaption(const char * str), в исходном коде вызов этого метода встретится в методе void CStateMgr::RefreshStateFrm(), например: if ( labStateEXP) { if (max!=0) sprintf( pszCha , "%4.2f%%" , num*100.0f/max ); else sprintf( pszCha , "0.00%"); labStateEXP->SetCaption( pszCha ); } Снова ищем строку "%4.2f%%" в IDA Pro и переходим по адресу её использования: Очевидно, что вызов неизвестной функции после двух вызовов библиотечной функции sprintf устанавливает текст метки labStateEXP. Функция является виртуальной, поэтому вновь открываем отладчик, ставим точку останова по адресу 0x0047F2A1 и открываем форму характеристик персонажа в игре: Отладчик подсказывает нам, что по адресу [EDX+3C] находится адрес метода void CLabel::SetCaption(const char * str) - 0x0042B1A0. Указатель на персонажа игрока можно посмотреть в том же методе void CStateMgr::RefreshStateFrm(): CForm * f = g_stUIState.frmState; if( !f->GetIsShow() ) return; CCharacter* pCha = g_stUIBoat.GetHuman(); if( !pCha ) return; SGameAttr* pCChaAttr = pCha->getGameAttr(); if (!pCChaAttr ) return; Переходим на начало метода в IDA Pro: Анализ ассемблерного листинга показывает, что указатель на персонажа игрока находится по адресу 0x00668B6C. Мы нашли все необходимые адреса: 0x0047F7F0 void CStateMgr::_evtMainShow(CGuiData *pSender) 0x0047F190 void CStateMgr::RefreshStateFrm() 0x004941F0 CCompent* CForm::Find(const char* str) 0x0042B1A0 void CLabel::SetCaption(const char * str) 0x00668B6C CCharacter* CBoatMgr::_pHuman 4) Все готово для создания DLL. В качестве языка программирования будем использовать C++. Создаем новый проект Dynamic-Link Library (DLL) в Visual Studio 2022 Community. Поскольку мы будем перехватывать вызовы void CStateMgr::_evtMainShow(CGuiData *pSender) и void CStateMgr::RefreshStateFrm(), то нам понадобится библиотека MS Detours, подключаем её к проекту. Записываем код DLL: #include <windows.h> #include <detours.h> #include <cstdio> namespace pkodev { // Addresses of imported functions from Game.exe namespace address { // void CStateMgr::_evtMainShow(CGuiData *pSender) const unsigned int CStateMgr___evtMainShow = 0x0047F7F0; // void CStateMgr::RefreshStateFrm() const unsigned int CStateMgr__RefreshStateFrm = 0x0047F190; // CCompent* CForm::Find( const char* str ) const unsigned int CForm__Find = 0x004941F0; // void CLabel::SetCaption( const char * str ) const unsigned int CLabel__SetCaption = 0x0042B1A0; // CCharacter* CBoatMgr::_pHuman const unsigned int CBoatMgr___pHuman = 0x00668B6C; } namespace pointer { // void CStateMgr::_evtMainShow(CGuiData *pSender) typedef void(__cdecl* CStateMgr___evtMainShow__Ptr)(void*); CStateMgr___evtMainShow__Ptr CStateMgr___evtMainShow = (CStateMgr___evtMainShow__Ptr)(void*)(address::CStateMgr___evtMainShow); // void CStateMgr::RefreshStateFrm() typedef void(__cdecl* CStateMgr__RefreshStateFrm__Ptr)(void*); CStateMgr__RefreshStateFrm__Ptr CStateMgr__RefreshStateFrm = (CStateMgr__RefreshStateFrm__Ptr)(void*)(address::CStateMgr__RefreshStateFrm); // CCompent* CForm::Find( const char* str ) typedef void* (__thiscall* CForm__Find__Ptr)(void*, const char*); CForm__Find__Ptr CForm__Find = (CForm__Find__Ptr)(void*)(address::CForm__Find); // void CLabel::SetCaption( const char * str ) typedef void (__thiscall* CLabel__SetCaption__Ptr)(void*, const char*); CLabel__SetCaption__Ptr CLabel__SetCaption = (CLabel__SetCaption__Ptr)(void*)(address::CLabel__SetCaption); } namespace hook { // void CStateMgr::_evtMainShow(CGuiData *pSender) void __cdecl CStateMgr___evtMainShow(void* pSender); // void CStateMgr::RefreshStateFrm() void __fastcall CStateMgr__RefreshStateFrm(void* This, void* NotUsed); } // Label "labLukShow" void* labLukShow = nullptr; // Label "labCriticalShow" void* labCriticalShow = nullptr; // Label "labMfShow" void* labMfShow = nullptr; } // Entry point BOOL APIENTRY DllMain( HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ) { switch (ul_reason_for_call) { // DLL attached to the proccess case DLL_PROCESS_ATTACH: // Enable hooks DetourRestoreAfterWith(); DetourTransactionBegin(); DetourUpdateThread(GetCurrentThread()); DetourAttach(&(PVOID&)pkodev::pointer::CStateMgr___evtMainShow, pkodev::hook::CStateMgr___evtMainShow); DetourAttach(&(PVOID&)pkodev::pointer::CStateMgr__RefreshStateFrm, pkodev::hook::CStateMgr__RefreshStateFrm); DetourTransactionCommit(); break; // DLL detached from the proccess case DLL_PROCESS_DETACH: // Disable hooks DetourTransactionBegin(); DetourUpdateThread(GetCurrentThread()); DetourDetach(&(PVOID&)pkodev::pointer::CStateMgr___evtMainShow, pkodev::hook::CStateMgr___evtMainShow); DetourDetach(&(PVOID&)pkodev::pointer::CStateMgr__RefreshStateFrm, pkodev::hook::CStateMgr__RefreshStateFrm); DetourTransactionCommit(); break; } return TRUE; } // void CStateMgr::_evtMainShow(CGuiData *pSender) void __cdecl pkodev::hook::CStateMgr___evtMainShow(void* pSender) { // Get pointers to the labels pkodev::labLukShow = pkodev::pointer::CForm__Find(pSender, "labLukShow"); pkodev::labCriticalShow = pkodev::pointer::CForm__Find(pSender, "labCriticalShow"); pkodev::labMfShow = pkodev::pointer::CForm__Find(pSender, "labMfShow"); // Call original CStateMgr___evtMainShow() function pkodev::pointer::CStateMgr___evtMainShow(pSender); } // void CStateMgr::RefreshStateFrm() void __fastcall pkodev::hook::CStateMgr__RefreshStateFrm(void* This, void* NotUsed) { // Call original function CStateMgr::RefreshStateFrm() pkodev::pointer::CStateMgr__RefreshStateFrm(This); // Get pointer to the main character // CCharacter* pCha = g_stUIBoat.GetHuman(); void* pCha = reinterpret_cast<void*>( *reinterpret_cast<unsigned int*>(pkodev::address::CBoatMgr___pHuman) ); if (pCha == nullptr) { // Exit from the hook return; } // Define ATTR constants const unsigned int ATTR_LUK = 30; const unsigned int ATTR_MF = 38; const unsigned int ATTR_CRT = 39; // Get offset to the attribute auto attr_get = [&pCha](unsigned int id) -> unsigned int { return *reinterpret_cast<unsigned int*>( (0xD0 + 4 * id + reinterpret_cast<unsigned int>(pCha)) ); }; // Buffer for labels captions char buf[128]{ 0x00 }; // Show character's ATTR_LUK if (pkodev::labLukShow != nullptr) { sprintf_s(buf, sizeof(buf), "LUK: %d", attr_get(ATTR_LUK)); pkodev::pointer::CLabel__SetCaption(pkodev::labLukShow, buf); } // Show character's ATTR_CRT if (pkodev::labCriticalShow != nullptr) { sprintf_s(buf, sizeof(buf), "CRT: %d", attr_get(ATTR_CRT)); pkodev::pointer::CLabel__SetCaption(pkodev::labCriticalShow, buf); } // Show character's ATTR_MF if (pkodev::labMfShow != nullptr) { sprintf_s(buf, sizeof(buf), "MF: %d", attr_get(ATTR_MF)); pkodev::pointer::CLabel__SetCaption(pkodev::labMfShow, buf); } } 1. В начале определяем найденные нами в пункте 3 адреса методов, функций и объектов; 2. Далее определяем указатели на необходимые функции и методы; 3. Затем определяем функции-перехватчики и глобальные переменные под указатели на текстовые метки; 4. В функции DllMain() записываем код для установки и снятия перехватчиков с помощью библиотеки Detours; 5. Реализуем перехватчик pkodev::hook::CStateMgr___evtMainShow(). В этой функции получаем указатели на объекты новых меток labLukShow, labCriticalShow и labMfShow с помощью метода CCompent* CForm::Find(const char* str); 6. Реализуем перехватчик pkodev::hook::CStateMgr__RefreshStateFrm(). Сначала получаем указатель на персонажа, которым управляет игрок. Далее записываем константы, обозначающие ID требуемых характеристик. Теперь стоит задача получения этих характеристик из памяти игры. В исходном коде клиента для этого используется указатель на объект типа SGameAttr, связанный с персонажем: SGameAttr* pCChaAttr = pCha->getGameAttr(); if (!pCChaAttr ) return; Анализ ассемблерного листинга показывает, что этот указатель находится по смещению 0xD0 относительно указателя на персонажа: .text:0047F1D2 mov ebx, dword_668B6C . . . .text:0047F1E4 add ebx, 0D0h Посмотрим что представляет собой объект SGameAttr в исходном коде: struct SGameAttr { long lAttr[MAX_ATTR_CLIENT]; // MAX_ATTR_CLIENT = 74 . . . }; Это структура, которая содержит только одно поле - массив из 74 целых чисел по 4 байта каждое, индексы элементов которого соответствует ID характеристик персонажа (см. файл AttrType.lua из скриптов GameServer). Из курса программирования мы знаем, что все элементы массива хранятся в памяти друг за другом. Значит, чтобы получить адрес характеристики персонажа с определенным ID, мы можем воспользоваться следующей формулой: 0xD0 + 4 * <ID> + <Адрес персонажа в памяти> Осталось самое простое: вывести требуемые характеристики персонажа в новые текстовые метки с помощью метода void CLabel::SetCaption(const char * str). 5) Компилируем проект и присоединяем DLL библиотеку к процессу игры. В результате мы получим следующее: После успешного тестирования, процесс создания модификации клиента завершен. Отмечу, что в примере я использовал GAME_13X_2, в Вашем Game.exe найденные адреса могут отличаться. Если у Вас возникли вопросы, то смело задавайте их в этой теме. Ниже прикладываю проект DLL-библиотеки и DLL-библиотеку мода. Скачать Архив с проектом DLL библиотеки модификации для Visual Studio 2022 Community и DLL библиотекой модификации из примера (286 Кб) Также на основе данной статьи был создан полноценный мод для вывода характеристик персонажа, который не ограничивается тремя характеристиками:
  22. [Мод] Автоматическое подключение к серверу / вход в игру Данная модификация позволяет указывать в параметрах запуска игры дополнительные параметры для автоматического подключения к серверу и входа персонажем в игру: start system\Game.exe startgame ip:127.0.0.1 port:1973 version:136 login:V3ct0r password:123456 character:V3ct0r При таком запуске клиента игроку не нужно будет вводить логин и пароль: игра автоматически подключится к серверу, а игрок попадет на сцену выбора персонажа. Кроме того, если было указано имя персонажа, то игрок сразу окажется в игре за этого персонажа, минуя процесс выбора. Также пользователь получает возможность указывать IP-адрес сервера, порт и версию. В отличие от решения, предложенного @ruubi, здесь присутствует функция входа персонажем сразу в игру. Мод может быть полезен для удобного запуска клиента и создания различных программ автообновления ("лаунчеров", "патчеров") с личным кабинетом, например: Список доступных параметров: ip - IP-адрес сервера [обязателен] port - порт сервера version - версия игры из GateServer.cfg login - логин от аккаунта игрока [обязателен] password - пароль от аккаунта игрока [обязателен] character - имя персонажа Параметры записываются в произвольном порядке в следующем формате: параметр:значение Пример: login:V3ct0r Если в параметрах запуска Game.exe не будут указаны параметры ip, login и password, то игра запустится в обычном режиме. При отсутствующих параметрах port и version, значения порта сервера и версии игры будут взяты из Game.exe - по умолчанию. Если не был указан параметр character, то игрок попадает на сцену выбора персонажа. Требования Установленный Загрузчик модов для сервера и клиента (PKOdev.NET mod loader). Информация о моде Название: pkodev.mod.autologin; Версия: 1.0; Автор: V3ct0r; Тип: для клиента (Game.exe); Поддерживаемые исполняемые .exe файлы: GAME_13X_0, GAME_13X_1, GAME_13X_2, GAME_13X_3, GAME_13X_4, GAME_13X_5. Установка Поместите файл DLL-библиотеки мода "pkodev.mod.autologin.client.13x_<ID>.dll" для Вашей версии Game.exe в папку "mods" игрового клиента. Скачать 1) Бинарные файлы мода (.dll); 2) Исходный код мода для Visual Studio 2019 Community (C++). Если Вы столкнулись с какой-либо проблемой, багом или у Вас возникли вопросы, то пишите в данной теме.
  23. [Мод] Подключение Game.exe к Stall Server (сервер "оффлайн" ларьков) Для реализации шифрования протокола в сервере "оффлайн" ларьков, последнему необходимо знать MD5-хэш пароля игрового аккаунта, но клиент версии 1.3x отправляет на сервер хэш пароля в зашифрованном виде. Данный мод для системы "PKODev.NET mod loader" необходим для отключения шифрования MD5-хэша пароля на стороне клиента и подключения к серверу "оффлайн" ларьков. Без данной модификации, при подключении к серверу с установленной системой "оффлайн" ларьков, пользователь будет получать ошибку "Неверный пароль!". Требования Установленный Загрузчик модов для сервера и клиента (PKOdev.NET mod loader). Информация о моде Название: pkodev.mod.stallserver; Версия: 1.0; Автор: V3ct0r; Тип: для клиента (Game.exe); Поддерживаемые исполняемые .exe файлы: GAME_13X_0, GAME_13X_1, GAME_13X_2, GAME_13X_3, GAME_13X_4, GAME_13X_5. Установка Поместите файл DLL-библиотеки мода "pkodev.mod.stallserver.client.13x_<ID>.dll" для Вашей версии Game.exe в папку "mods" игрового клиента. Скачать 1) Бинарные файлы мода (.dll); 2) Исходный код мода для Visual Studio 2019 Community (C++). Если Вы столкнулись с какой-либо проблемой, багом или у Вас возникли вопросы, то пишите в данной теме.
  24. Здравствуйте! Ув.Форумчане. Пытаюсь сделать локально сервер и клиент работоспособными. Все вроде бы работает, за исключением того, что не отображается ни один текст в игре (например диалоги НПС, когда выбираешь персонажа и тп, ники, сообщения в чат, при телепорте в другой регион тоже не высвечивается текст (только табло). Подскажите, куда копать? Может кто знает какой файл за этот текст отвечает?
  25. Работа с .res файлами (2.x версия) Автор: Monsiure aka Ingry Итак, можно думаю приступить, а начнем мы со скачивания ICU. Скачать Благодарности: Спасибо @lyon и @insider за направление на верный путь. Особая благодарность @kLabMouse за исправление неисправностей в декомпилировании, путем редактирования исходников, версия была взята родная 1.3.8.1. Внутри файлов лежит исходник + скомпилированные .exe .Полное сообщение неисправностей, которые он исправил: Теперь можно приступить к объяснению: Компиляция: Создаем папку icu в корне диска C; В папку ICU выгружаем содержимое из папки bin (В нашем скаченном архиве); Далее создаем в папке icu, файл compile.bat; Нажимаем правой кнопкой > изменить; И добавляем туда это: genrb -e UTF-8 -s | ПУТЬ ДО ПАПКИ С ICU | файл который будем компилировать | Пример: genrb -e UTF-8 -s C:/icu en_US.txt При этом нужно файл, который будем компилировать поместить в папку ICU; Сохраняем, запускаем. Декомпиляция: Создаем в нашей папке ICU еще один .bat файл; Называем его decompile; Добавляем туда такие строчки; derb -e UTF-8 -s | ПУТЬ ДО ПАПКИ С ICU | файл который будем декомпилировать | Пример: derb -e UTF-8 -s C:/icu en_US.res При этом нужно файл, который будем декомпилировать поместить в папку ICU; Сохраняем, запускаем. Вопрос: Найдите тут место, где я посмеялся
×
×
  • Create New...