Qveshn / LightAPI

Bukkit Library for create invisible light source
Other
29 stars 13 forks source link

don't see light #36

Open Timtaran opened 2 years ago

Timtaran commented 2 years ago

1.16.5 Paper image image

Qveshn commented 2 years ago
  1. Последний параметр в createLight (async) всегда ставьте false. Асинхронный режим работает некорректно

  2. createLight/deleteLight только создает/удаляет свет на сервере. Клиент об этом не знает, т.к. сервер не посылает сообщения клиенту об этом. Поэтому игрок увидит изменения только если он отбежит очень далеко и вернется обратно (даже перезагрузка чанков не поможет F3+A)

Это сделано специально, т.к. после каждого вызова этой функции посылать уведомления клиенту не рационально и это нагрузит сервер и клиент. Для оптимизации быстродействия клиенту посылается уведомления отдельной функцией updateLight, которая за раз отправляет пакет с информацией по всему чанку, указывая какие секции чанка (16х16х16) следует обновить.

В результате алгоритм использования API примерно следующий:

  1. Создаем/удаляем свет в блоках и тут же запоминаем в хэше (HashSet) список затронутых секций и чанков (свет одного блока распространяется с затуханием и может затрагивать несклько секций/чанков). Получить список потенциально затронутых секций/чанков можно функцией collectChunks.
  2. Далее в цикле по этому списку посылаем пакеты клиентам (игрокам) командой updateLight с информацией об обновленных чанках. Клиент перерисовывает на своей стороне свет в этих секциях/чанках. (updateLight всегда работает в асинхронном режиме)

Пример кода можно посмотреть тут: https://www.spigotmc.org/threads/lightapi-fork.278321/page-9#post-4228780

Первый пример без оптимизации. Он создает/удаляет свет в блоке и тут же отправляет клиентам пакеты об изменениях. Второй пример показывает принцип оптимизации. Он создает/удаляет свет сразу во многих блоках и коллекционирует список затронутых секций/чанков. А в конце уже отправляет пакеты клиентам.

Класс ChunkInfo в примере имеет кривое название (исторически сложилось). Он на самом деле означает инфу по секции чанка (16х16х16), а не по всему чанку (16х256х16). Т.е. updateLight на вход получает инфу по секции чанка и запоминает в своем внутреннем буфере. Далее уже плагин с указанной в конфиге периодичностью обрабатывает этот буфер. Берет от туда секции, агрегирует их по чанкам и уже потом отправляет клиентам пакеты об изменении в чанках.

Timtaran commented 2 years ago

Ок, есть вопрос по второму примеру, так как в Java я почти полный ноль: Как создать Collection и засунуть в него locations? про существование гугла знаю, но там не нашел 'Collection' is abstract; cannot be instantiated Если по подсказкам IntelijIdea делать, то Incompatible types. Found: 'boolean', required: 'java.util.Collection<org.bukkit.Location>'

Timtaran commented 2 years ago

Первый способ работал, но когда я его перенес на другой сервер, он не заработал ._. Возможно проблема в ядре Patina

image

Фото на локальном сервере image

BeYkeRYkt commented 2 years ago

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

Timtaran commented 2 years ago

ок, тогда попробую заменить на Paper

Timtaran commented 2 years ago

Да, проблема была в этом.

Qveshn commented 2 years ago

Collection это не класс, а интерфейс. Т.е. на вход во вторую функцию передается экземпляр класса, который реализует интерфейс "Collection". Есть много классов, которые реализуют этот интерфейс. Например ArrayList, HashSet, Vector и т.п. https://docs.oracle.com/javase/8/docs/api/java/util/Collection.html Полный перечень классов, которые реализуют данный интерфейс, смотри под заголовком "All Known Implementing Classes". В угловых скобочках Collection<Location> указывается тип каждого элемента коллекции.

Т.е. снаружи пишешь например так:

List<Location> list= new ArrayList<>(); // Интерфейс List тоже включает в себя итерфейс Collection
list.add(new Location(...));
list.add(new Location(...));
list.add(new Location(...));
setLight(list, 15, LightType.BLOCK);;
Qveshn commented 2 years ago

Да, со StarLight полная беда. Его сначала воткнули в Tuinity. Потом в Purpur. Вроде где то слышал что его собираются скоро воткнуть и в Paper.

Qveshn commented 2 years ago

В общем, как я и предполагал, StarLight уже воткнули в Paper. https://github.com/Qveshn/LightAPI/issues/37

Timtaran commented 2 years ago

вобщем я к счастью на 1.16.5, жаль что на Paper плагин на машины работает отвратительно.

Timtaran commented 2 years ago

кажись придется рыться в исходниках и пересобирать ядро

BeYkeRYkt commented 2 years ago

На скорую руку сделал патч для Starlight на 1.17: https://github.com/BeYkeRYkt/Paper/commit/48c517fb7b15239f30063759001c6b6740b62d7a

Патч содержит код только для блоков

И немного переписал плагин для проверки: https://github.com/BeYkeRYkt/LightAPI/tree/temp/5.0.0-starlight

Плагин содержит обратную совместимость со старым интерфейсом. Также проект содержит тестовый плагин для проверок с помощью блоков: красный блок, обсидиан и бедрок. На первый взгляд вроде работает, но могут быть некоторые приколы с переосвещением чанков.

Qveshn commented 2 years ago

o_O это надо курить))