- 192
- 2
- 9
Всем привет. Сразу скажу, что я не прошу помогать мне что-то фиксить. Я прошу лишь объяснить на пальцах, как работает прокси. Если я смогу понять эту тему, вряд ли я буду приходить на форум с подобными вопросами в поисках решений! Я читал ряд статей, в том числе и статью большую (где-то тут) отведенную конкретно под прокси, но вопросы всё еще остаются.
Собрал сборку, решил поиграть, но сервер не запускается из-за крашей. Краш вполне себе понятный, сервер пытается обратиться к клиентским полям (иногда и к классам):
Залезаю в код предмета, вижу нечто подобное:
Прокси:
Дальше по иерархии:
Главный класс:
И вот чего я не могу понять... Регистрация предметов происходит в
То есть сервер обрабатывает методы с
Заранее спасибо!
Собрал сборку, решил поиграть, но сервер не запускается из-за крашей. Краш вполне себе понятный, сервер пытается обратиться к клиентским полям (иногда и к классам):
Краш:
cpw.mods.fml.common.LoaderException: java.lang.NoSuchFieldError: icons
at cpw.mods.fml.common.LoadController.transition(LoadController.java:163)
at cpw.mods.fml.common.Loader.preinitializeMods(Loader.java:559)
at cpw.mods.fml.server.FMLServerHandler.beginServerLoading(FMLServerHandler.java:88)
at cpw.mods.fml.common.FMLCommonHandler.onServerStart(FMLCommonHandler.java:314)
at net.minecraft.server.dedicated.DedicatedServer.func_71197_b(DedicatedServer.java:117)
at net.minecraft.server.MinecraftServer.run(MinecraftServer.java:387)
at net.minecraft.server.MinecraftServer$2.run(MinecraftServer.java:685)
Caused by: java.lang.NoSuchFieldError: icons
at thaumrev.item.armor.ItemThauminiteFortressArmor.<init>(ItemThauminiteFortressArmor.java:33)
at thaumrev.config.ConfigItems.initializeThaumicBasesIntegration(ConfigItems.java:118)
at thaumrev.config.ConfigItems.init(ConfigItems.java:30)
at thaumrev.common.CommonProxy.preInit(CommonProxy.java:28)
at thaumrev.ThaumicRevelations.preInit(ThaumicRevelations.java:57)
Залезаю в код предмета, вижу нечто подобное:
ItemThauminiteFortressArmor:
package thaumrev.item.armor;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import java.util.ArrayList;
import java.util.List;
import net.minecraft.client.model.ModelBiped;
import net.minecraft.client.renderer.texture.IIconRegister;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.EnumAction;
import net.minecraft.item.EnumRarity;
import net.minecraft.item.ItemArmor;
import net.minecraft.item.ItemStack;
import net.minecraft.util.DamageSource;
import net.minecraft.util.EnumChatFormatting;
import net.minecraft.util.IIcon;
import net.minecraft.util.StatCollector;
import net.minecraftforge.common.ISpecialArmor;
import net.minecraftforge.oredict.OreDictionary;
import thaumcraft.api.IGoggles;
import thaumcraft.api.IRepairable;
import thaumcraft.api.IRunicArmor;
import thaumcraft.api.IVisDiscountGear;
import thaumcraft.api.aspects.Aspect;
import thaumcraft.api.nodes.IRevealer;
import thaumrev.client.models.ModelThauminiteFortressArmor;
import thaumrev.config.ConfigLibrary;
public class ItemThauminiteFortressArmor extends ItemArmor implements IRepairable, IRunicArmor, ISpecialArmor, IGoggles, IRevealer, IVisDiscountGear {
@SideOnly(Side.CLIENT)
public IIcon[] icons = new IIcon[3];
@SideOnly(Side.CLIENT)
ModelBiped[] models = new ModelBiped[3];
public ItemThauminiteFortressArmor(int type, String name) {
super(ConfigLibrary.armorMaterialFortressThauminite, 4, type);
this.setUnlocalizedName(name);
this.setCreativeTab(ConfigLibrary.tabThaumRev);
}
public int getVisDiscount(ItemStack armor, EntityPlayer entityPlayer, Aspect aspect) { return 4; }
public ArmorProperties getProperties(EntityLivingBase player, ItemStack armor, DamageSource source, double damage, int slot) {
int priority = 1;
double ratio = this.damageReduceAmount / 20.0D;
if (source.isMagicDamage()) ratio = this.damageReduceAmount / 35.0D;
else if (!source.isFireDamage() && !source.isExplosion() && source.isUnblockable()) {
ratio = 0.0D;
priority = 0;
}
if (player instanceof EntityPlayer) {
double set = 0.875D;
for (ItemStack piece : ((EntityPlayer)player).inventory.armorInventory) {
if (piece != null && piece.getItem() instanceof ItemThauminiteFortressArmor) {
set += 0.125D;
if (piece.hasTagCompound() && piece.stackTagCompound.hasKey("mask")) set += 0.05D;
}
}
ratio *= set;
}
return new ISpecialArmor.ArmorProperties(priority, ratio, armor.getMaxDamage() + 1 - armor.getItemDamageForDisplay());
}
public EnumRarity getRarity(ItemStack armor) { return EnumRarity.rare; }
public void addInformation(ItemStack armor, EntityPlayer player, List<String> list, boolean par4) {
if (armor.hasTagCompound() && armor.stackTagCompound.hasKey("goggles"))
list.add(EnumChatFormatting.DARK_PURPLE + StatCollector.translateToLocal("item.ItemGoggles.name"));
if (armor.hasTagCompound() && armor.stackTagCompound.hasKey("mask"))
list.add(EnumChatFormatting.GOLD + StatCollector.translateToLocal("item.HelmetFortress.mask." + armor.stackTagCompound.getInteger("mask")));
list.add("");
list.add(EnumChatFormatting.DARK_PURPLE + StatCollector.translateToLocal("tc.visdiscount") + ": " + getVisDiscount(armor, player, null) + "%");
super.addInformation(armor, player, list, par4);
}
public boolean getIsRepairable(ItemStack armor, ItemStack material) {
ArrayList<ItemStack> thauminiteList = OreDictionary.getOres("ingotThauminite");
boolean isRepairable = false;
if (super.getIsRepairable(armor, material)) return true;
for (ItemStack thauminite : thauminiteList)
isRepairable = material.isItemEqual(thauminite);
return isRepairable;
}
public int getArmorDisplay(EntityPlayer player, ItemStack armor, int slot) { return this.damageReduceAmount; }
public void damageArmor(EntityLivingBase entity, ItemStack armor, DamageSource source, int damage, int slot) {
if (source != DamageSource.fall) armor.damageItem(damage, entity);
}
public int getRunicCharge(ItemStack armor) { return 0; }
public boolean showNodes(ItemStack armor, EntityLivingBase player) { return (armor.hasTagCompound() && armor.stackTagCompound.hasKey("goggles")); }
public boolean showIngamePopups(ItemStack armor, EntityLivingBase player) { return (armor.hasTagCompound() && armor.stackTagCompound.hasKey("goggles")); }
@SideOnly(Side.CLIENT)
public void registerIcons(IIconRegister register) {
this.icons[0] = register.registerIcon("thaumrev:armor/thauminitefortresshelm");
this.icons[1] = register.registerIcon("thaumrev:armor/thauminitefortresschest");
this.icons[2] = register.registerIcon("thaumrev:armor/thauminitefortresslegs");
}
@SideOnly(Side.CLIENT)
public IIcon getIconFromDamage(int par1) { return this.icons[this.armorType]; }
@SideOnly(Side.CLIENT)
public ModelBiped getArmorModel(EntityLivingBase entity, ItemStack armor, int armorSlot) {
int type = ((ItemArmor)armor.getItem()).armorType;
if (this.models[1] == null) this.models[1] = new ModelThauminiteFortressArmor(1.0F);
if (this.models[2] == null) this.models[2] = new ModelThauminiteFortressArmor(0.5F);
if (type != 1 && type != 3) this.models[0] = this.models[2];
else this.models[0] = this.models[1];
if (this.models[0] != null) {
this.models[0].bipedHead.showModel = (armorSlot == 0);
this.models[0].bipedHeadwear.showModel = (armorSlot == 0);
this.models[0].bipedBody.showModel = (armorSlot == 1 || armorSlot == 2);
this.models[0].bipedRightArm.showModel = (armorSlot == 1);
this.models[0].bipedLeftArm.showModel = (armorSlot == 1);
this.models[0].bipedRightLeg.showModel = (armorSlot == 2);
this.models[0].bipedLeftLeg.showModel = (armorSlot == 2);
this.models[0].isSneak = entity.isSneaking();
this.models[0].isRiding = entity.isRiding();
this.models[0].isChild = entity.isChild();
this.models[0].aimedBow = false;
this.models[0].heldItemRight = (entity.getHeldItem() != null) ? 1 : 0;
if (entity instanceof EntityPlayer && ((EntityPlayer)entity).getItemInUseDuration() > 0) {
EnumAction enumaction = ((EntityPlayer)entity).getItemInUse().getItemUseAction();
if (enumaction == EnumAction.block) (this.models[0]).heldItemRight = 3;
else if (enumaction == EnumAction.bow) (this.models[0]).aimedBow = true;
}
}
return this.models[0];
}
@SideOnly(Side.CLIENT)
public String getArmorTexture(ItemStack armor, Entity entity, int slot, String type) { return "thaumrev:textures/models/thauminite_fortress_armor.png"; }
}
Прокси:
ClientProxy:
package thaumrev.client;
import cpw.mods.fml.client.registry.ClientRegistry;
import cpw.mods.fml.client.registry.RenderingRegistry;
import cpw.mods.fml.common.FMLCommonHandler;
import cpw.mods.fml.common.network.NetworkRegistry;
import net.minecraft.client.renderer.entity.Render;
import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer;
import thaumrev.ThaumicRevelations;
import thaumrev.client.renderers.RenderPurity;
import thaumrev.client.renderers.TileKnowledgeReprocessorRenderer;
import thaumrev.common.CommonProxy;
import thaumrev.entities.EntityPurity;
import thaumrev.lib.network.ClientPacketHandler;
import thaumrev.lib.utils.KeyHandler;
import thaumrev.tiles.TileKnowledgeReprocessor;
public class ClientProxy extends CommonProxy {
public void preInit() {
super.preInit();
}
public void init() {
super.init();
RenderingRegistry.registerEntityRenderingHandler(EntityPurity.class, new RenderPurity());
ClientRegistry.bindTileEntitySpecialRenderer(TileKnowledgeReprocessor.class, new TileKnowledgeReprocessorRenderer());
FMLCommonHandler.instance().bus().register(new KeyHandler());
}
public void postInit() {
super.postInit();
}
}
CommonProxy:
package thaumrev.common;
import cpw.mods.fml.common.network.NetworkRegistry;
import cpw.mods.fml.common.registry.GameRegistry;
import thaumrev.ThaumicRevelations;
import thaumrev.api.wardenic.WardenicChargeEvents;
import thaumrev.api.wardenic.WardenicUpgrades;
import thaumrev.client.gui.GuiHandler;
import thaumrev.config.ConfigAspects;
import thaumrev.config.ConfigBlocks;
import thaumrev.config.ConfigIntegrations;
import thaumrev.config.ConfigItems;
import thaumrev.config.ConfigLibrary;
import thaumrev.config.ConfigRecipes;
import thaumrev.config.ConfigResearches;
import thaumrev.lib.CreativeTabThaumRev;
import thaumrev.lib.network.ServerPacketHandler;
import thaumrev.lib.utils.MobDropsHandler;
import thaumrev.lib.world.ThaumRevWorldGenerator;
public class CommonProxy {
public void preInit() {
ConfigLibrary.tabThaumRev = new CreativeTabThaumRev(ThaumicRevelations.MODID);
ConfigIntegrations.init();
MobDropsHandler.init();
ConfigBlocks.init();
ConfigItems.init();
ConfigAspects.registerAspects();
WardenicChargeEvents.init();
WardenicUpgrades.init();
GameRegistry.registerWorldGenerator(new ThaumRevWorldGenerator(), 1);
}
public void init() {
GuiHandler.init();
ThaumicRevelations.channel = NetworkRegistry.INSTANCE.newEventDrivenChannel("thaumrev");
ThaumicRevelations.channel.register(new ServerPacketHandler());
}
public void postInit() {
ConfigRecipes.registerRecipes();
ConfigAspects.registerItemAspects();
ConfigResearches.registerResearches();
}
}
ConfigItems:
package thaumrev.config;
import cpw.mods.fml.common.registry.GameRegistry;
import net.minecraft.item.Item;
import net.minecraft.item.ItemSeeds;
import net.minecraft.item.ItemStack;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.common.util.EnumHelper;
import thaumcraft.api.wands.StaffRod;
import thaumcraft.api.wands.WandRod;
import thaumrev.item.ItemExcubituraSeeds;
import thaumrev.item.ItemResource;
import thaumrev.item.ItemWardenBow;
import thaumrev.item.ItemWardenWeapon;
import thaumrev.item.ItemWaslieHammer;
import thaumrev.item.armor.ItemCrimsonHat;
import thaumrev.item.armor.ItemThauminiteFortressArmor;
import thaumrev.item.armor.ItemWardenArmor;
import thaumrev.item.armor.ItemWardenclothRobes;
import thaumrev.item.baubles.ItemLoveRing;
import thaumrev.item.baubles.ItemWardenAmulet;
import thaumrev.item.wands.ItemWandCore;
import thaumrev.item.wands.foci.ItemFocusIllumination;
import thaumrev.item.wands.foci.ItemFocusPurity;
public final class ConfigItems {
public static void init() {
if (ConfigIntegrations.isThaumicBasesLoaded) {
initializeThaumicBasesIntegration();
registerThaumicBasesIntegration();
}
initializeMaterials();
initializeItems();
initializeWandCores();
registerItems();
}
private static void initializeItems() {
ConfigLibrary.itemResource = new ItemResource();
ConfigLibrary.itemWardenWeapon = new ItemWardenWeapon();
ConfigLibrary.itemWardenBow = new ItemWardenBow();
ConfigLibrary.itemFocusPurity = new ItemFocusPurity();
ConfigLibrary.itemCrimsonHat = new ItemCrimsonHat();
ConfigLibrary.itemWardenHelm = new ItemWardenArmor(0, "itemWardenHelm");
ConfigLibrary.itemWardenChest = new ItemWardenArmor(1, "itemWardenChest");
ConfigLibrary.itemWardenLegs = new ItemWardenArmor(2, "itemWardenLegs");
ConfigLibrary.itemWardenBoots = new ItemWardenArmor(3, "itemWardenBoots");
ConfigLibrary.itemWardenAmulet = new ItemWardenAmulet();
ConfigLibrary.itemLoveRing = new ItemLoveRing();
ConfigLibrary.itemWaslieHammer = new ItemWaslieHammer();
ConfigLibrary.itemFocusIllumination = new ItemFocusIllumination();
ConfigLibrary.itemWardenclothChest = new ItemWardenclothRobes(1, "itemWardenclothChest");
ConfigLibrary.itemWardenclothLegs = new ItemWardenclothRobes(2, "itemWardenclothLegs");
ConfigLibrary.itemWardenclothBoots = new ItemWardenclothRobes(3, "itemWardenclothBoots");
ConfigLibrary.itemExcubituraSeeds = new ItemExcubituraSeeds();
}
private static void initializeMaterials() {
ConfigLibrary.armorMaterialWarden = EnumHelper.addArmorMaterial("WARDEN", 999, new int[] { 3, 8, 6, 3 }, 0);
ConfigLibrary.armorMaterialWardencloth = EnumHelper.addArmorMaterial("WARDENCLOTH", 50, new int[] { 2, 4, 2, 1 }, 15);
ConfigLibrary.armorMaterialCrimsoncloth = EnumHelper.addArmorMaterial("CRIMSONCLOTH", 50, new int[] { 2, 3, 2, 1 }, 15);
ConfigLibrary.toolMaterialWarden = EnumHelper.addToolMaterial("WARDEN", 9, 999, 6.0F, 12.0F, 0);
}
private static void initializeWandCores() {
String res = "thaumrev:textures/models/rod_";
ConfigLibrary.itemWandCore = new ItemWandCore();
ConfigLibrary.WAND_ROD_WARDENCLOTH = new WandRod("wardencloth", 150, new ItemStack(ConfigLibrary.itemWandCore, 1, 0), 12, new ResourceLocation(res + "wardencloth.png"));
ConfigLibrary.WAND_ROD_VOIDWOOD = new WandRod("voidwood", 200, new ItemStack(ConfigLibrary.itemWandCore, 1, 1), 12, new ResourceLocation(res + "voidwood.png"));
ConfigLibrary.WAND_ROD_CRIMSONCULT = new WandRod("crimsoncult", 100, new ItemStack(ConfigLibrary.itemWandCore, 1, 2), 12, new ResourceLocation(res + "crimsoncult.png"));
ConfigLibrary.WAND_ROD_CRIMSONCULT.setGlowing(true);
ConfigLibrary.STAFF_ROD_WARDENCLOTH = new StaffRod("wardencloth", 375, new ItemStack(ConfigLibrary.itemWandCore, 1, 10), 32, new ResourceLocation(res + "wardencloth_staff.png"));
ConfigLibrary.STAFF_ROD_VOIDWOOD = new StaffRod("voidwood", 500, new ItemStack(ConfigLibrary.itemWandCore, 1, 11), 32, new ResourceLocation(res + "voidwood_staff.png"));
ConfigLibrary.STAFF_ROD_VOIDWOOD.setRunes(true);
ConfigLibrary.STAFF_ROD_CRIMSONCULT = new StaffRod("crimsoncult", 1000, new ItemStack(ConfigLibrary.itemWandCore, 1, 12), 32, new ResourceLocation(res + "crimsoncult_staff.png"));
ConfigLibrary.STAFF_ROD_CRIMSONCULT.setRunes(true);
ConfigLibrary.STAFF_ROD_CRIMSONCULT.setGlowing(true);
}
private static void registerItems() {
GameRegistry.registerItem(ConfigLibrary.itemResource, "itemResource");
GameRegistry.registerItem(ConfigLibrary.itemWardenWeapon, "itemWardenWeapon");
GameRegistry.registerItem(ConfigLibrary.itemWardenBow, "itemWardenBow");
GameRegistry.registerItem(ConfigLibrary.itemWardenAmulet, "itemWardenAmulet");
GameRegistry.registerItem(ConfigLibrary.itemCrimsonHat, "itemCrimsonHat");
GameRegistry.registerItem(ConfigLibrary.itemWardenHelm, "itemWardenHelm");
GameRegistry.registerItem(ConfigLibrary.itemWardenChest, "itemWardenChest");
GameRegistry.registerItem(ConfigLibrary.itemWardenLegs, "itemWardenLegs");
GameRegistry.registerItem(ConfigLibrary.itemWardenBoots, "itemWardenBoots");
GameRegistry.registerItem(ConfigLibrary.itemWardenclothChest, "itemWardenclothChest");
GameRegistry.registerItem(ConfigLibrary.itemWardenclothLegs, "itemWardenclothLegs");
GameRegistry.registerItem(ConfigLibrary.itemWardenclothBoots, "itemWardenclothBoots");
GameRegistry.registerItem(ConfigLibrary.itemLoveRing, "itemLoveRing");
GameRegistry.registerItem(ConfigLibrary.itemWaslieHammer, "itemWaslieHammer");
GameRegistry.registerItem(ConfigLibrary.itemFocusIllumination, "itemFocusIllumination");
GameRegistry.registerItem(ConfigLibrary.itemFocusPurity, "itemFocusPurity");
GameRegistry.registerItem((Item)ConfigLibrary.itemExcubituraSeeds, "itemExcubituraSeeds");
GameRegistry.registerItem(ConfigLibrary.itemWandCore, "itemWandCore");
}
private static void initializeThaumicBasesIntegration() {
ConfigLibrary.armorMaterialFortressThauminite = EnumHelper.addArmorMaterial("FORTRESS_THAUMINITE", 43, new int[] { 4, 9, 7, 4 }, 17);
ConfigLibrary.itemThauminiteFortressHelm = new ItemThauminiteFortressArmor(0, "itemThauminiteFortressHelm");
ConfigLibrary.itemThauminiteFortressChest = new ItemThauminiteFortressArmor(1, "itemThauminiteFortressChest");
ConfigLibrary.itemThauminiteFortressLegs = new ItemThauminiteFortressArmor(2, "itemThauminiteFortressLegs");
}
private static void registerThaumicBasesIntegration() {
GameRegistry.registerItem(ConfigLibrary.itemThauminiteFortressHelm, "itemThauminiteFortressHelm");
GameRegistry.registerItem(ConfigLibrary.itemThauminiteFortressChest, "itemThauminiteFortressChest");
GameRegistry.registerItem(ConfigLibrary.itemThauminiteFortressLegs, "itemThauminiteFortressLegs");
}
}
ThaumicRevelations:
package thaumrev;
import cpw.mods.fml.client.event.ConfigChangedEvent;
import cpw.mods.fml.common.IWorldGenerator;
import cpw.mods.fml.common.Mod;
import cpw.mods.fml.common.Mod.EventHandler;
import cpw.mods.fml.common.Mod.Instance;
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 cpw.mods.fml.common.eventhandler.SubscribeEvent;
import cpw.mods.fml.common.network.FMLEventChannel;
import cpw.mods.fml.common.registry.GameRegistry;
import java.io.File;
import net.minecraft.creativetab.CreativeTabs;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import thaumrev.api.wardenic.WardenicChargeEvents;
import thaumrev.api.wardenic.WardenicUpgrades;
import thaumrev.client.gui.GuiHandler;
import thaumrev.common.CommonProxy;
import thaumrev.config.Config;
import thaumrev.config.ConfigAspects;
import thaumrev.config.ConfigBlocks;
import thaumrev.config.ConfigIntegrations;
import thaumrev.config.ConfigItems;
import thaumrev.config.ConfigLibrary;
import thaumrev.config.ConfigRecipes;
import thaumrev.config.ConfigResearches;
import thaumrev.lib.CreativeTabThaumRev;
import thaumrev.lib.utils.MobDropsHandler;
import thaumrev.lib.world.ThaumRevWorldGenerator;
@Mod(modid = ThaumicRevelations.MODID, version = "1.2.2.1", useMetadata = true)
public final class ThaumicRevelations {
public static final String MODID = "thaumrev", networkChannelName = MODID;
public static final Logger log = LogManager.getLogger("Thaumic Revelations");
public File modDir;
public static FMLEventChannel channel;
public static final int PACKET_TYPE_AMULET_USE = 1, PACKET_TYPE_S2C_TEST = 1;
@Instance(MODID)
public static ThaumicRevelations instance;
@SidedProxy(serverSide = "thaumrev.common.CommonProxy", clientSide = "thaumrev.client.ClientProxy")
public static CommonProxy proxy;
@EventHandler
public void preInit(FMLPreInitializationEvent event) {
modDir = event.getModConfigurationDirectory();
try { Config.init(event.getSuggestedConfigurationFile()); }
catch (Exception var8) { log.error("Thaumic Revelations had a problem loading its configuration"); }
finally { if (Config.config != null) Config.save(); }
Config.save();
proxy.preInit();
}
@EventHandler
public void init(FMLInitializationEvent event) {
proxy.init();
}
@EventHandler
public void postInit(FMLPostInitializationEvent event) {
proxy.postInit();
}
@SubscribeEvent
public void onConfigChanged(ConfigChangedEvent.OnConfigChangedEvent event) {
if (event.modID.equals(MODID)) Config.sync();
if (Config.config != null && Config.config.hasChanged()) Config.save();
}
}
И вот чего я не могу понять... Регистрация предметов происходит в
CommonProxy
, то есть на обеих сторонах - верно? Но у айтема есть поля и методы, которые должны работать только на клиенте. Такие поля помечаются аннотацией @SideOnly(Side.CLIENT)
и, как я читал всё на этом же форуме, сервер такие куски кода не читает (правда или миф?). Так по какой тогда причине сервер пытается обращаться к этим полям, если поля используются так же только в методах с пометкой @SideOnly(Side.CLIENT)
?То есть сервер обрабатывает методы с
@SideOnly(Side.CLIENT)
? Или есть какие-то куски кода у мода, где идет обращение к этим полям от классов, зарегистрированных в CommonProxy без аннотации @SideOnly(Side.CLIENT)
, но в иерархии краша они не прослеживаются в данном случае?Заранее спасибо!
Последнее редактирование: