1. Этот сайт использует файлы cookie. Продолжая пользоваться данным сайтом, Вы соглашаетесь на использование нами Ваших файлов cookie. Узнать больше.
  2. Вы находитесь в сообществе Rubukkit. Мы - администраторы серверов Minecraft, разрабатываем собственные плагины и переводим на различные языки плагины наших коллег из других стран.
    Скрыть объявление
Скрыть объявление
В преддверии глобального обновления, мы проводим исследования, которые помогут нам сделать опыт пользования форумом ещё удобнее. Помогите нам, примите участие!

Туториал Как написать своё ядро. Часть 1-2.

Тема в разделе "Руководства, инструкции, утилиты", создана пользователем ifxandy, 4 окт 2020.

?

Интересна ли вам статья.

  1. Да, интересна

    15 голосов
    83,3%
  2. Нет, не интересна

    3 голосов
    16,7%
  1. Автор темы
    ifxandy

    ifxandy Активный участник Пользователь

    Баллы:
    76
    Имя в Minecraft:
    witwar
    Как написать своё ядро.
    [​IMG]
    Приветствую вас, вы читаете статью о том, где сумасшедший вроде меня будет объяснять вам как написать своё ядро для серверов майнкрафт. Подразумевается, что эта статья - объяснение документации простыми словами.

    Начало.
    Для начала, нам нужно определиться с языком и некоторыми другими вещами. В этой статье мы будем использовать Python 3, так как он более лёгкий для новичков, а ещё потому, что мне так захотелось. Так же стоит определиться где мы будем писать, а именно в каком IDE. Нет, вы конечно можете использовать удобные Nano и Vim, но не все люди любят терминалы. Я могу предложить вам несколько IDE.

    1. Visual Studio Code. Поделка Microsoft. Присутствует версия DEB.
    2. PyCharm. Поделка JetBrains. Как по мне его минус - написан он на java. Отсутствует DEB.
    3. Sublime Text. Поделка не знаю кого. Это вообще не IDE. DEB присутствует.

    Когда мы выбрали IDE, можно приступать к созданию проекта. Лично я буду пользоваться Visual Studio, так как он мне удобнее. Надо бы создать проект. Как делать это, показывать не буду - Вам нечего делать тут если вы не знаете как создавать проект в своей IDE. После того как у нас есть пустая папка, нам надо создать скелет проекта. Первое что мы создадим будет файлом requirements.txt. Он нужен для удобной установки зависимостей. В него мы будем писать названия всех библиотек которые используем. После создания сразу запишем туда строчки.

    Код:
    quarry
    
    loguru
    Это наши две зависимости. Поясню,
    quarry - библиотека для удобной работы с протоколом майнкрафт, а loguru это просто рай для программиста, она позволяет работать с логами очень удобно. Далее мы создадим виртуальное окружение которое нужно, чтобы не засорять систему разными библиотеками нужными для проекта. Сделать это легко и просто можно командой:

    $ virtualenv venv -p python3

    У нас создастся как бы "отдельная система" с установленным питоном 3-ей версии. Теперь надо войти в это окружение. Для этого используем команду:

    $ source venv/bin/activate

    Теперь надо бы установить все наши зависимости, сделаем это через PiP:

    $ pip install -r requirements.txt

    Нам осталось совсем немного. Создадим лишь файл оболочки в корневой папке для запуска проекта. В моём случае это будет start.sh. Он пока остаётся пустым, так как самой "начинки" у нас ещё нету.

    Библиотека Quarry
    Как было упомянуто ранее, для работы с протоколом мы будем использовать библиотеку quarry. Более 90% работы она будет выполнять за нас. Первым делом, давайте создадим главную папку, пусть она называется так же как и проект, только с маленькой буквы. В ней мы создадим файл main.py. Он будет служить стартовой точкой для программы, будет разбирать аргументы и запускать сам сервер. Давайте напишем в него примерно такой код:


    Код:
    from loguru import logger # Логирование
    import argparse # Аргументы
    
    def main():
      parser = argparse.ArgumentParser()
      parser.add_argument("-m", "--motd", default="Test!", type=str, help="Server motd")
      args = parser.parse_args()
      logger.add("latest.log", rotation="5 MB")
      logger.info("All works!")
    
    main()
    Этот короткий код-заготовка при запуске вызовет главную функцию, распарсит аргументы и положит их в args. После этого создастя файл latest.log который будет пересоздаваться каждый раз когда будет достигать 5 MB веса и выведется сообщение "All works!". Окей, давайте теперь напишем основную логику. Создадим файл с любым названием. Теперь нам нужно создать для него некоторую заготовку. Для этого импортируем некоторые классы.


    Код:
    from twisted.internet import reactor
    from quarry.net.server import ServerProtocol, ServerFactory
    Далее, нам нужно создать классы наследники.


    Код:
    class ExampleProtocol(ServerProtocol):
    
      def player_joined(self): # Игрок зашёл
        ServerProtocol.player_joined(self) # Базовые действия при заходе игрока
        self.close("You disconnected because you {0}".format(self.display_name)) # Кикаем игрока по причине "You disconnected because you [имя игрока]"
    
    class ExampleFactory(ServerFactory):
      protocol = ExampleProtocol # Устанавливаем протокол
      motd = "My shiny test motd!" # Устанавливаем мотд для сервера
    На этом и подошла к концу первая часть. Вторую я напишу, если эта часть окажется хоть кому то полезной и/или интересной. Хочу отметить, что созданный проект не дописан и не должен работать.
     
    Последнее редактирование: 4 окт 2020
  2. Автор темы
    ifxandy

    ifxandy Активный участник Пользователь

    Баллы:
    76
    Имя в Minecraft:
    witwar
    Это ответ тем, кто говорил, что мне стоит написать туториал о чём то оригинальном.
     
    Последнее редактирование: 4 окт 2020
  3. Автор темы
    ifxandy

    ifxandy Активный участник Пользователь

    Баллы:
    76
    Имя в Minecraft:
    witwar
    Как написать своё ядро. Часть II.
    [​IMG]
    Приветствую вас, вы читаете продолжение статьи о том, где сумасшедший вроде меня наконец изъяснится до конца вам о том, как написать ядро для сервера майнкрафт. Если вы не видели 1-ую статью, советую прочитать сначала её. Цель данной статьи - показать, насколько легко написать своё ядро.

    Продолжение
    Вспомним про наш уже существующий проект и допишем его. Определимся с целью нашего ядра, давайте сплагиатим небольшую часть из моего проекта и будет генерировать для каждого игрока отдельный токен. Входим в виртуальное окружение и открываем все нужные файлы в нашем IDE.

    Приступим к написанию кода. Сначала напишем логику самого сервера. Импортируем библиотеку secrets(она стандартная для python3 и заносить в requirements.txt её не надо)

    Код:
    import secrets
    Данная библиотека поможет нам в генерации ключа игрока. Добавим пару строчек перед этим.

    Код:
    self.close("You disconnected because you {0}".format(self.display_name))
    Вот, что мы допишем.

    Код:
    token = secrets.hex(5) # 5 - Длина ключа, может быть любой
    Данный код сгенерирует HEX-последовательность и положит её в переменную token. Далее нам надо немного подправить файл main.py где обрабатываются аргументы. Добавим в него несколько аргументов. Вот что у нас получится.

    Код:
    from loguru import logger # Логирование
    import argparse # Аргументы
    
    def main():
      parser = argparse.ArgumentParser()
      parser.add_argument("-a", "--api", required=True type=str, help="HTTPS API to send requests")
      parser.add_argument("-A", "--api-token", required=True, type=str, help="API  TOKEN for authorization.")
      args = parser.parse_args()
      logger.add("latest.log", rotation="5 MB")
      logger.info("All works!")
    
    main()
    Теперь для запуска нашего сервера, обязательно надо будет указать адрес сайта, на который будет отправляться POST запрос с данными и токен, чтобы сайт мог определить, что запрос именно от нашего сервера. В основном файле нам осталось только отправить запрос. Но сначала мы доделаем файл main.py. Допишем в наш основной файл функцию(не относящуюся к какому либо классу).

    Код:
    def main(args):
      f = ExampleFactory()
      f.api = args.api
      f.token = args.api_token
      f.listen('localhost', 25565)
      reactor.run()
    Она нужна для того, чтобы мы могли вызвать её из main.py передав аргументы как аргумент. Разберём её подробнее, в ней мы создаём экземпляр фабрики и устанавливаем несколько переменных у этого экземпляра. Это нужно для того, чтобы мы могли получить эти переменные в классе-протоколе. Дальше, мы заставляем фабрику слушать 'localhost' на порте 25565(стандартный порт майнкрафт серверов). Теперь мы можем со спокойной совестью импортировать эту функцию в main.py и вызвать её. Наш сервер уже способен запуститься и генерировать токен на каждого игрока. Давайте кстати изменим причину кика в основном файле на причину содержащую токен. Например "Your token is: [token]". Остаётся только отправить запрос, это сделаем при помощи стандартной библиотеки request. Импортируем её.

    Код:
    import requests
    Определим несколько переменных отвечающих за данные запроса и его хёдеры. Назовём их к примеру headers и data. Это всё должно находиться перед закрытием соединения. Вот что мы допишем.

    Код:
    headers = {"Authorization":"Bearer " + self.factory.token}
    data = {"token":token,"username":self.display_name,"uuid":self.uuid}
    Разберёмся. Начнём с хёдеров, первым и единственным у нас будет хёдер Authorization. Он служит в запросах для авторизации в чём то или где то. Мы используем его для того, чтобы сказать серверу о том что это мы. Дальше идёт переменная data - тело запроса. Оно содержит такие параметры как token - токен сгенерированный для пользователя в коде выше, username - имя пользователя(игрока), uuid - UUID игрока. Давайте отправим это всё дело на сервер при помощи данного кода.

    Код:
    try:
      request = requests.post(self.factory.api, headers=headers, data=data)
    except:
      self.logger.error("HTTP API cannot be requested.")
      self.close("Internal Server Error")
    В данном коде мы пробуем отправить POST-запрос на адрес из переменной api в фабрике с хёдерами headers и с данными data. Если возникает ошибка - печатаем в консоль повесть о том, что мы не можем достучаться до сервера и закрываем соединение с пользователем по причине "Internal Server Error".

    Открываем файл оболочки(у меня start.sh) и записываем туда команду для вызова main.py файла.

    Вот впринципе и всё.
     
  4. iForgotPassword

    iForgotPassword Активный участник Пользователь

    Баллы:
    66
    Имя в Minecraft:
    iForgotPassword
    Интересно, но так бессмысленно...
    Почему Python?
    Это не ядро, а какой-то скрипт, который выводит motd и кикает при коннекте.
    Тема интересная, развития никакого, к сожалению.
     
  5. Автор темы
    ifxandy

    ifxandy Активный участник Пользователь

    Баллы:
    76
    Имя в Minecraft:
    witwar
    Я дал лишь основу, чтобы из этого можно было сделать что либо ещё, по своей задумке. Python разве не легче для понимания и не занимает меньше оперативы? К тому же библиотека Quarry благодаря которой я написал статью, попалась мне на глаза первее, чем любая библиотека под яву(Они вообще такие есть под неё?).
     
  6. iForgotPassword

    iForgotPassword Активный участник Пользователь

    Баллы:
    66
    Имя в Minecraft:
    iForgotPassword
    Я твой посыл понял, лайк бы поставил на теме. Мне не понравилось то, что как-то не до конца раскрыта тема, наверное. Не знаю.
    Не уверен, что прочитав эту статью кто-то захочет написать свое ядро сервера, да и к тому же на Python, когда все вокруг Minecraft крутится на Java. Java - де-факто для мира Minecraft и никакой другой язык в ближайшее время его не заменит. К тому же, менять Java на Python плохая идея т.к Python еще менее производительнее чем Java (как минимум из-за того, что Python интерпретируемый язык). К тому же, количество выделяемой памяти под приложение Java/Python не играет роли, если итоговая производительность приложения ниже.
    Я точно не знаю как создаются ядра для серверов, но, если я не ошибаюсь, есть ядро Bukkit, а все остальное - его форки в той или иной степени.
    Также при написании своего ядра на Python возникнет ряд проблем с интеграцией Java плагинов.
    Да и в целом Python не предназначен для высоконагруженной системы (могу ошибаться)
     
  7. Автор темы
    ifxandy

    ifxandy Активный участник Пользователь

    Баллы:
    76
    Имя в Minecraft:
    witwar
    Java к слову майнкрафт скорее всего выбрал не потому что им так захотелось, а потому что он просто кроссплатформенный. Но компиляция Java насколько знаю - не превращение кода в бинарник, Java кроссплатформенная из за принципа её работы. Она компилирует приложение в понятный для себя байткод, его к слову прочитать можно легко и без особых проблем, а только потом уже при запуске она превращает его в понятный для машины код(это всё не точно, я не обновлял знания по работе Java давно). А выделенная оперативка играет роль, так как чем меньше надо оперативки - тем лучше, ведь запустить прогу ты сможешь на машине с характеристиками чуть хуже. А на счёт Bukkit - необязательно, это не какой то закон.
     
  8. iForgotPassword

    iForgotPassword Активный участник Пользователь

    Баллы:
    66
    Имя в Minecraft:
    iForgotPassword
    Java выбрал Маркус Перссон т.к он на нем изначально программировал => все последующее развитие Minecraft на Java.
    Код:
    Java являются JIT-компилируемыми. Для JIT-компиляции требуется промежуточный язык, позволяющий разбивать код на блоки (или фреймы).  Сам по себе JIT не делает выполнение быстрее, ведь он по-прежнему выполняет те же последовательности байт-кода. Однако, он позволяет выполнять оптимизацию в рантайме. Хороший JIT-оптимизатор видит, какие части приложения выполняются чаще, и помечает их тегом "hot spot", чтобы в следующий раз выполнение прошло быстрее.
    
    Сейчас заканчивается 2020г, а не 90-00, когда размер памяти играл большую роль.
    К тому же, зачем тебе много оперативки, если у тебя стоит никчемный процессор? Оперативная память нужна для того, чтобы хранить в ней какие-то данные и быстро ими манипулировать. А т.к у нас не текстовый редактор а сервер, то нам нужна многопоточность и быстрота процессора => оперативная память на втором месте. Если у тебя будет все тупить в следствие того, что процессор не может обработать такое кол-во операций, то пиши пропало, оператос не спасет.
     
  9. Автор темы
    ifxandy

    ifxandy Активный участник Пользователь

    Баллы:
    76
    Имя в Minecraft:
    witwar
    Так поэтому и хорошо делать программы с мелким потреблением оперативы, чтобы ты мог вбухать больше денег в процессор и при этом программа всё равно запустилась. Да и вообще, всегда будет лучше, если программа требует меньше ресурсов.
     
  10. iForgotPassword

    iForgotPassword Активный участник Пользователь

    Баллы:
    66
    Имя в Minecraft:
    iForgotPassword
    Разница в количестве потребляемой оперативной памяти не такая большая, чтобы пренебрегать скоростью работы
     
  11. Автор темы
    ifxandy

    ifxandy Активный участник Пользователь

    Баллы:
    76
    Имя в Minecraft:
    witwar
    Ну и в конце концов, этоn конечно скорее всего не будет применяться для написания таких вещей где важна скорость работы буквально RealTime.
     
  12. iForgotPassword

    iForgotPassword Активный участник Пользователь

    Баллы:
    66
    Имя в Minecraft:
    iForgotPassword
    :good:
     
  13. alexandrage

    alexandrage Старожил Пользователь

    Баллы:
    173
    Этот quarry в любом случае нигде не будет применятся да. Ибо это не ядро, а пустой протокол майна. Внутри него ничего нет. И таких протоколов много на гитхабе, даже на node js есть
     
  14. Nikolai_Faint

    Nikolai_Faint Активный участник Пользователь

    Баллы:
    96
    Бред.
    Сейчас все еще смотрят на бенчи. Все что быстрее эквивалентно тому что это лучше.
    Большую роль играет удобство, но если у тебя всё хавает тонну озу и нагружает процессор до предела - люди будут перестраиваться под другой продукт.
    Ну есть майн на плюсах который намного производительнее оригинала т.к не содержит тонны абстракций на абстракциях, глупые реализации простейших вещей, и прочее.
    ладно.......

    ТС'у:
    Тема полнейший бред, это не ядро.
    Это больше похоже на какую-то проксю для обработки запросов с клиента.
     
  15. SimMiMo

    SimMiMo Активный участник Пользователь

    Баллы:
    76
    Сейчас обычный недорогой дедик имеет 32-64 гб памяти и это все будет дешеветь с каждым годом.
    Майн на мобилу.. покет едишн. Если честно, под него вообще нормальных ядер нет, одно говно.
    Да и любителей телефончиков не настолько чтобы дофига. Не представляю, как там пэхаться.
    Но опять же, это не вина самого майна пе.
     
    Последнее редактирование: 20 окт 2020
  16. iForgotPassword

    iForgotPassword Активный участник Пользователь

    Баллы:
    66
    Имя в Minecraft:
    iForgotPassword
    майнна плюсах это же Bedrock edition, то бишь PE, PS4 и пр. что != Java edition
     
  17. Nikolai_Faint

    Nikolai_Faint Активный участник Пользователь

    Баллы:
    96
    Дак бедрок есть не только на телефоны o_0
    Что ****ь за бред ты несешь? Причём тут то что он не Java Edition? Мы говорим то что он в разы производительнее чем оригинал (даже если убрать тот факт что он нативный), т.к в нём нету сотни тысяч абстракций, глупых реализаций, и просто врапперов над врапперами.
    Каждый прыжок по сегментам занимает кучу времени, особенно если забить на то что твой код нужно оптимизировать т.к ты работаешь через виртуалку.
    Инфляция это who
     
  18. Автор темы
    ifxandy

    ifxandy Активный участник Пользователь

    Баллы:
    76
    Имя в Minecraft:
    witwar
    Так потому он и прекрасен, он уже убирает мороку с подключением и даёт какой никакой API для работы с пакетами. При этом над пакетами play у тебя есть полный контроль. К тому же там есть примеры, из который вполне будет понятно как реализовать определённую вещь.
     
  19. alexandrage

    alexandrage Старожил Пользователь

    Баллы:
    173
    Ну дает и что? А серверлогики то нет. Портировать весь кубач на питон? Ну такое.
     

Поделиться этой страницей