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

Способ запуска клиента игры из Лаунчера Часть 2

Хм.. надо потестировать. Теоретически такой проблемы не должно быть
 
Ап. Ну никак не хочет запускаться. Пробовал запускать метод main в net.minecraft.client.Minecraft. Что странно, всё равно не запускается майн. Инициализация проходит хорошо, а на старте закрывается...
 
Ап. Ну никак не хочет запускаться. Пробовал запускать метод main в net.minecraft.client.Minecraft. Что странно, всё равно не запускается майн. Инициализация проходит хорошо, а на старте закрывается...

С форджем майн действительно не будет запускаться, так как способ запускает апплет.
Разработчики форджа писали, что запуск через апплет не возможен, и исправлять это они не планируют.
 
С форджем майн действительно не будет запускаться, так как способ запускает апплет.
Разработчики форджа писали, что запуск через апплет не возможен, и исправлять это они не планируют.
facepalm.gif
все джава лаунчеры с аплета запускают и норм. Руки у вас кривые. Forge перезапускает аплет через net.minecraft.launcher. Если ваш аплет через заднее место написан никто не виноват
 
Код:
package cpw.mods.fml.relauncher;
 
import java.applet.Applet;
import java.io.File;
import java.io.PrintStream;
import java.lang.reflect.Method;
import java.net.URLClassLoader;
import javax.swing.JDialog;
import javax.swing.JOptionPane;
 
public class FMLRelauncher
{
  private static FMLRelauncher INSTANCE;
  public static String logFileNamePattern;
  private static String side;
  private RelaunchClassLoader classLoader;
  private Object newApplet;
  private Class appletClass;
  JDialog popupWindow;
 
  public static void handleClientRelaunch(ArgsWrapper wrap)
  {
    logFileNamePattern = "ForgeModLoader-client-%g.log";
    side = "CLIENT";
    instance().relaunchClient(wrap);
  }
 
  public static void handleServerRelaunch(ArgsWrapper wrap)
  {
    logFileNamePattern = "ForgeModLoader-server-%g.log";
    side = "SERVER";
    instance().relaunchServer(wrap);
  }
 
  static FMLRelauncher instance()
  {
    if (INSTANCE == null)
    {
      INSTANCE = new FMLRelauncher();
    }
    return INSTANCE;
  }
 
  private FMLRelauncher()
  {
    URLClassLoader ucl = (URLClassLoader)getClass().getClassLoader();
 
    this.classLoader = new RelaunchClassLoader(ucl.getURLs());
  }
 
  private void showWindow(boolean showIt)
  {
    if (RelaunchLibraryManager.downloadMonitor != null) return;
    try
    {
      if (showIt)
      {
        RelaunchLibraryManager.downloadMonitor = new Downloader();
        this.popupWindow = ((JDialog)RelaunchLibraryManager.downloadMonitor.makeDialog());
      }
      else
      {
        RelaunchLibraryManager.downloadMonitor = new DummyDownloader();
      }
    }
    catch (Throwable e)
    {
      if (RelaunchLibraryManager.downloadMonitor == null)
      {
        RelaunchLibraryManager.downloadMonitor = new DummyDownloader();
        e.printStackTrace();
      }
      else
      {
        RelaunchLibraryManager.downloadMonitor.makeHeadless();
      }
      this.popupWindow = null;
    }
  }
 
  private void relaunchClient(ArgsWrapper wrap)
  {
    showWindow(false);
    Class client;
    try
    {
      File minecraftHome = computeExistingClientHome();
      setupHome(minecraftHome);
 
      client = setupNewClientHome(minecraftHome);
    }
    finally
    {
      if (this.popupWindow != null)
      {
        this.popupWindow.setVisible(false);
        this.popupWindow.dispose();
      }
    }
 
    if (RelaunchLibraryManager.downloadMonitor.shouldStopIt())
    {
      System.exit(1);
    }
    try
    {
      ReflectionHelper.findMethod(client, null, new String[] { "fmlReentry" }, new Class[] { ArgsWrapper.class }).invoke(null, new Object[] { wrap });
    }
    catch (Exception e)
    {
      e.printStackTrace();
    }
  }
 
  private Class setupNewClientHome(File minecraftHome)
  {
    Class client = ReflectionHelper.getClass(this.classLoader, new String[] { "net.minecraft.client.Minecraft" });
    ReflectionHelper.setPrivateValue(client, null, minecraftHome, new String[] { "minecraftDir", "an", "minecraftDir" });
    return client;
  }
 
  private void relaunchServer(ArgsWrapper wrap)
  {
    showWindow(false);
 
    File minecraftHome = new File(".");
    setupHome(minecraftHome);
 
    Class server = ReflectionHelper.getClass(this.classLoader, new String[] { "net.minecraft.server.MinecraftServer" });
    try
    {
      ReflectionHelper.findMethod(server, null, new String[] { "fmlReentry" }, new Class[] { ArgsWrapper.class }).invoke(null, new Object[] { wrap });
    }
    catch (Exception e)
    {
      e.printStackTrace();
    }
  }
 
  private void setupHome(File minecraftHome)
  {
    FMLInjectionData.build(minecraftHome, this.classLoader);
    FMLRelaunchLog.minecraftHome = minecraftHome;
    FMLRelaunchLog.info("Forge Mod Loader version %s.%s.%s.%s for Minecraft %s loading", new Object[] { FMLInjectionData.major, FMLInjectionData.minor, FMLInjectionData.rev, FMLInjectionData.build, FMLInjectionData.mccversion, FMLInjectionData.mcpversion });
    try
    {
      RelaunchLibraryManager.handleLaunch(minecraftHome, this.classLoader);
    }
    catch (Throwable t)
    {
      if (this.popupWindow != null)
      {
        try
        {
          String logFile = new File(minecraftHome, "ForgeModLoader-client-0.log").getCanonicalPath();
          JOptionPane.showMessageDialog(this.popupWindow, String.format("<html><div align=\"center\"><font size=\"+1\">There was a fatal error starting up minecraft and FML</font></div><br/>Minecraft cannot launch in it's current configuration<br/>Please consult the file <i><a href=\"file:///%s\">%s</a></i> for further information</html>", new Object[] { logFile, logFile }), "Fatal FML error", 0);
        }
        catch (Exception ex)
        {
        }
 
      }
 
      throw new RuntimeException(t);
    }
  }
 
  private File computeExistingClientHome()
  {
    Class mcMaster = ReflectionHelper.getClass(getClass().getClassLoader(), new String[] { "net.minecraft.client.Minecraft" });
 
    String str = System.getProperty("minecraft.applet.TargetDirectory");
    if (str != null)
    {
      str = str.replace('/', File.separatorChar);
      ReflectionHelper.setPrivateValue(mcMaster, null, new File(str), new String[] { "minecraftDir", "an", "minecraftDir" });
    }
 
    Method setupHome = ReflectionHelper.findMethod(mcMaster, null, new String[] { "getMinecraftDir", "getMinecraftDir", "b" }, new Class[0]);
    try
    {
      setupHome.invoke(null, new Object[0]);
    }
    catch (Exception e)
    {
    }
 
    File minecraftHome = (File)ReflectionHelper.getPrivateValue(mcMaster, null, new String[] { "minecraftDir", "an", "minecraftDir" });
    return minecraftHome;
  }
 
  public static void appletEntry(Applet minecraftApplet)
  {
    side = "CLIENT";
    logFileNamePattern = "ForgeModLoader-client-%g.log";
    instance().relaunchApplet(minecraftApplet);
  }
 
  private void relaunchApplet(Applet minecraftApplet)
  {
    showWindow(false);
 
    this.appletClass = ReflectionHelper.getClass(this.classLoader, new String[] { "net.minecraft.client.MinecraftApplet" });
    if (minecraftApplet.getClass().getClassLoader() == this.classLoader)
    {
      if (this.popupWindow != null)
      {
        this.popupWindow.setVisible(false);
        this.popupWindow.dispose();
      }
      try
      {
        this.newApplet = minecraftApplet;
        ReflectionHelper.findMethod(this.appletClass, this.newApplet, new String[] { "fmlInitReentry" }, new Class[0]).invoke(this.newApplet, new Object[0]);
        return;
      }
      catch (Exception e)
      {
        System.out.println("FMLRelauncher.relaunchApplet");
        e.printStackTrace();
        throw new RuntimeException(e);
      }
    }
 
    File mcDir = computeExistingClientHome();
    setupHome(mcDir);
    setupNewClientHome(mcDir);
 
    Class parentAppletClass = ReflectionHelper.getClass(getClass().getClassLoader(), new String[] { "java.applet.Applet" });
    try
    {
      this.newApplet = this.appletClass.newInstance();
      Object appletContainer = ReflectionHelper.getPrivateValue(ReflectionHelper.getClass(getClass().getClassLoader(), new String[] { "java.awt.Component" }), minecraftApplet, new String[] { "parent" });
 
      String launcherClassName = System.getProperty("minecraft.applet.WrapperClass", "net.minecraft.Launcher");
      Class launcherClass = ReflectionHelper.getClass(getClass().getClassLoader(), new String[] { launcherClassName });
      if (launcherClass.isInstance(appletContainer))
      {
        ReflectionHelper.findMethod(ReflectionHelper.getClass(getClass().getClassLoader(), new String[] { "java.awt.Container" }), minecraftApplet, new String[] { "removeAll" }, new Class[0]).invoke(appletContainer, new Object[0]);
 
        ReflectionHelper.findMethod(launcherClass, appletContainer, new String[] { "replace" }, new Class[] { parentAppletClass }).invoke(appletContainer, new Object[] { this.newApplet });
      }
      else
      {
        FMLRelaunchLog.severe("Found unknown applet parent %s, unable to inject!\n", new Object[] { appletContainer.getClass().getName() });
        throw new RuntimeException();
      }
    }
    catch (Exception e)
    {
      throw new RuntimeException(e);
    }
    finally
    {
      if (this.popupWindow != null)
      {
        this.popupWindow.setVisible(false);
        this.popupWindow.dispose();
      }
    }
  }
 
  public static void appletStart(Applet applet)
  {
    instance().startApplet(applet);
  }
 
  private void startApplet(Applet applet)
  {
    if (applet.getClass().getClassLoader() == this.classLoader)
    {
      if (this.popupWindow != null)
      {
        this.popupWindow.setVisible(false);
        this.popupWindow.dispose();
      }
      if (RelaunchLibraryManager.downloadMonitor.shouldStopIt())
      {
        System.exit(1);
      }
      try
      {
        ReflectionHelper.findMethod(this.appletClass, this.newApplet, new String[] { "fmlStartReentry" }, new Class[0]).invoke(this.newApplet, new Object[0]);
      }
      catch (Exception e)
      {
        System.out.println("FMLRelauncher.startApplet");
        e.printStackTrace();
        throw new RuntimeException(e);
      }
    }
  }
 
  public static String side()
  {
    return side;
  }
}
По изучай этот класс мб допрет как перезапуск аплета работает.
 
Перезапуск работает через враппер.
Поэтому для своего лаунчера я переопределил его и проблем с запуском нет, как чистого клиента, так и с форджем.
 
Я уже решил эту проблему сам, стащил с нотчевского лаунчера net.minecraft.Launcher и запихнул в minecraft.jar, и использую его вместо MinecraftFakeLauncher (он же asf, он же avk в обфусцированном виде).
А ты на чем пишеш?
Извращаюсь через C#, но дело не в языке.
 

Вложения:

А причину всеравно найти надо, я думаю в java коде возникает неперехватываемое исключение, я попробую его поймать и посмотреть где и кто накосячил.
Чтоб все было точно какую версию minecraft ты используеш и версию мода?
 
А причину всеравно найти надо, я думаю в java коде возникает неперехватываемое исключение, я попробую его поймать и посмотреть где и кто накосячил.
Чтоб все было точно какую версию minecraft ты используеш и версию мода?
Да нет там никакой причины, просто для форджа нужен класс-враппер.
 
Да, задали задачку... Поизучал я код Forge, они переписали main функцию класса net.minecraft.client.Minecraft. Вообщем у меня пока не получилось создать собственный аплейт чтобы установить два параметра "server" и "port", хотя если это не нужно можно просто без гемора вызвать main функцию с нужными параметрами и все будет работать.
PHP:
env->CallStaticVoidMethod(env->FindClass("net/minecraft/client/Minecraft"), env->GetStaticMethodID(env->FindClass("net/minecraft/client/Minecraft"), "main", "([Ljava/lang/String;)V"), env->NewStringUTF(""));
 
Да, задали задачку... Поизучал я код Forge, они переписали main функцию класса net.minecraft.client.Minecraft. Вообщем у меня пока не получилось создать собственный аплейт чтобы установить два параметра "server" и "port", хотя если это не нужно можно просто без гемора вызвать main функцию с нужными параметрами и все будет работать.
PHP:
env->CallStaticVoidMethod(env->FindClass("net/minecraft/client/Minecraft"), env->GetStaticMethodID(env->FindClass("net/minecraft/client/Minecraft"), "main", "([Ljava/lang/String;)V"), env->NewStringUTF(""));
Пробовал, не работает.
 
Все работает, я не пишу того что сам не проверяю
 
Уважаемый Шаман, а можно подробнее про переопределение класса враппера?

Можно)
В Java это делается так:
Код:
System.setProperty("minecraft.applet.WrapperClass", "класс_Вашего_враппера");

В лаунчере у меня получилась такая конструкция:
Код:
jclass systemClass = env->FindClass("java/lang/System");
            jmethodID setPropertyMethod = env->GetStaticMethodID(systemClass, "setProperty","(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;");
            env->CallStaticObjectMethod(systemClass,setPropertyMethod,env->NewStringUTF("minecraft.applet.WrapperClass"),env->NewStringUTF("net.minecraft.tenaxy"));

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

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

Назад
Верх