Иконка ресурса

Вырезалка 2

Версия(и) Minecraft
1.7.10+
Что это такое
Вырезалка это плагин для градла. Она нужна для автоматического вырезания клиентского кода из серверных билдов.
Разграничение серверного кода и клиентского происходит через аннотации.


Установка
Тут все стало значительно проще. Я все-таки обзавелся доменом в мавен централе и теперь применение снапшота выглядит вот так:
Gradle (Groovy):
buildscript {
    repositories {
        maven {
            url 'https://oss.sonatype.org/content/repositories/snapshots/'
        }
    }
    dependencies {
        classpath 'tech.justagod:cutter:2.1.0-SNAPSHOT'
    }
}
apply plugin: 'cutter'
Stable версии уже стоит смотреть в поиске.

Пример для 1.7.10
Java:
buildscript {
    repositories {
        mavenCentral()
        maven {
            name = "forge"
            url = "https://files.minecraftforge.net/maven"
        }
        maven {
            name = "maven"
            url = "https://repo1.maven.org/maven2"
        }
        maven {
            name = "sonatype"
            url = "https://oss.sonatype.org/content/repositories/snapshots/"
        }
    }
    dependencies {
        classpath 'tech.justagod:cutter:2.1.0-SNAPSHOT'
        classpath 'net.minecraftforge.gradle:ForgeGradle:1.2-SNAPSHOT'
    }
}

apply plugin: 'cutter'
apply plugin: 'forge'
И для 1.8
Gradle (Groovy):
buildscript {
    repositories {
        mavenCentral()
        maven {
            name = "sonatype"
            url = "https://oss.sonatype.org/content/repositories/snapshots/"
        }
    }
    dependencies {
        classpath 'tech.justagod:cutter:2.1.0-SNAPSHOT'
    }
}
plugins {
    id "net.minecraftforge.gradle.forge" version "2.0.2"
}
apply plugin: 'cutter'
Настройка
Вырезалка довольно гибкий в настройке плагин, но мне сказали, что гибкость не нужна. Нужно что б все было просто.

Теперь настройка представляет из себя одну строку
cutter.initializeDefault(true, false)
1 true - включать ли дефолтную либу вырезалки в целевой жарник
2 false - включать ли эвристику (о ней позже)

Ее нужно сунуть где то в конец вашего build.gradle но до секции dependencies.


С более брутальной настройкой вы можете ознакомится в репозитории: Cutter

Примеры

Вырезалка добавит 3 таска: buildClient, buildServer и buildAll.
Что они делают думаю кристально понятно.

Далее примеры аннотирования

Вырезание класса:
Java:
package com.example.examplemod;                   
                                                  
import net.minecraft.init.Blocks;                 
import cpw.mods.fml.common.Mod;                   
import cpw.mods.fml.common.Mod.EventHandler;       
import cpw.mods.fml.common.event.FMLInitializationEvent;
                                                  
import ru.justagod.cutter.*;                       
                                                  
@Mod(modid = ExampleMod.MODID, version = ExampleMod.VERSION)
@GradleSideOnly(GradleSide.SERVER)
public class ExampleMod
{                                         
    public static final String MODID = "examplemod";
    public static final String VERSION = "1.0";
}

Вырезание только методов:
Java:
package com.example.examplemod;                                                                           
                                                                                                          
import net.minecraft.init.Blocks;                                                                         
import cpw.mods.fml.common.Mod;                                                                           
import cpw.mods.fml.common.Mod.EventHandler;                                                             
import cpw.mods.fml.common.event.FMLInitializationEvent;                                                 
                                                                                                          
import ru.justagod.cutter.*;                                                                             
                                                                                                          
@Mod(modid = ExampleMod.MODID, version = ExampleMod.VERSION)                                             
@GradleSideOnly(GradleSide.SERVER)                                                                       
public class ExampleMod                                                                                   
{                                                                                                         
    public static final String MODID = "examplemod";                                                     
    public static final String VERSION = "1.0";                                                           
                                                                                                          
    @GradleSideOnly(GradleSide.SERVER)                                                                   
    public void server() {}                                                                               
                                                                                                          
    @GradleSideOnly(GradleSide.CLIENT)                                                                   
    public void client() {}                                                                               
}

Для вырезания директории целиком нужно завести в ней же файл package-info.java и пихнуть туда вот такой код:
Java:
@GradleSideOnly(GradleSide.CLIENT)
package com.example;

import ru.justagod.cutter.*;

