Войти или зарегистрироваться
  • Вы находитесь в сообществе Rubukkit. Мы - администраторы серверов Minecraft, разрабатываем собственные плагины и переводим на различные языки плагины наших коллег из других стран.

Помогите Как получить список всех чанков и пролупить каждый блок?

Статус
Закрыто для дальнейших ответов.

Bars

Старожил
Девелопер
Пользователь
Баллы
173
Как получить список всех чанков и пролупить каждый блок?
 
Как получить список всех чанков и пролупить каждый блок?
world.getChunkAt(x, z) - получение произвольного чанка

Берёшь в цикле и перебираешь ручками по нужным координатам.

Есть так же метод для получения загруженных чанков, метода, который бы получил тебе все загруженные чанки нет, нужно самому обойти чанки по координатами и решить что с ними делать.
 
world.getChunkAt(x, z) - получение произвольного чанка

Берёшь в цикле и перебираешь ручками по нужным координатам.

Есть так же метод для получения загруженных чанков, метода, который бы получил тебе все загруженные чанки нет, нужно самому обойти чанки по координатами и решить что с ними делать.
Что посоветуете в плане производительности? Карта большая, плагин выполняться будет с вайт-листом, но все же.
 
Что посоветуете в плане производительности? Карта большая, плагин выполняться будет с вайт-листом, но все же.
Никакой производительности не будет. Несколько миллионов блоков невозможно комфортно обработать в реальном времени, только придумывать механизм очередей, разделять объёмы на части и пытаться в различных тиках делать обработку различных маленьких кусочков.
 
Как получить список всех чанков и пролупить каждый блок?

А что нужно делать?

Если — обрабатывать огромные участки, то рекомендую делать очередь, которая бы всё таки давала бы серверу "вздохнуть" и в процессе работы выводите в консоль или куда-то "прогресс: 0%, 5%, 10%....".
Блоки обрабатывайте именно почанково. Т.е. вцепились в чанк - и дальше ни ногой, пока в нём все не обработаете. При первом обращении к чанку, проверяйте загружен он или нет; выгружайте, если не был загружен.

Кстати, я обращал внимание, что иногда нужно ещё и принудительно сохранять чанки. Судя по всему, не всё хорошо работает в ядре сервера. При больших изменениях какие-то чанки при выгрузке не сохраняются.

Ну и подумайте насколько всё ресурсоемко? Может достаточно ловить событие загрузки чанка и на лету обрабатывать его (некоторые чанки куда игроки не добрались останутся не обработанными - так может и фиг с ними?)
 
Плагин находит определённые блоки в мире и сохраняет ID и координаты каждого подходящего блока в конфиг для последующего восстановления на другой карте (нет, это не перенос построек :)).

Дело в том, что карта рисуется и все чанки в ней уже сгенерированы, а хочется один раз поставить, провести желаемые действия и убрать плагин. До этого ответа я написал вот такой говнокод:
Java:
@Override
public boolean onCommand(CommandSender sender, Command command, String commandLabel, String[] args) {
    if (command.getName().equalsIgnoreCase("myplugin")) {
        if ((args.length != 2) || !(sender.hasPermission("myplugin.perform"))) return true;
        if (args[0].equalsIgnoreCase("save")) {
            Bukkit.getScheduler().runTaskAsynchronously(this, new OGSaveTask(this, args[1]));
            return true;
        }
    }

    return false;
}

Java:
package ru.onlymc.MyPlugin;

import org.bukkit.World;

public class OGSaveTask implements Runnable {
    private MyPlugin plugin;
    private World world;

    public OGSaveTask(MyPlugin p, String w) {
        plugin = p;
        world = plugin.getServer().getWorld(w);
    }

    @Override
    public void run() {
        int timer = 0;
        for (int y = plugin.miny; y < plugin.maxy; y++) {
            for (int x = plugin.minx; x < plugin.maxx; x++) {
                for (int z = plugin.minz; z < plugin.maxz; z++) {
                    if (timer == plugin.timer) try { Thread.sleep(plugin.sleep); } catch (InterruptedException e) {  };
                    int newid = world.getBlockTypeIdAt(x, y, z);
                    if (!plugin.newids.contains(newid)) continue;
                    plugin.config.getStringList("list").add(String.valueOf(newid + "," + y + "," + x + "," + z));
                    timer++;
                    // TODO Вывод в консоль процента и начала/окончания обработки блоков
                }
            }
        }
    }
}
Где miny, minx, minz - координаты угла на границе карты, а maxy, maxx, maxz - координаты противоположного угла. Т.е. от начала карты и 4 высоты до конца карты и 96 высоты. Эти координаты прописываются в конфиг, сделал не почанково. Не знаю, как получить все блоки в них и как итерировать для прохождения по всем чанкам (либо getLoadedChunks(), который только для загруженных чанков (а не для всех существующих), либо в циклах итерировать x и z с шагом по 16 блоков).
А что нужно делать?

