Package

Source Code of MultiMCLauncher

//
//  Copyright 2012 MultiMC Contributors
//
//    Licensed under the Apache License, Version 2.0 (the "License");
//    you may not use this file except in compliance with the License.
//    You may obtain a copy of the License at
//
//        http://www.apache.org/licenses/LICENSE-2.0
//
//    Unless required by applicable law or agreed to in writing, software
//    distributed under the License is distributed on an "AS IS" BASIS,
//    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//    See the License for the specific language governing permissions and
//    limitations under the License.
//

import java.applet.Applet;
import java.awt.Dimension;

import java.io.File;
import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Modifier;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.zip.ZipEntry;
import java.util.zip.ZipException;
import java.util.zip.ZipFile;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import org.simplericity.macify.eawt.Application;
import org.simplericity.macify.eawt.DefaultApplication;

public class MultiMCLauncher
{
  /**
   * @param args
   *            The arguments you want to launch Minecraft with. New path,
   *            Username, Session ID.
   */
  public static void main(String[] args)
  {
    if (args.length < 3)
    {
      System.out.println("Not enough arguments.");
      System.exit(-1);
    }
   
    // Set the OSX application icon first, if we are on OSX.
    Application application = new DefaultApplication();
    if(application.isMac())
    {
      try
      {
        BufferedImage image = ImageIO.read(new File("icon.png"));
        application.setApplicationIconImage(image);
      }
      catch (IOException e)
      {
        e.printStackTrace();
      }
    }
   
    String userName = args[0];
    String sessionId = args[1];
    String windowtitle = args[2];
    String windowParams = args[3];
    String lwjgl = args[4];
    String cwd = System.getProperty("user.dir");
   
    Dimension winSize = new Dimension(854, 480);
    boolean maximize = false;
    boolean compatMode = false;
   
   
    String[] dimStrings = windowParams.split("x");
   
    if (windowParams.equalsIgnoreCase("compatmode"))
    {
      compatMode = true;
    }
    else if (windowParams.equalsIgnoreCase("max"))
    {
      maximize = true;
    }
    else if (dimStrings.length == 2)
    {
      try
      {
        winSize = new Dimension(Integer.parseInt(dimStrings[0]),
            Integer.parseInt(dimStrings[1]));
      }
      catch (NumberFormatException e)
      {
        System.out.println("Invalid Window size argument, " +
            "using default.");
      }
    }
    else
    {
      System.out.println("Invalid Window size argument, " +
          "using default.");
    }
   
    try
    {
      File binDir = new File(cwd, "bin");
      File lwjglDir;
      if(lwjgl.equalsIgnoreCase("Mojang"))
        lwjglDir = binDir;
      else
        lwjglDir = new File(lwjgl);
     
      System.out.println("Loading jars...");
      String[] lwjglJars = new String[] {
        "lwjgl.jar", "lwjgl_util.jar", "jinput.jar"
      };
     
      URL[] urls = new URL[4];
      try
      {
        File f = new File(binDir, "minecraft.jar");
        urls[0] = f.toURI().toURL();
        System.out.println("Loading URL: " + urls[0].toString());

        for (int i = 1; i < urls.length; i++)
        {
          File jar = new File(lwjglDir, lwjglJars[i-1]);
          urls[i] = jar.toURI().toURL();
          System.out.println("Loading URL: " + urls[i].toString());
        }
      }
      catch (MalformedURLException e)
      {
        System.err.println("MalformedURLException, " + e.toString());
        System.exit(5);
      }
     
      System.out.println("Loading natives...");
      String nativesDir = new File(lwjglDir, "natives").toString();
     
      System.setProperty("org.lwjgl.librarypath", nativesDir);
      System.setProperty("net.java.games.input.librarypath", nativesDir);

      URLClassLoader cl =
          new URLClassLoader(urls, MultiMCLauncher.class.getClassLoader());
     
      // Get the Minecraft Class.
      Class<?> mc = null;
      try
      {
        mc = cl.loadClass("net.minecraft.client.Minecraft");
       
        Field f = getMCPathField(mc);
       
        if (f == null)
        {
          System.err.println("Could not find Minecraft path field. Launch failed.");
          System.exit(-1);
        }
       
        f.setAccessible(true);
        f.set(null, new File(cwd));
        // And set it.
        System.out.println("Fixed Minecraft Path: Field was " + f.toString());
      }
      catch (ClassNotFoundException e)
      {
        System.err.println("Can't find main class. Searching...");
       
        // Look for any class that looks like the main class.
        File mcJar = new File(new File(cwd, "bin"), "minecraft.jar");
        ZipFile zip = null;
        try
        {
          zip = new ZipFile(mcJar);
        } catch (ZipException e1)
        {
          e1.printStackTrace();
          System.err.println("Search failed.");
          System.exit(-1);
        } catch (IOException e1)
        {
          e1.printStackTrace();
          System.err.println("Search failed.");
          System.exit(-1);
        }
       
        Enumeration<? extends ZipEntry> entries = zip.entries();
        ArrayList<String> classes = new ArrayList<String>();
       
        while (entries.hasMoreElements())
        {
          ZipEntry entry = entries.nextElement();
          if (entry.getName().endsWith(".class"))
          {
            String entryName = entry.getName().substring(0, entry.getName().lastIndexOf('.'));
            entryName = entryName.replace('/', '.');
            System.out.println("Found class: " + entryName);
            classes.add(entryName);
          }
        }
       
        for (String clsName : classes)
        {
          try
          {
            Class<?> cls = cl.loadClass(clsName);
            if (!Runnable.class.isAssignableFrom(cls))
            {
              continue;
            }
            else
            {
              System.out.println("Found class implementing runnable: " +
                  cls.getName());
            }
           
            if (getMCPathField(cls) == null)
            {
              continue;
            }
            else
            {
              System.out.println("Found class implementing runnable " +
                  "with mcpath field: " + cls.getName());
            }
           
            mc = cls;
            break;
          }
          catch (ClassNotFoundException e1)
          {
            // Ignore
            continue;
          }
        }
       
        if (mc == null)
        {
          System.err.println("Failed to find Minecraft main class.");
          System.exit(-1);
        }
        else
        {
          System.out.println("Found main class: " + mc.getName());
        }
      }
     
      System.setProperty("minecraft.applet.TargetDirectory", cwd);
     
      String[] mcArgs = new String[2];
      mcArgs[0] = userName;
      mcArgs[1] = sessionId;
     
      if (compatMode)
      {
        System.out.println("Launching in compatibility mode...");
        mc.getMethod("main", String[].class).invoke(null, (Object) mcArgs);
      }
      else
      {
        System.out.println("Launching with applet wrapper...");
        try
        {
          Class<?> MCAppletClass = cl.loadClass(
              "net.minecraft.client.MinecraftApplet");
          Applet mcappl = (Applet) MCAppletClass.newInstance();
          MCFrame mcWindow = new MCFrame(windowtitle);
          mcWindow.start(mcappl, userName, sessionId, winSize, maximize);
        } catch (InstantiationException e)
        {
          System.out.println("Applet wrapper failed! Falling back " +
              "to compatibility mode.");
          mc.getMethod("main", String[].class).invoke(null, (Object) mcArgs);
        }
      }
    } catch (ClassNotFoundException e)
    {
      e.printStackTrace();
      System.exit(1);
    } catch (IllegalArgumentException e)
    {
      e.printStackTrace();
      System.exit(2);
    } catch (IllegalAccessException e)
    {
      e.printStackTrace();
      System.exit(2);
    } catch (InvocationTargetException e)
    {
      e.printStackTrace();
      System.exit(3);
    } catch (NoSuchMethodException e)
    {
      e.printStackTrace();
      System.exit(3);
    } catch (SecurityException e)
    {
      e.printStackTrace();
      System.exit(4);
    }
  }

  public static Field getMCPathField(Class<?> mc)
  {
    Field[] fields = mc.getDeclaredFields();
   
    for (int i = 0; i < fields.length; i++)
    {
      Field f = fields[i];
      if (f.getType() != File.class)
      {
        // Has to be File
        continue;
      }
      if (f.getModifiers() != (Modifier.PRIVATE + Modifier.STATIC))
      {
        // And Private Static.
        continue;
      }
      return f;
    }
    return null;
  }
}
TOP

Related Classes of MultiMCLauncher

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.