Перейти к содержанию

Прокси#

Перед началом создания модов надо понять и правильно использовать очень важную вещь.

Дело в том, что Minecraft состоит из нескольких частей:

  • Физический клиент - это программа, которую вы запускаете с помощью лаунчера.
  • Физический сервер - это программа, которая запускается с помощью файлов типа minecraft_server.jar.
  • Логический клиент отвечает за отображение моделей и текстур, за прием данных от мышки и клавиатуры, за отображение GUI.
  • Логический сервер отвечает за всю игровую логику: спавн мобов, погоду, обновление инвентарей, AI и все другие механики игры.

Зачем надо это знать? А затем, что при попытке выполнить отрисовку текстуры блока на стороне сервера он незамедлительно крашнется! И наоборот, попытка реализовывать игровую механику (открытие GUI, создание взрывов) на стороне клиента может привести к непредсказуемым багам, появлению пустых твердых блоков, рассинхронизации и так далее...

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

CommonProxy#

Для начала нам надо создать класс для выполнения действий, которые должны выполняться на стороне и клиента, и сервера.

Для этого создайте пакет common внутри пакета нашего мода и класс CommonProxy внутри него. Объявите внутри класса три уже знакомых вам метода:

  • preInit
  • init
  • postInit
public class CommonProxy {
    public void preInit(FMLPreInitializationEvent event) {

    }

    public void init(FMLInitializationEvent event) {

    }

    public void postInit(FMLPostInitializationEvent event) {

    }
}

ClientProxy#

Теперь создадим класс для действий, которые должны выполняться только на стороне клиента, а именно:

  • Регистрация моделей блоков/мобов/предметов
  • Регистрация рендеров этих самых моделей

Для этого создадим класс ClientProxy, наследующий класс CommonProxy в пакете client:

public class ClientProxy extends CommonProxy {
    @Override
    public void preInit(FMLPreInitializationEvent event) {
        super.preInit(event);
    }

    @Override
    public void init(FMLInitializationEvent event) {
        super.init(event);
    }

    @Override
    public void postInit(FMLPostInitializationEvent event) {
        super.postInit(event);
    }
}

Заметьте, что мы вызываем все три метода из CommonProxy с помощью super, чтобы они обязательно выполнились на стороне клиента.

Регистрация в главном файле#

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

Теперь вернемся в главный файл нашего мода и скажем Forge об этом. Для того чтобы это сделать, создадим переменную proxy типа CommonProxy и добавим к ней аннотацию @SidedProxy:

public class McModding {
    @SidedProxy(
            clientSide = "ru.mcmodding.tutorial.client.ClientProxy",
            serverSide = "ru.mcmodding.tutorial.common.CommonProxy"
    )
    public static CommonProxy proxy;
}

Эта аннотация содержит два поля, которые обозначают пути до классов ClientProxy и CommonProxy. При запуске, Forge будет автоматически определять нужную сторону (клиент/сервер) и создавать объект класса ClientProxy или CommonProxy.

Последнее, что нам нужно сделать: выполнить три метода (pre, init, post) в нашем главном файле мода:

public class McModding {
    @Mod.EventHandler
    public void preInit(FMLPreInitializationEvent event) {
        proxy.preInit(event);
    }

    @Mod.EventHandler
    public void init(FMLInitializationEvent event){
        proxy.init(event);
    }

    @Mod.EventHandler
    public void postInit(FMLPostInitializationEvent event) {
        proxy.postInit(event);
    }
}

Полный код главного файла мода:

package ru.mcmodding.tutorial;

import cpw.mods.fml.common.Mod;
import cpw.mods.fml.common.SidedProxy;
import cpw.mods.fml.common.event.FMLInitializationEvent;
import cpw.mods.fml.common.event.FMLPostInitializationEvent;
import cpw.mods.fml.common.event.FMLPreInitializationEvent;
import ru.mcmodding.tutorial.common.CommonProxy;

@Mod(modid = MODID, version = VERSION)
public class Tutorial {
    public static final String MOD_ID = "mcmodding";
    public static final String VERSION = "1.0.0";

    @SidedProxy(
            clientSide = "ru.mcmodding.tutorial.client.ClientProxy",
            serverSide = "ru.mcmodding.tutorial.common.CommonProxy"
    )
    public static CommonProxy proxy;

    @Mod.EventHandler
    public void preInit(FMLPreInitializationEvent event) {
        proxy.preInit(event);
    }

    @Mod.EventHandler
    public void init(FMLInitializationEvent event) {
        proxy.init(event);
    }

    @Mod.EventHandler
    public void postInit(FMLPostInitializationEvent event) {
        proxy.postInit(event);
    }
}