Если — обрабатывать огромные участки, то рекомендую делать очередь, которая бы всё таки давала бы серверу "вздохнуть" и в процессе работы выводите в консоль или куда-то "прогресс: 0%, 5%, 10%....".
Блоки обрабатывайте именно почанково. Т.е. вцепились в чанк - и дальше ни ногой, пока в нём все не обработаете. При первом обращении к чанку, проверяйте загружен он или нет; выгружайте, если не был загружен.

Кстати, я обращал внимание, что иногда нужно ещё и принудительно сохранять чанки. Судя по всему, не всё хорошо работает в ядре сервера. При больших изменениях какие-то чанки при выгрузке не сохраняются.

Ну и подумайте насколько всё ресурсоемко? Может достаточно ловить событие загрузки чанка и на лету обрабатывать его (некоторые чанки куда игроки не добрались останутся не обработанными - так может и фиг с ними?)
Всего 141376 чанков (карта 6016х192х6016).
 
Последнее редактирование:
Плагин находит определённые блоки в мире и сохраняет ID и координаты каждого подходящего блока в конфиг для последующего восстановления на другой карте (нет, это не перенос построек :)).

Дело в том, что карта рисуется и все чанки в ней уже сгенерированы, а хочется один раз поставить, провести желаемые действия и убрать плагин. До этого ответа я написал вот такой говнокод:
Java:
@Override
public boolean onCommand(CommandSender sender, Command command, String commandLabel, String[] args) {
    if (command.getName().equalsIgnoreCase("myplugin")) {
        if ((args.length != 2) || !(sender.hasPermission("myplugin.perform"))) return true;
        if (args[0].equalsIgnoreCase("save")) {
            Bukkit.getScheduler().runTaskAsynchronously(this, new OGSaveTask(this, args[1]));
            return true;
        }
    }

    return false;
}

Java:
package ru.onlymc.MyPlugin;

import org.bukkit.World;

public class OGSaveTask implements Runnable {
    private MyPlugin plugin;
    private World world;

    public OGSaveTask(MyPlugin p, String w) {
        plugin = p;
        world = plugin.getServer().getWorld(w);
    }

    @Override
    public void run() {
        int timer = 0;
        for (int y = plugin.miny; y < plugin.maxy; y++) {
            for (int x = plugin.minx; x < plugin.maxx; x++) {
                for (int z = plugin.minz; z < plugin.maxz; z++) {
                    if (timer == plugin.timer) try { Thread.sleep(plugin.sleep); } catch (InterruptedException e) {  };
                    int newid = world.getBlockTypeIdAt(x, y, z);
                    if (!plugin.newids.contains(newid)) continue;
                    plugin.config.getStringList("list").add(String.valueOf(newid + "," + y + "," + x + "," + z));
                    timer++;
                    // TODO Вывод в консоль процента и начала/окончания обработки блоков
                }
            }
        }
    }
}
Где miny, minx, minz - координаты угла на границе карты, а maxy, maxx, maxz - координаты противоположного угла. Т.е. от начала карты и 4 высоты до конца карты и 96 высоты. Эти координаты прописываются в конфиг, сделал не почанково. Не знаю, как получить все блоки в них и как итерировать для прохождения по всем чанкам (либо getLoadedChunks(), который только для загруженных чанков (а не для всех существующих), либо в циклах итерировать x и z с шагом по 16 блоков).

Всего 141376 чанков (карта 6016х192х6016).
Для переноса построек есть WE со схематиками- мне страшно представить сколько итоговый файлик будет весить, ведь это текстовая информация.
 
Для переноса построек есть WE со схематиками- мне страшно представить сколько итоговый файлик будет весить, ведь это текстовая информация.
Плагин находит определённые блоки в мире и сохраняет ID и координаты каждого подходящего блока в конфиг для последующего восстановления на другой карте (нет, это не перенос построек).

Ладно, открою завесу тайны - это málmgrýti.
 
Собственно не важно для чего осуществляется перебор блоков, но "for (int z = plugin.minz; z < plugin.maxz; z++)" — это как раз "неэффективный" момент, поскольку идёт поблочный перебор.
Просто если Вы весь этот объем блоков будете прогонять поблочно, то в какой-то момент времени будет загружено в память столько чанков, что сервер просто упадёт.

Координаты чанка можно получить допустим, вычисляя из координат (координату делим на 16 и получаем координату чанка):

