У нас есть 18 ответов на вопрос Какой протокол использует Minecraft? Скорее всего, этого будет достаточно, чтобы вы получили ответ на ваш вопрос.

Содержание

  • Какой протокол использует сервер Minecraft?
  • На каком порту работает Майнкрафт?
  • Как узнать порт локального сервера Minecraft?
  • Какой протокол использует Minecraft? Ответы пользователей
  • Какой протокол использует Minecraft? Видео-ответы

Отвечает Лёша Гасанов

Minecraft Server Query – это простой протокол, позволяющий получить актуальную информацию о состоянии сервера путём отправки пары-тройки незамысловатых UDP-пакетов.Feb 23, 2021

Какой протокол использует сервер Minecraft?

Протокол сервера Classic используется в Minecraft Classic Creative Multiplayer сервере.

На каком порту работает Майнкрафт?

Как узнать порт локального сервера Minecraft?

Нажмите Esc для появления меню, в котором надо выбрать «Открыть для сети». Появится уведомление с присвоенным для сервера портом, который необходимо запомнить. Теперь выйдите на рабочий стол, запустите командную строку и введите в ней ipconfig для определения своего IPv4-адреса.

Зашёл на политический сервер в майнкрафте

Какой протокол использует Minecraft? Ответы пользователей

Отвечает Сергей Долматов

Решил создать сервер майнкрафт, и тут проблема: какой протокол портов подходит? UDP или TCP? Помогите, пожалуйста! Добавил в категорию Интернет, .

Отвечает Максим Бычков

Сегодня я расскажу, как создать сервер Minecraft на CloudLITE. . enable-query, true / false, false, Позволяет активировать протокол GameSpy4 для прослушки .

Отвечает Милан Заруцкий

Но за счёт ненадежности протокола UDP снижается нагрузка на сервер, поэтому его чень часто используют в онлайн играх, где одновременно играют очень много .

Отвечает Наталья Куряжская

Протокол – тот, который вам нужен, TCP или UDP. Внешний и внутренний начальный порт – конкретный номер, например 25444. Внутренний IP – адрес IPv4, который вы .

Отвечает Станислав Синяк

Каждая редакция Minecraft использует свой собственный формат для хранения уровней. . Протокол сервера Classic используется в Minecraft Classic Creative .

Отвечает Рома Фрольченков

Как и все игры-песочницы, Minecraft предоставляет пользователю огромные . true активирует протокол GameSpy4 для прослушивания сервера; .

Отвечает Гидаят Осокин

майнкрафт как и любая полнофункциональная клиент-серверная игра использует полный протокол TCP/IP, HTTP это «надпротокол» (протокол 3-его .

Отвечает Анна Дмитриева

Minecraft должен отвечать тем же идентификатором, но с идентификатором сервера motd и . Более конкретно, протокол Minecraft использует UDP, что означает, .

Отвечает Слава Чибриков

Вопрос по теме: php, minecraft, sockets, network-protocols, packets. . Более конкретно, протокол Minecraft использует UDP, что означает, что вам нужно .

Какой протокол использует Minecraft? Видео-ответы

Как работает компаратор? | Minecraft

Приветик! В Minecraft есть один чертовски сложный и непонятный блок — компаратор. Если ты не понимаешь как им .

  • Как работает компаратор? | Minecraft
  • Red-основы: компаратор

    Нужны ли такие гайды по другим редстоун-элементам? Голосуйте здесь: http://vk.com/siverusprod?w=wall-38833408_2986 .

  • Red-основы: компаратор
  • СПОСОБНОСТЬ ВЫЗЫВАТЕЛЯ В МАЙНКРАФТ БЕЗ МОДОВ (MCPE)

    В этом видео вы узнаете, как сделать способность вызывателя БЕЗ МОДОВ в Майнкрафт PE. Команды из видео: /enchant .

  • СПОСОБНОСТЬ ВЫЗЫВАТЕЛЯ В МАЙНКРАФТ БЕЗ МОДОВ (MCPE)
  • Этими Сайтами Пользуются ВСЕ Майнкрафтеры | Майнкрафт Открытия

    Как Вы думаете пользуются ли опытные Майнкрафтеры вспомогательными ресурсами? Ответ — да! Ведь никто не зхочет .

  • Этими Сайтами Пользуются ВСЕ Майнкрафтеры | Майнкрафт Открытия
  • Админ ОБМАНУЛ игрока на сервере в Майнкрафт #Shorts

    В этом ролике: Я попросил Админа Домера ресурсов на сервере в майнкрафт, но админ оказался жадным? Это пранк для .

    Источник: querybase.ru

    Реализация Minecraft Query протокола в .Net Core

    Minecraft Server Query – это простой протокол, позволяющий получить актуальную информацию о состоянии сервера путём отправки пары-тройки незамысловатых UDP-пакетов.

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

    Так было принято решение написать свою реализацию.

    Скажи мне, кто ты.

    Для начала, посмотрим, что из себя представляет сам протокол Minecraft Query. Согласно вики, мы имеем в распоряжении 3 вида пакетов запросов и, соотвественно, 3 вида пакетов ответа:

    • Handshake
    • BasicStatus
    • FullStatus

    Первый тип пакета используется для получения ChallengeToken, необходимого для формирования других двух пакетов. Привязывается он к IP-адресу отправителя на 30 секунд. Смысловая нагрузка оставшихся двух ясна из названий.

    Стоит отметить, что хотя последние два запроса отличаются друг от друга лишь выравниванием на концах пакетов, присылаемые ответы отличаются способом представления данных. Для примера, вот так выглядит ответ BasicStatus

    Ответ на запрос BasicStatus

    А вот так – FullStatus

    Ответ на запрос FullStatus

    Все данные, помимо тех, что хранятся в short, представлены в big-endian. А для поля SessionId, которое постоянно в рамках одного клиент-сервер соединения, должно выполняться условие SessionId ручном» режиме.

    Итак, определившись, можем уже представить, как будет выглядеть архитектура классов. Я вижу работу примерно таким образом

    public static async Task DoSomething(IPAddress host, int port)

    Здесь создаётся разовое соединение. Для долгоживущего потребуется проверять состояние сокета и инициализировать заново (об этом в конце статьи).

    Для того, чтобы пакет отправить, его надо для начала сформировать. Этим будет заниматься класс Request.

    public class Request < // Набор констант для формирования пакета private static readonly byte[] Magic = < 0xfe, 0xfd >; private static readonly byte[] Challenge = < 0x09 >; private static readonly byte[] Status = < 0x00 >; public byte[] Data < get; private set; >private Request()<> public byte RequestType => Data[2]; public static Request GetHandshakeRequest(SessionId sessionId) < var request = new Request(); // Собираем пакет var data = new List(); data.AddRange(Magic); data.AddRange(Challenge); data.AddRange(sessionId.GetBytes()); request.Data = data.ToArray(); return request; > public static Request GetBasicStatusRequest(SessionId sessionId, byte[] challengeToken) < if (challengeToken == null) < throw new ChallengeTokenIsNullException(); >var request = new Request(); var data = new List(); data.AddRange(Magic); data.AddRange(Status); data.AddRange(sessionId.GetBytes()); data.AddRange(challengeToken); request.Data = data.ToArray(); return request; > public static Request GetFullStatusRequest(SessionId sessionId, byte[] challengeToken) < if (challengeToken == null) < throw new ChallengeTokenIsNullException(); >var request = new Request(); var data = new List(); data.AddRange(Magic); data.AddRange(Status); data.AddRange(sessionId.GetBytes()); data.AddRange(challengeToken); data.AddRange(new byte[] ); // Padding request.Data = data.ToArray(); return request; > >

    Читайте также:  Как узнать почту по нику Майнкрафт

    Здесь всё просто. Храним все константы внутри класса и формируем пакет в трёх статических методах. Можно ещё заметить класс SessionId, который может давать как байтовое, так и строковое представление по необходимости.

    Дождавшись ответа сервера, мы получаем последовательность байт, которые хотим привести к человекочитаемому виду. Для этого служит класс Response, который представляет набор «парсеров» в виде статических полей.

    public static class Response < public static byte ParseType(byte[] data) < return data[0]; >// public static SessionId ParseSessionId(byte[] data) < if (data.Length < 1) throw new IncorrectPackageDataException(data); var sessionIdBytes = new byte[4]; Buffer.BlockCopy(data, 1, sessionIdBytes, 0, 4); return new SessionId(sessionIdBytes); >public static byte[] ParseHandshake(byte[] data) < if (data.Length < 5) throw new IncorrectPackageDataException(data); var response = BitConverter.GetBytes(int.Parse(Encoding.ASCII.GetString(data, 5, data.Length — 6))); if (BitConverter.IsLittleEndian) < response = response.Reverse().ToArray(); >return response; > public static ServerBasicState ParseBasicState(byte[] data) < if (data.Length (); short port = -1; data = data.Skip(5).ToArray(); // Skip Type + SessionId var stream = new MemoryStream(data); var sb = new StringBuilder(); int currentByte; int counter = 0; while ((currentByte = stream.ReadByte()) != -1) < if (counter >6) break; // Парсим нормер порта if (counter == 5) < byte[] portBuffer = ; if (!BitConverter.IsLittleEndian) portBuffer = portBuffer.Reverse().ToArray(); port = BitConverter.ToInt16(portBuffer); // Little-endian short counter++; continue; > // Парсим параметры-строки if (currentByte == 0x00) < string fieldValue = sb.ToString(); statusValues.Enqueue(fieldValue); sb.Clear(); counter++; >else sb.Append((char) currentByte); > var serverInfo = new ServerBasicState < Motd = statusValues.Dequeue(), GameType = statusValues.Dequeue(), Map = statusValues.Dequeue(), NumPlayers = int.Parse(statusValues.Dequeue()), MaxPlayers = int.Parse(statusValues.Dequeue()), HostPort = port, HostIp = statusValues.Dequeue(), >; return serverInfo; > // «Секции» пакета резделены константными последовательностями байт, // это можно испльзовать для проверки, что мы всё сделали правильно public static ServerFullState ParseFullState(byte[] data) < var statusKeyValues = new Dictionary(); var players = new List(); var buffer = new byte[256]; Stream stream = new MemoryStream(data); stream.Read(buffer, 0, 5); // Read Type + SessionID stream.Read(buffer, 0, 11); // Padding: 11 bytes constant var constant1 = new byte[] ; for (int i = 0; i < constant1.Length; i++) Debug.Assert(constant1[i] == buffer[i], «Byte mismatch at » + i + » Val :» + buffer[i]); var sb = new StringBuilder(); string lastKey = string.Empty; int currentByte; while ((currentByte = stream.ReadByte()) != -1) < if (currentByte == 0x00) < if (!string.IsNullOrEmpty(lastKey)) < statusKeyValues.Add(lastKey, sb.ToString()); lastKey = string.Empty; >else < lastKey = sb.ToString(); if (string.IsNullOrEmpty(lastKey)) break; >sb.Clear(); > else sb.Append((char) currentByte); > stream.Read(buffer, 0, 10); // Padding: 10 bytes constant var constant2 = new byte[] ; for (int i = 0; i < constant2.Length; i++) Debug.Assert(constant2[i] == buffer[i], «Byte mismatch at » + i + » Val :» + buffer[i]); while ((currentByte = stream.ReadByte()) != -1) < if (currentByte == 0x00) < var player = sb.ToString(); if (string.IsNullOrEmpty(player)) break; players.Add(player); sb.Clear(); >else sb.Append((char) currentByte); > ServerFullState fullState = new() < Motd = statusKeyValues[«hostname»], GameType = statusKeyValues[«gametype»], GameId = statusKeyValues[«game_id»], Version = statusKeyValues[«version»], Plugins = statusKeyValues[«plugins»], Map = statusKeyValues[«map»], NumPlayers = int.Parse(statusKeyValues[«numplayers»]), MaxPlayers = int.Parse(statusKeyValues[«maxplayers»]), PlayerList = players.ToArray(), HostIp = statusKeyValues[«hostip»], HostPort = int.Parse(statusKeyValues[«hostport»]), >; return fullState; > >

    Таким образом мы получаем полный инструментарий для формирования пакетов, их отправки, получения ответов и извлечения из них необходимой информации.

    Долгоживущие приложения на основе библиотеки

    Вернёмся к том, о чем я говорил выше. Это можно реализовать таким образом. Код взят из моего нотификатора пользовательской активности. Здесь каждые 5 секунд запрашивается FullStatus, поэтому имеет смысл обновлять ChallengeToken периодически сразу после истечения предыдущего. Всего приложение имеет 2 режима работы: штатный и режим восстановления соединения.

    В штатном режиме приложение по таймерам обновляет токен и запрашивает FullStatus. При обнаружении упавшего сервера/оборванного соединения/etc (5 попыток передачи) приложение переходит в режим восстановления соединения и при удачной попытке получения сообщения снова возвращается в штатный режим.

    Для начала напишем конструктор и два метода для запуска прослушивания сервера и окончания.

    public StatusWatcher(string serverName, string host, int queryPort) < ServerName = serverName; _mcQuery = new McQuery(Dns.GetHostAddresses(host)[0], queryPort); _mcQuery.InitSocket(); >public async Task Unwatch() < await UpdateChallengeTokenTimer.DisposeAsync(); await UpdateServerStatusTimer.DisposeAsync(); >public async void Watch() < // Обновляем challengetoken по таймеру каждые 30 секунд UpdateChallengeTokenTimer = new Timer(async obj =>< if (!IsOnline) return; if(Debug) Console.WriteLine($»[INFO] [] Send handshake request»); try < var challengeToken = await _mcQuery.GetHandshake(); // Если всё ок, говорим, что мы в онлайне и сбрасываем счетчик попыток IsOnline = true; lock (_retryCounterLock) < RetryCounter = 0; >if(Debug) Console.WriteLine($»[INFO] [] ChallengeToken is set up: » + BitConverter.ToString(challengeToken)); > // Если что-то не так, увеличиваем счетчик неудачных попыток catch (Exception ex) < if (ex is SocketException || ex is McQueryException || ex is ChallengeTokenIsNullException) < if(Debug) Console.WriteLine($»[WARNING] [] [UpdateChallengeTokenTimer] Server doesn’t response. Try to reconnect: «); if(ex is McQueryException) Console.Error.WriteLine(ex); lock (_retryCounterLock) < RetryCounter++; if (RetryCounter >= RetryMaxCount) < RetryCounter = 0; WaitForServerAlive(); // Переходим в режим восстановления соединения >> > else < throw; >> >, null, 0, GettingChallengeTokenInterval); // По таймеру запрашиваем текущее состояние UpdateServerStatusTimer = new Timer(async obj => < if (!IsOnline) return; if(Debug) Console.WriteLine($»[INFO] [] Send full status request»); try < var response = await _mcQuery.GetFullStatus(); IsOnline = true; lock (_retryCounterLock) < RetryCounter = 0; >if(Debug) Console.WriteLine($»[INFO] [] Full status is received»); OnFullStatusUpdated?.Invoke(this, new ServerStateEventArgs(ServerName, response)); > // По аналогии с предыдущим catch (Exception ex) < if (ex is SocketException || ex is McQueryException || ex is ChallengeTokenIsNullException) < if(Debug) Console.WriteLine($»[WARNING] [] [UpdateServerStatusTimer] Server doesn’t response.

    Читайте также:  Как сделать Майнкрафт на пайтоне

    Try to reconnect: «); if(ex is McQueryException) Console.Error.WriteLine(ex); lock (_retryCounterLock) < RetryCounter++; if (RetryCounter >= RetryMaxCount) < RetryCounter = 0; WaitForServerAlive(); >> > else < throw; >> >, null, 500, GettingStatusInterval); >

    Осталось только реализовать ожидание восстановления соединения. Для этого нам достаточно убедиться, что мы получили хоть какой-то ответ от сервера. Для этого мы можем воспользоваться тем же запросом хэндшейка, который не требует наличия действующего ChallengeToken.

    public async void WaitForServerAlive() < if(Debug) Console.WriteLine($»[WARNING] [] Server is unavailable. Waiting for reconnection. «); // Отключаем отслеживание IsOnline = false; await Unwatch(); _mcQuery.InitSocket(); // Пересоздаём сокет Timer waitTimer = null; waitTimer = new Timer(async obj => < try < await _mcQuery.GetHandshake(); // Говорим, что можно возвращаться в штатный режим и отключаем таймер IsOnline = true; Watch(); lock (_retryCounterLock) < RetryCounter = 0; >waitTimer.Dispose(); > // Пересоздаем сокет каждые 5 (настраивается) неудачных соединений catch (SocketException) < if(Debug) Console.WriteLine($»[WARNING] [] [WaitForServerAlive] Server doesn’t response. Try to reconnect: «); lock (_retryCounterLock) < RetryCounter++; if (RetryCounter >= RetryMaxCount) < if(Debug) Console.WriteLine($»[WARNING] [] [WaitForServerAlive] Recreate socket»); RetryCounter = 0; _mcQuery.InitSocket(); > > > >, null, 500, 5000); >

    UDP1: Вынес библиотеку в отдельный репозиторий.

    Источник: habr.com

    Разделение Клиент-Сервер и пакетная система ElegantNetworking

    6175.jpg

    Разделение Клиент-Сервер и пакетная система ElegantNetworking

    В этой статье описаны базовые принципы коммуникации между клиентом и сервером Minecraft, а также предложен удобный фреймворк для создания своих пакетов.

    1. Разделение Клиент-Сервер
    2. Коммуникация ванильный Клиент ←→ Сервер
    3. Безопасность при обработке пакетов с клиента
    4. Коммуникация Клиент ←→ Сервер с помощью SimpleNetworkWrapper
    5. Коммуникация Клиент ←→ Сервер с помощью библиотеки ElegantNetworking

    Разделение Клиент-Сервер ​

    • Физический клиент — это программа, которая выполняется всякий раз при запуске Minecraft из лаунчера. Все потоки, процессы и службы, которые выполняются во время графического, интерактивного времени жизни игры, являются частью физического клиента.
    • Физический сервер — часто известный как выделенный сервер (Dedicated server), это программа, которая выполняется всякий раз, когда вы запускаете какой-либо файл minecraft_server.jar, который не создает графический интерфейс.
    • Логический сервер — это то, что запускает логику игры : спавн мобов, погода, обновление инвентарей, здоровье, AI и все другие игровые механики. Логический сервер присутствует на физическом сервере, но также может работать внутри физического клиента вместе с логическим клиентом в одиночном мире (Integrated server). Логический сервер всегда работает в потоке с именем Server Thread.
    • Логический клиент — это то, что принимает ввод от игрока и передает его на логический сервер. Кроме того, он получает информацию с логического сервера и делает ее графически доступной игроку. Логический клиент работает в Client Thread, хотя часто другие потоки порождаются для для обработки таких вещей, как обработка звуков и рендер чанков.

    physical-logical-mc-sides.png

    physical-logical-mc-sides (1).png

    • Серверная сторона отвечает за поддержание оригинала мира — обновление блоков и сущностей основываясь на пакетах, полученных от клиентов, отправление обновленной информации всем клиентам.
    • Клиентская сторона в первую очередь отвечает за обработку входной информации (нажатие клавиш, клики мыши) и отрисовку экрана.
    • Если World.isRemote() == true , то это сторона Клиента
    • Если World.isRemote() == false, то это сторона Сервера

    В других случаях можно использовать FMLcommonHandler.instance().getEffectiveSide() (или EffectiveSide.get() на новых версиях), который угадывает текущую сторону, анализируя поток, в котором вызывается. Этот способ не является эффективным и надежным, поэтому используйте его с осторожностью.

    Для определения физической стороны выполнения, используйте FMLCommonHandler.instance().getSide() (или FMLEnvironment.dist на новых версиях). Поскольку физическая сторона определяется при запуске, метод не полагается на угадывание, однако число вариантов использования этого метода ограничено (Пример : выпадение специального предмета при ломании блока, но только если мод запущен на выделенном сервере, а не в одиночной игре).

    Основные ошибки
    Когда клиент и сервер должны синхронизироваться друг с другом, они обмениваются информацией по сети. Даже когда мы находимся в одиночной игре, клиент и сервер все еще полностью разделены и не имеют доступа к объектом друг друга. Если ваш код, работающий (скажем) на стороне сервера, обратился к объектам, принадлежащим стороне клиента, это приведет к случайным крашам и странному поведению. Это также приведет к крашу вашего кода сразу после установки на выделенный сервер.
    Всякий раз, когда вы хотите отправлять информацию с одной логической стороны на другую, вы должны использовать сетевые пакеты. Невероятно заманчиво в одиночной игре напрямую передавать данные с логического сервера на логический клиент, что очень часто непреднамеренно делается через статические поля, но поскольку логический клиент и логический сервер используют одну и ту же JVM в одиночной игре, оба потока, записывающие и считывающие из статический полей, будут вызывать разного рода состояния гонки и классические проблемы, связанные с потоковой обработкой.
    Эта ошибка также может быть совершена при попытке обратиться к client-only классам, таким как net.minecraft.client.Minecraft , существующем только на логическом клиенте, из общего кода, выполняющегося на логическом сервере. Код будет работать в одиночной игре, но крашнется на физическом сервере.

    Читайте также:  Как установить читы на Майнкрафт лаунчер tlauncher

    Коммуникация ванильный Клиент ←→ Сервер ​

    Ванильная связь между клиентскими и серверными сторонами происходит через пакеты, которые отправляются туда и обратно с помощью NetHandlerPlayClient и NetHandlerPlayServer . Основные этапы показаны на диаграмме ниже.

    VanillaClientServer.png

    Ключевые моменты
    Пакеты — это набор информации (числа, строки, ItemStack’и и др), конвертированный в байты для передачи по сети.
    Пакеты, отправленные с Клиента на Сервер, начинаются с C, например C07PacketPlayerDigging .
    Пакеты, отправленные с сервера на клиент, начинаются с S, например S06PacketUpdateHealth .
    Можно создать ванильные пакеты и отправлять их с помощью NetHandler, однако это почти никогда не требуется. Если вы вызовете правильные существующие методы, они отправят вам пакеты (например, ServerConfigurationManager.sendChatMsg() вместо S02PacketChat ).

    Безопасность при обработке пакетов с клиента ​

    При обработке пакетов с клиента не пренебрегайте дополнительными проверками полученных данных! Клиент может попытаться отправить специально созданные пакеты с неожиданными для вас данными, чтобы вызвать лаги, дюпы и краши сервера.
    Основной проблемой является уязвимость к произвольной генерации чанков. Обычно это происходит, когда сервер доверяет позиции блока, указанной в полученном пакете, чтобы взаимодействовать с блоком или тайлом на этом месте. При попытке доступа к блокам в не загруженных участках мира, сервер либо загрузит этот участок с диска, либо сгенерирует его. Это может привести к катастрофическому падению производительности и захламлению места на диске, совершенно не оставляя следов.
    Чтобы избежать этой проблемы, общим правилом является ограничение доступа блокам и сущностям, удаленных от него на определенное расстояние — проверка квадрата расстояния игрока до блока (рекомендовано), либо доступ только к загруженным участкам мира — когда world.isBlockLoaded(pos) истинно.
    Главное помнить, что если ваш пакет отсылается с клиента, и в зависимости его содержимого сервер производит какие-то действия, необходимо делать проверки на корректность полученных данных.

    Коммуникация Клиент ←→ Сервер с помощью SimpleNetworkWrapper ​

    Forge предоставляет SimpleNetworkWrapper для создания и обмена пакетами.
    Инструкции, как использовать этот метод вы найдете здесь:
    Статья из англоязычного источника
    Статья с форума

    Коммуникация Клиент ←→ Сервер с помощью библиотеки ElegantNetworking ​

    • Создание, удаление, перемещение, здоровье, и другие действия для сущностей.
    • Удаление и размещение блоков.
    • Добавление переменных DataWatcher в вашу сущность.
    • Контейнеры (инвентарь, печь и тд).

    Каждый элегантный пакет представляет из себя отдельный класс:

    EN packet structure.png

    sendToServer() — с клиента на сервер​
    ServerToClientPacket#
    sendToPlayer(player) — с сервера на клиент игрока​
    sendToClients() — с сервера на все клиенты​
    sendPacketToAllAround(world, x,y,z, range) — всем игрокам в радиусе вокруг точки​
    sendToDimension(world) — всем игрокам в измерении​

    sendToChunk(world, chunkX, chunkZ) — всем игрокам, которые находятся в пределах view distance вокруг чанка​

    Генерация, передача и получение сообщения (от клиента к серверу) проиллюстрированы на диаграмме ниже. Отправка сообщения от сервера к клиенту осуществляется по той же схеме.

    principle of networking.png

    • Дата-классы — это просто классы с полями, конструкторами, геттерами и сеттерами
    • Каждое поле пакета должно быть доступно для чтения в пределах package класса вашего пакета непосредственно или через геттер
    • Каждое изменяемое поле пакета должно быть доступно для присваивания непосредственно или через сеттер
    • Для неизменяемых полей должен быть конструктор с аргументами соответственно полям. Если неизменяемых полей нет, то должен быть конструктор без аргументов. Порядок аргументов должен совпадать с порядком объявления полей.
    • Поля, которые не нужно сериализовать, можно пометить модификатором transient

    public class Some < public final String str1; final String str2; //private-package private final String str3; //Приватное поле, но имеет геттер public int num1; private int num2; //Приватное поле, но имеет геттер и сеттер private boolean available; // Приватное поле, но имеет геттер и сеттер transient boolean service; // Какое-то служебное поле, которое не нужно сериализовывать public Some(String str1, String str2, String str3) < // Конструктор для всех финальных полей this.str1 = str1; this.str2 = str2; this.str3 = str3; >String getStr3() < return str3; >int getNum2() < return num2; >void setNum2(int v) < num2 = v; >boolean isAvailable() < // Для boolean можно использовать приставку is вместо get return available; >void setAvailable(boolean v) < available = v; >>

    • Примитивы, массивы, енумы, ItemStack, BlockPos, NBT тэги, ResourceLocation, UUID
    • Коллекции
    • Поддерживаются все стандартные коллекции и часто используемые коллекции из доступных в Forge библиотек
    • Кастомные коллекции пока не поддерживаются
    • Item, Block, Fluid, Potion и прочие. Конкретный список зависит от версии игры, его можно посмотреть в hohserg.elegant.networking.impl.RegistrableSingletonSerializer.RegistryHandler
    • Каждый такой абстрактный тип должен иметь хотя бы одну не абстрактную реализацию
    • Если реализаций много — будет как ADT сумма.

    interface Location < >public class FixedPos implement Location < final BlockPos pos; public FixedPos(BlockPos pos) < this.pos=pos; >> public class VolatilePos implement Location < final UUID playerId; public VolatilePos(UUID playerId) < this.playerId=playerId; >>

    • Эти правила применяются рекурсивно
    • Элементы коллекций должны им соответствовать
    • Типы полей дата-классов тоже

    Автор GlassSpirit Просмотры 6,374 Первый выпуск 25 Фев 2018 Обновление 6 Авг 2021 Оценка 4.80 звёзд 5 оценок

    Источник: forum.mcmodding.ru