Иногда нужно вырезать только отдельную часть тела метода. Про это можно прочитать в репозитории в разделе инвокаторов и обсуждения в этой теме.
В дефолтной настройки вырезалки можно использовать класс-агрегатор ru.justagod.cutter.invoke.Invoke

Валидация 2.1.0+
Во время сборки, после вырезания, но до упаковки в результирующий бинарник вырезалка будет проводить валидацию. Это значит, что она будет пытаться найти такие моменты когда вы дергаете клиентские классы из серверного кода или серверные из клиентского. Если она найдет такие случаи, она выведет их всех в консоль и выбросит исключение. Это значит, что в итоге бинарник она не соберет.
Чтобы отключить валидацию, нужно прописать cutter.validation = false. Я, конечно же, очень не советую так делать.
Также существует возможность отключить валидацию для класса/метода/поля при помощи аннотации. Это самая опасная штука валидации потому в стандартной конфигурации эта аннотация задана не будет. Если кому-то это все же будет действительно нужно, welcome разбираться тык

Инвокаторы 2.1.0+
Иногда возникает необходимость вырезать не весь метод, а только его часть. Для таких целей в вырезалеке есть класс ru.justagod.cutter.invoke.Invoke.
Клиентский код оборачивать в Invoke.client(() -> clientCode()).
Серверный код оборачивать в Invoke.server(() -> serverCode()).

Содержимое лямбд будет вырезано на соответствующих билдах.


Также иногда возникает необходимость вернуть значение из вот такой вот лямбды. Тут все тоже очень просто.
Клиентский код оборачивать в Object a = Invoke.clientValue(() -> clientCode()).
Серверный код оборачивать в Object a = Invoke.serverValue(() -> serverCode()).

clientValue на сервере всегда будет возвращать null вместо объектов и дефолтное значение вместо примитивов.

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


Эвристика 2.1.0+
Я уверен, что у многих в коде есть что-то типа
Java:
if (world.isRemote)
    // client code
} else {
    // server code
}
И в целом было бы удобно если бы такие куски кода вырезались бы без применения инвокаторов. И именно эту проблему решает эвристика. Она на базе используемых в if выражениях полях и методах делает предположения о том куда может зайти код, а куда не может.
Это все настраивается достаточно гибко, но в дефолтной конфигурации эвристика смотрит только на world.isRemote , если кому то этого покажется мало, милости просим читать документацию в репо.

Эвристика на данный момент фича экспериментальная, а как следствие дефолтная конфигурация не включает ее по дефолту.
Чтобы исправить эту ситуацию нужно написать cutter.initializeDefault(true, true)


Немного про анализ
Вырезалка будет ожидать, что вы будете ставить аннотацию над классом, методом, полем или в package-info. Помимо очевидных эффектов (вырезание конкретно данной сущности) еще происходят следующие явления:
  • Все наследники удаленного класса/интерфейса также будут вырезаны
  • Все методы, переопределяющие удаленный метод, также будут удалены
  • Все классы объявленные в удаленном классе или методе также будут удалены
  • Методы, имплементящие тело лямбд в удаленных методах, также будут удалены
В остальном вырезалка ведет себе достаточно интуитивно👀

Еще пара слов про настройку

Тут просто хочу заметить, что вы можете изменять дефолтную конфигурацию не полностью. Это значит, что можно применить ее, а потом еще пару шагов(не все) применить отсюда

Заключение
Если после прочтения данной темы вы что-то не поняли, вы можете ознакомится с моим отвратительным видосиком для 1.7.10 тык



Peace!
Автор
JustAGod
Просмотры
5,233
Первый выпуск
Обновление
Оценка
5.00 звёзд 4 оценок

Другие ресурсы пользователя JustAGod

Последние обновления

  1. Новый год - новая вырезалка

    крч прикол жесть Извиняюсь, что так надолго забил на тему, но меня все-таки распинали обновить...

Последние рецензии

Работа то хорошая, но мне кажется полегче будет с final boolean'ами и просто проверками
Меньше чем за 2 минуты мне удалось разбить свой бод на клиентский и серверный билд. Просто, быстро, работоспособно и с большой возможностью настройки. 10/10!
Молодец, классная вещь! Правда, мне кажется настройка очень сложная. Надо чтобы вот чтобы скачать только - а дальше она все сама. И еще мод за меня чтобы писала.
JustAGod
JustAGod
настройка состоит из одной строчки. куда проще то...
Потрясная штука! Юзаю для EM, чтобы в релизные билды не входил дебажный код
https://github.com/EndersMagic/EnderMagic/blob/just-a-cut-debug-code/build.gradle#L32
Стоит добавить ресурсу иконку
Сверху