for (int z=plugin.minz>>4; z<=plugin.maxz>>4;z++)

Здесь, z - это уже будут координаты чанка. Соответственно циклично (по x и z) перебираем чанки, а уже в них - координаты от 0 до 15 (соответственно и для x и для z):

Кроме того, я опять же повторюсь. Для огромных объёмов лучше сделать очередь.
Допустим циклом выбрали список чанков. А потом уже по одному их из этого списка обрабатываете. При этом для себя считаете сколько нужно обрабатывать: либо какое-то фиксированное число на тик. Либо же динамически, считаете сколько затрачивается время и на основе этого обрабатываете то или иное количество чанков.
Интересно, это хорошо или плохо, что я не знаю что это такое или на что Вы намекаете ;)
 
не заметил.
ну всё равно. как-то бестолково.
Если бы можно было отключить пруды в генераторе, не пришлось бы делать такие костыли.
ZM37LqQ.png

CuKx57J.png
Интересно, это хорошо или плохо, что я не знаю что это такое или на что Вы намекаете ;)
Руды :)
 
Последнее редактирование:
Т.е. вместо того, чтобы раскидать руды на другой карте случайным образом - мы будем копировать их месторасположение? Хотя бы собственными ручками.
- Просто великолепный выход, достойный программиста.
 
Т.е. вместо того, чтобы раскидать руды на другой карте случайным образом - мы будем копировать их месторасположение? Хотя бы собственными ручками.
- Просто великолепный выход, достойный программиста.
WorldPainter на такое не способен. Он сообщает Minecraft'у, что карта недогенерирована, т.е. переводит на стадию генерации на ней деревьев, руд, грибов, деревень, домов ведьм и т.д. Вот цитата с ветки на форуме:
Worldpainter does not populate the world when you use "populate". http://www.worldpainter.net/trac/wiki/Populate
It simply tells minecraft a stage in the terrain generation proces hasn't been completed yet and minecraft will finish it.
Перевод: "Это просто сообщает Minecraft'у, что этап генерации местности ещё не был завершён и Minecraft должен будет его завершить.".

Т.е. это этап генерации карты, на котором создаются месторождения руд, расставляются деревья и грибы (в грибном биоме), образуются пруды и так далее.
 
WorldPainter на такое не способен. Он сообщает Minecraft'у, что карта недогенерирована, т.е. переводит на стадию генерации на ней деревьев, руд, грибов, деревень, домов ведьм и т.д. Вот цитата с ветки на форуме:
Перевод: "Это просто сообщает Minecraft'у, что этап генерации местности ещё не был завершён и Minecraft должен будет его завершить.".

Т.е. это этап генерации карты, на котором создаются месторождения руд, расставляются деревья и грибы (в грибном биоме), образуются пруды и так далее.
А нет такого варианта, как взять и вместо стандартного генератора прилепить свой, который прогенерирует руды, деревья, но пруды не будет генерировать?
 
А нет такого варианта, как взять и вместо стандартного генератора прилепить свой, который прогенерирует руды, деревья, но пруды не будет генерировать?
В том и дело. Я не умею работать с генератором, для меня это тёмный лес.
Я даже когда-то делал запрос, вот: http://www.rubukkit.org/threads/Запрет-генерации-этих-уродств.62584/
Всё же руды не вариант. Мне нужна генерация грибов и подземелий, но не нужна генерация прудов, деревьев и пещер. Как можно воздействовать на генератор?
 
В том и дело. Я не умею работать с генератором, для меня это тёмный лес.
Я даже когда-то делал запрос, вот: http://www.rubukkit.org/threads/Запрет-генерации-этих-уродств.62584/
Всё же руды не вариант. Мне нужна генерация грибов и подземелий, но не нужна генерация прудов, деревьев и пещер. Как можно воздействовать на генератор?
* Переопределить
* Сделать свою генерацию
* Скопировать существующую и подправить под себя
* Использовать чужой генератор-плагин и правильно его настроить
 
В том и дело. Я не умею работать с генератором, для меня это тёмный лес.
Я даже когда-то делал запрос, вот: http://www.rubukkit.org/threads/Запрет-генерации-этих-уродств.62584/
Всё же руды не вариант. Мне нужна генерация грибов и подземелий, но не нужна генерация прудов, деревьев и пещер. Как можно воздействовать на генератор?
На сколько я знаю, пещеры генерируются на стадии создания чанка. Грибы, деревья, пруды, руды генерируются на стадии постобработки чанков. В букките грибы -- разновидность деревьев, в генератор не лазил за этим.
 
Статус
Закрыто для дальнейших ответов.

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

Назад
Верх