Хостинг серверов Minecraft playvds.com
  1. Вы находитесь в русском сообществе Bukkit. Мы - администраторы серверов Minecraft, разрабатываем собственные плагины и переводим на русский язык плагины наших собратьев из других стран.
    Скрыть объявление

Разработка плагина на регенерацию мира с сохранением приватов

Тема в разделе "Разработка плагинов для новичков", создана пользователем amorphine, 12 июн 2016.

Статус темы:
Закрыта.
  1. Автор темы
    amorphine

    amorphine Новичок

    Баллы:
    16
    Всем привет, недавно увлекся серверостроением майнкрафта и столкнулся с проблемой, что очень хочется повторить функционал плагина на проекте Mconly.
    У них раз в месяц проводится очистка территории - полная регенерация всего, за исключением приватов - они остаются нетронутыми. Я сейчас вырабатываю стратегию, пишу первый код, однако столкнулся с философской дилеммой.
    Наиболее простой способ сохранить приваты - экспорт их в БД в виде блоба(schematic). Однако проблемно получить сам блоб.
    Казалось бы, можно использовать worldedit - да, но для работы с экспортом регионов ему требуется Player/
    Есть ли возможность экспортировать регион, зная лишь его координаты? Спасибо.
     
  2. Хостинг MineCraft
    <
  3. Dereku

    Dereku Старожил

    Баллы:
    173
    Skype:
    derek_unavailable
    Имя в Minecraft:
    _Dereku
    Смотри AutoSaveWorld от Шевчика. В схематики сохранения там были вроде бы в 15 году.
     
  4. alexandrage

    alexandrage Администратор

    Баллы:
    173
    Skype:
    alexandr0116
    Лучше удалять чанки где нет регионов, это будет в разы быстрее. Потом они сами отрегенятся при загрузке.
     
  5. fall.us

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

    Баллы:
    76
    Имя в Minecraft:
    fallus
    Накидал за часик:
    SchematicMaster.ajav
    Код:
    import java.io.ByteArrayOutputStream;
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.util.LinkedList;
    
    import org.bukkit.Location;
    import org.bukkit.Material;
    import org.bukkit.block.Block;
    
    import ru.fallus.modifire.lib.ByteUtils;
    
    public class SchematicMaster
    {
        private Schemaster plugin;
    
        private File schematicFolder;
    
        public SchematicMaster(final Schemaster plugin)
        {
            this.plugin = plugin;
    
            schematicFolder = plugin.getDataFolder();
        }
    
        public void saveSchematic(Location loc1, Location loc2, String name) throws IOException
        {
            int minX = Math.min(loc1.getBlockX(), loc2.getBlockX());
            int maxX = Math.max(loc1.getBlockX(), loc2.getBlockX());
    
            int minY = Math.min(loc1.getBlockY(), loc2.getBlockY());
            int maxY = Math.max(loc1.getBlockY(), loc2.getBlockY());
    
            int minZ = Math.min(loc1.getBlockZ(), loc2.getBlockZ());
            int maxZ = Math.max(loc1.getBlockZ(), loc2.getBlockZ());
    
            File file = new File(schematicFolder, name + ".sch");
    
            if(!file.exists())
            {
                plugin.getDataFolder().mkdirs();
       
                file.createNewFile();
            }
    
            FileOutputStream os = new FileOutputStream(file);
    
            for(int x = minX; x < maxX; x++)
            {
                for(int y = minY; y < maxY; y++)
                {
                    for(int z = minZ; z < maxZ; z++)
                    {
                        Block block = loc1.getWorld().getBlockAt(x, y, z);
               
                        if(block.getType() == Material.AIR)
                            continue;
               
                        //использаем числа в диапазоне 0 - 65535
                        short localX = (short) (x - minX);
                        short localY = (short) (y - minY);
                        short localZ = (short) (z - minZ);
               
                        short id = (short) block.getTypeId();
               
                        byte data = block.getData();
               
                        ByteArrayOutputStream bos = new ByteArrayOutputStream();
               
                        //writing 9 bytes(in total) per block
                        bos.write(ByteUtils.makeBytes(localX));
                        bos.write(ByteUtils.makeBytes(localY));
                        bos.write(ByteUtils.makeBytes(localZ));
                        bos.write(ByteUtils.makeBytes(id));
                        bos.write(new byte[]{ data });
               
                        os.write(bos.toByteArray());
                    }
                }
            }
    
            os.close();
        }
    
        public LinkedList<SchematicBlock> loadSchematic(String name) throws IOException
        {
            File file = new File(schematicFolder, name + ".sch");
    
            if(!file.exists())
                return null;
    
            //файл поврежден или данные записаны неверно
            if(file.length() % 9 != 0)
                return null;
    
            FileInputStream is = new FileInputStream(file);
    
            //для хранения большого кол-ва элементов
            LinkedList<SchematicBlock> blocks = new LinkedList<SchematicBlock>();
    
            //количество блоков, записанных в файле
            long blockCount = (long) (file.length() / 9);
    
            for(long i = 0; i < blockCount; i++)
            {
                byte[] bytes = new byte[9];
       
                if(is.read(bytes) == 9)
                {
                    SchematicBlock b = new SchematicBlock();
           
                    b.localX     = ByteUtils.makeShort(bytes, 0);
                    b.localY     = ByteUtils.makeShort(bytes, 2);
                    b.localZ     = ByteUtils.makeShort(bytes, 4);
                    b.id         = ByteUtils.makeShort(bytes, 6);
                    b.data        = bytes[8];
           
                    blocks.add(b);
                }
            }
    
            is.close();
    
            return blocks;
        }
    }
    

    SchematicBlock.jvaa
    Код:
    import org.bukkit.Location;
    import org.bukkit.Material;
    
    public class SchematicBlock
    {
        public short localX = 0;
        public short localY = 0;
        public short localZ = 0;
    
        public short id = 0;
    
        public byte data = 0x00;
    
        public void apply(Location origin)
        {
            Location loc = new Location(origin.getWorld(), origin.getBlockX() + localX, origin.getBlockY() + localY, origin.getBlockZ() + localZ);
    
            loc.getBlock().setType(Material.getMaterial(id));
            loc.getBlock().setData(data);
        }
    }
    

    Загрузка schematic:
    Код:
    public boolean loadAndApplySchematic(Location origin, String name)
    {
        LinkedList<SchematicBlock> blocks;
    
        try
        {
            blocks = sm.loadSchematic(name);
     
            Iterator<SchematicBlock> i = blocks.iterator();
     
            //если выполняете анинхронно
            Bukkit.getScheduler().runTask(this, () -> {
                while(i.hasNext())
                {
                    SchematicBlock b = i.next();
         
                    b.apply(origin);
              }});
        }
        catch (IOException e)
        {
            e.printStackTrace();
     
            return false;
        }
    
        return true;
    }
    Надеюсь, как работать с байтами Вы знаете. Если нет, могу скинуть свой ByteUtils.java
     
    Последнее редактирование: 12 июн 2016
  6. Shevchik

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

    Баллы:
    173
    Имя в Minecraft:
    _Shevchik_
    Всё зависит от того сколько весит мир, и сколько на нём регионов. Но удалять чанки тупо надёжнее, не надо потом мудохаться с правильной вставкой схематиков обратно.
     
  7. Автор темы
    amorphine

    amorphine Новичок

    Баллы:
    16
    Спасибо за код, очень лаконичный и понятный. Если не возражаете, я вам в ЛС отпишусь. Так же обещаю, что не буду использовать в коммерческих целях или выкладывать в общий доступ без разрешения)

    Согласен, однако можно использовать этот подход для выполнения основной грубой работы, а для тонкой, с чанками с приватами - от fall.us. Теоретически, это позволит добиться того, что нужно. Спасибо за ответы.
     
  8. fall.us

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

    Баллы:
    76
    Имя в Minecraft:
    fallus
    Если бы я не хотел, чтобы мой код кто-то использовал, я бы его нигде не выкладывал))
    Делайте что хотите.
     
  9. Lord9000

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

    Баллы:
    103
    Регенерация от шевчика, как-то криво работает, по крайней мере у меня.
     
  10. alexandrage

    alexandrage Администратор

    Баллы:
    173
    Skype:
    alexandr0116
    Потому лучше и быстрее не проводить регенерацию, а просто обрезать чанки где нет регионов. Лучше пусть останется чанк рядом с регионом, чем реген отсетает содержимое сунтуков с края региона.
     
  11. Lord9000

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

    Баллы:
    103
    Согласен, но чем можно это сделать?
     
  12. Автор темы
    amorphine

    amorphine Новичок

    Баллы:
    16
  13. Lord9000

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

    Баллы:
    103
  14. fall.us

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

    Баллы:
    76
    Имя в Minecraft:
    fallus
    Мой сервер регенерирует чанки со скоростью чуть больше 100 чанков/сек. Имея мир с максимальным размером в 30 млн. блоков, получаю 1.875.000 * 1.875.000 чанков. Итого получаю 1000+ лет регенерации*. В планетарных масштабах может и быстро))...
    (* - при регенерации от x=z=-1875000,до x1=z1=1875000).

    А если серьезно, то я могу помочь товарищу @amorphine написать такой плагин(если тот попросит).
     
    Последнее редактирование: 12 июн 2016
  15. Lord9000

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

    Баллы:
    103
    Ну что могу сказать. Пытайтесь. На самом деле я думаю, что этот плагин будет не совместим с модами (екстарбиомс, биомопленти, сум. лес) По крайней мере стандартный WorldEdit не работает с ними)
     
  16. Dereku

    Dereku Старожил

    Баллы:
    173
    Skype:
    derek_unavailable
    Имя в Minecraft:
    _Dereku
    Удаляя чанки с карты мы ломаем совместимость с Forge? Куда смеяться?
     
  17. Lord9000

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

    Баллы:
    103
    Ты не понял. Я привёл в пример известный плагин WE. В его функционале есть команда //regen но при её использовании он использует плагин просто игнорирует наличие генерации других модов. А регенерирует мир чисто по seed
     
  18. Dereku

    Dereku Старожил

    Баллы:
    173
    Skype:
    derek_unavailable
    Имя в Minecraft:
    _Dereku
    Так то он так же использует баккитовский метод регенерации (использовал?). Ну и как пишут создатели модов - работоспособность модов на ядре с bukkit api не гарантируется.
     
  19. Shevchik

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

    Баллы:
    173
    Имя в Minecraft:
    _Shevchik_
    Реген и удаление чанков не одно и то же.
     
  20. Lord9000

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

    Баллы:
    103
    Ошибься
     
Статус темы:
Закрыта.

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