    001package net.minecraft.client;
    002
    003import cpw.mods.fml.client.FMLClientHandler;
    004import cpw.mods.fml.common.FMLCommonHandler;
    005import cpw.mods.fml.common.registry.GameData;
    006import cpw.mods.fml.common.registry.ItemData;
    007import cpw.mods.fml.relauncher.ArgsWrapper;
    008import cpw.mods.fml.relauncher.FMLRelauncher;
    009import cpw.mods.fml.relauncher.Side;
    010import cpw.mods.fml.relauncher.SideOnly;
    011import java.awt.BorderLayout;
    012import java.awt.Canvas;
    013import java.awt.Color;
    014import java.awt.Component;
    015import java.awt.Dimension;
    016import java.awt.Frame;
    017import java.awt.Graphics;
    018import java.io.File;
    019import java.io.IOException;
    020import java.nio.ByteBuffer;
    021import java.text.DecimalFormat;
    022import java.util.ArrayList;
    023import java.util.HashMap;
    024import java.util.Iterator;
    025import java.util.List;
    026import javax.swing.JPanel;
    027import net.minecraft.block.Block;
    028import net.minecraft.client.audio.SoundManager;
    029import net.minecraft.client.entity.EntityClientPlayerMP;
    030import net.minecraft.client.gui.FontRenderer;
    031import net.minecraft.client.gui.GuiChat;
    032import net.minecraft.client.gui.GuiGameOver;
    033import net.minecraft.client.gui.GuiIngame;
    034import net.minecraft.client.gui.GuiIngameMenu;
    035import net.minecraft.client.gui.GuiMainMenu;
    036import net.minecraft.client.gui.GuiMemoryErrorScreen;
    037import net.minecraft.client.gui.GuiScreen;
    038import net.minecraft.client.gui.GuiSleepMP;
    039import net.minecraft.client.gui.LoadingScreenRenderer;
    040import net.minecraft.client.gui.ScaledResolution;
    041import net.minecraft.client.gui.achievement.GuiAchievement;
    042import net.minecraft.client.gui.inventory.GuiInventory;
    043import net.minecraft.client.multiplayer.GuiConnecting;
    044import net.minecraft.client.multiplayer.NetClientHandler;
    045import net.minecraft.client.multiplayer.PlayerControllerMP;
    046import net.minecraft.client.multiplayer.ServerData;
    047import net.minecraft.client.multiplayer.WorldClient;
    048import net.minecraft.client.particle.EffectRenderer;
    049import net.minecraft.client.renderer.CallableParticleScreenName;
    050import net.minecraft.client.renderer.EntityRenderer;
    051import net.minecraft.client.renderer.GLAllocation;
    052import net.minecraft.client.renderer.ItemRenderer;
    053import net.minecraft.client.renderer.OpenGlHelper;
    054import net.minecraft.client.renderer.RenderBlocks;
    055import net.minecraft.client.renderer.RenderEngine;
    056import net.minecraft.client.renderer.RenderGlobal;
    057import net.minecraft.client.renderer.Tessellator;
    058import net.minecraft.client.renderer.WorldRenderer;
    059import net.minecraft.client.renderer.entity.RenderManager;
    060import net.minecraft.client.renderer.texture.TextureManager;
    061import net.minecraft.client.settings.EnumOptions;
    062import net.minecraft.client.settings.GameSettings;
    063import net.minecraft.client.settings.KeyBinding;
    064import net.minecraft.client.texturepacks.TexturePackList;
    065import net.minecraft.crash.CrashReport;
    066import net.minecraft.crash.CrashReportCategory;
    067import net.minecraft.entity.EntityList;
    068import net.minecraft.entity.EntityLiving;
    069import net.minecraft.entity.item.EntityBoat;
    070import net.minecraft.entity.item.EntityItemFrame;
    071import net.minecraft.entity.item.EntityMinecart;
    072import net.minecraft.entity.item.EntityPainting;
    073import net.minecraft.item.Item;
    074import net.minecraft.item.ItemStack;
    075import net.minecraft.logging.ILogAgent;
    076import net.minecraft.logging.LogAgent;
    077import net.minecraft.network.INetworkManager;
    078import net.minecraft.network.MemoryConnection;
    079import net.minecraft.network.packet.Packet3Chat;
    080import net.minecraft.profiler.IPlayerUsage;
    081import net.minecraft.profiler.PlayerUsageSnooper;
    082import net.minecraft.profiler.Profiler;
    083import net.minecraft.profiler.ProfilerResult;
    084import net.minecraft.server.integrated.IntegratedServer;
    085import net.minecraft.stats.AchievementList;
    086import net.minecraft.stats.StatFileWriter;
    087import net.minecraft.stats.StatList;
    088import net.minecraft.util.AxisAlignedBB;
    089import net.minecraft.util.EnumMovingObjectType;
    090import net.minecraft.util.EnumOS;
    091import net.minecraft.util.HttpUtil;
    092import net.minecraft.util.MathHelper;
    093import net.minecraft.util.MinecraftError;
    094import net.minecraft.util.MouseHelper;
    095import net.minecraft.util.MovementInputFromOptions;
    096import net.minecraft.util.MovingObjectPosition;
    097import net.minecraft.util.ReportedException;
    098import net.minecraft.util.ScreenShotHelper;
    099import net.minecraft.util.Session;
    100import net.minecraft.util.StatCollector;
    101import net.minecraft.util.StringTranslate;
    102import net.minecraft.util.ThreadDownloadResources;
    103import net.minecraft.util.Timer;
    104import net.minecraft.world.ColorizerFoliage;
    105import net.minecraft.world.ColorizerGrass;
    106import net.minecraft.world.WorldSettings;
    107import net.minecraft.world.chunk.storage.AnvilSaveConverter;
    108import net.minecraft.world.storage.ISaveFormat;
    109import net.minecraft.world.storage.ISaveHandler;
    110import net.minecraft.world.storage.WorldInfo;
    111import org.lwjgl.LWJGLException;
    112import org.lwjgl.Sys;
    113import org.lwjgl.input.Keyboard;
    114import org.lwjgl.input.Mouse;
    115import org.lwjgl.opengl.ContextCapabilities;
    116import org.lwjgl.opengl.Display;
    117import org.lwjgl.opengl.DisplayMode;
    118import org.lwjgl.opengl.GL11;
    119import org.lwjgl.opengl.GL20;
    120import org.lwjgl.opengl.GLContext;
    121import org.lwjgl.opengl.PixelFormat;
    122import org.lwjgl.util.glu.GLU;
    123
    124import com.google.common.collect.MapDifference;
    125
    126import net.minecraftforge.common.ForgeHooks;
    127import net.minecraftforge.event.ForgeEventFactory;
    128import net.minecraftforge.event.entity.player.PlayerInteractEvent.Action;
    129
    130@SideOnly(Side.CLIENT)
    131public abstract class Minecraft implements Runnable, IPlayerUsage
    132{
    133    /** A 10MiB preallocation to ensure the heap is reasonably sized. */
    134    public static byte[] memoryReserve = new byte[10485760];
    135    private final ILogAgent field_94139_O = new LogAgent("Minecraft-Client", " [CLIENT]", (new File(getMinecraftDir(), "output-client.log")).getAbsolutePath());
    136    private ServerData currentServerData;
    137
    138    /**
    139     * Set to 'this' in Minecraft constructor; used by some settings get methods
    140     */
    141    private static Minecraft theMinecraft;
    142    public PlayerControllerMP playerController;
    143    private boolean fullscreen = false;
    144    private boolean hasCrashed = false;
    145
    146    /** Instance of CrashReport. */
    147    private CrashReport crashReporter;
    148    public int displayWidth;
    149    public int displayHeight;
    150    private Timer timer = new Timer(20.0F);
    151
    152    /** Instance of PlayerUsageSnooper. */
    153    private PlayerUsageSnooper usageSnooper = new PlayerUsageSnooper("client", this);
    154    public WorldClient theWorld;
    155    public RenderGlobal renderGlobal;
    156    public EntityClientPlayerMP thePlayer;
    157
    158    /**
    159     * The Entity from which the renderer determines the render viewpoint. Currently is always the parent Minecraft
    160     * class's 'thePlayer' instance. Modification of its location, rotation, or other settings at render time will
    161     * modify the camera likewise, with the caveat of triggering chunk rebuilds as it moves, making it unsuitable for
    162     * changing the viewpoint mid-render.
    163     */
    164    public EntityLiving renderViewEntity;
    165    public EntityLiving field_96291_i;
    166    public EffectRenderer effectRenderer;
    167    public Session session = null;
    168    public String minecraftUri;
    169    public Canvas mcCanvas;
    170
    171    /** a boolean to hide a Quit button from the main menu */
    172    public boolean hideQuitButton = false;
    173    public volatile boolean isGamePaused = false;
    174
    175    /** The RenderEngine instance used by Minecraft */
    176    public RenderEngine renderEngine;
    177
    178    /** The font renderer used for displaying and measuring text. */
    179    public FontRenderer fontRenderer;
    180    public FontRenderer standardGalacticFontRenderer;
    181
    182    /** The GuiScreen that's being displayed at the moment. */
    183    public GuiScreen currentScreen = null;
    184    public LoadingScreenRenderer loadingScreen;
    185    public EntityRenderer entityRenderer;
    186
    187    /** Reference to the download resources thread. */
    188    private ThreadDownloadResources downloadResourcesThread;
    189
    190    /** Mouse left click counter */
    191    private int leftClickCounter = 0;
    192
    193    /** Display width */
    194    private int tempDisplayWidth;
    195
    196    /** Display height */
    197    private int tempDisplayHeight;
    198
    199    /** Instance of IntegratedServer. */
    200    private IntegratedServer theIntegratedServer;
    201
    202    /** Gui achievement */
    203    public GuiAchievement guiAchievement = new GuiAchievement(this);
    204    public GuiIngame ingameGUI;
    205
    206    /** Skip render world */
    207    public boolean skipRenderWorld = false;
    208
    209    /** The ray trace hit that the mouse is over. */
    210    public MovingObjectPosition objectMouseOver = null;
    211
    212    /** The game settings that currently hold effect. */
    213    public GameSettings gameSettings;
    214    protected MinecraftApplet mcApplet;
    215    public SoundManager sndManager = new SoundManager();
    216
    217    /** Mouse helper instance. */
    218    public MouseHelper mouseHelper;
    219
    220    /** The TexturePackLister used by this instance of Minecraft... */
    221    public TexturePackList texturePackList;
    222    public File mcDataDir;
    223    private ISaveFormat saveLoader;
    224
    225    /**
    226     * This is set to fpsCounter every debug screen update, and is shown on the debug screen. It's also sent as part of
    227     * the usage snooping.
    228     */
    229    private static int debugFPS;
    230
    231    /**
    232     * When you place a block, it's set to 6, decremented once per tick, when it's 0, you can place another block.
    233     */
    234    private int rightClickDelayTimer = 0;
    235
    236    /**
    237     * Checked in Minecraft's while(running) loop, if true it's set to false and the textures refreshed.
    238     */
    239    private boolean refreshTexturePacksScheduled;
    240
    241    /** Stat file writer */
    242    public StatFileWriter statFileWriter;
    243    private String serverName;
    244    private int serverPort;
    245
    246    /**
    247     * Makes sure it doesn't keep taking screenshots when both buttons are down.
    248     */
    249    boolean isTakingScreenshot = false;
    250
    251    /**
    252     * Does the actual gameplay have focus. If so then mouse and keys will effect the player instead of menus.
    253     */
    254    public boolean inGameHasFocus = false;
    255    long systemTime = getSystemTime();
    256
    257    /** Join player counter */
    258    private int joinPlayerCounter = 0;
    259    private boolean isDemo;
    260    private INetworkManager myNetworkManager;
    261    private boolean integratedServerIsRunning;
    262
    263    /** The profiler instance */
    264    public final Profiler mcProfiler = new Profiler();
    265    private long field_83002_am = -1L;
    266
    267    /** The working dir (OS specific) for minecraft */
    268    private static File minecraftDir = null;
    269
    270    /**
    271     * Set to true to keep the game loop running. Set to false by shutdown() to allow the game loop to exit cleanly.
    272     */
    273    public volatile boolean running = true;
    274
    275    /** String that shows the debug information */
    276    public String debug = "";
    277
    278    /** Approximate time (in ms) of last update to debug string */
    279    long debugUpdateTime = getSystemTime();
    280
    281    /** holds the current fps */
    282    int fpsCounter = 0;
    283    long prevFrameTime = -1L;
    284
    285    /** Profiler currently displayed in the debug screen pie chart */
    286    private String debugProfilerName = "root";
    287
    288    public Minecraft(Canvas par1Canvas, MinecraftApplet par2MinecraftApplet, int par3, int par4, boolean par5)
    289    {
    290        StatList.nopInit();
    291        this.tempDisplayHeight = par4;
    292        this.fullscreen = par5;
    293        this.mcApplet = par2MinecraftApplet;
    294        Packet3Chat.maxChatLength = 32767;
    295        this.startTimerHackThread();
    296        this.mcCanvas = par1Canvas;
    297        this.displayWidth = par3;
    298        this.displayHeight = par4;
    299        this.fullscreen = par5;
    300        theMinecraft = this;
    301        TextureManager.func_94263_a();
    302    }
    303
    304    private void startTimerHackThread()
    305    {
    306        ThreadClientSleep threadclientsleep = new ThreadClientSleep(this, "Timer hack thread");
    307        threadclientsleep.setDaemon(true);
    308        threadclientsleep.start();
    309    }
    310
    311    public void crashed(CrashReport par1CrashReport)
    312    {
    313        this.hasCrashed = true;
    314        this.crashReporter = par1CrashReport;
    315    }
    316
    317    /**
    318     * Wrapper around displayCrashReportInternal
    319     */
    320    public void displayCrashReport(CrashReport par1CrashReport)
    321    {
    322        this.hasCrashed = true;
    323        this.displayCrashReportInternal(par1CrashReport);
    324    }
    325
    326    public abstract void displayCrashReportInternal(CrashReport crashreport);
    327
    328    public void setServer(String par1Str, int par2)
    329    {
    330        this.serverName = par1Str;
    331        this.serverPort = par2;
    332    }
    333
    334    /**
    335     * Starts the game: initializes the canvas, the title, the settings, etcetera.
    336     */
    337    public void startGame() throws LWJGLException
    338    {
    339        if (this.mcCanvas != null)
    340        {
    341            Graphics graphics = this.mcCanvas.getGraphics();
    342
    343            if (graphics != null)
    344            {
    345                graphics.setColor(Color.BLACK);
    346                graphics.fillRect(0, 0, this.displayWidth, this.displayHeight);
    347                graphics.dispose();
    348            }
    349
    350            Display.setParent(this.mcCanvas);
    351        }
    352        else if (this.fullscreen)
    353        {
    354            Display.setFullscreen(true);
    355            this.displayWidth = Display.getDisplayMode().getWidth();
    356            this.displayHeight = Display.getDisplayMode().getHeight();
    357
    358            if (this.displayWidth <= 0)
    359            {
    360                this.displayWidth = 1;
    361            }
    362
    363            if (this.displayHeight <= 0)
    364            {
    365                this.displayHeight = 1;
    366            }
    367        }
    368        else
    369        {
    370            Display.setDisplayMode(new DisplayMode(this.displayWidth, this.displayHeight));
    371        }
    372
    373        Display.setTitle("Minecraft Minecraft 1.5");
    374        this.func_98033_al().func_98233_a("LWJGL Version: " + Sys.getVersion());
    375
    376        try
    377        {
    378            Display.create((new PixelFormat()).withDepthBits(24));
    379        }
    380        catch (LWJGLException lwjglexception)
    381        {
    382            lwjglexception.printStackTrace();
    383
    384            try
    385            {
    386                Thread.sleep(1000L);
    387            }
    388            catch (InterruptedException interruptedexception)
    389            {
    390                ;
    391            }
    392
    393            Display.create();
    394        }
    395
    396        OpenGlHelper.initializeTextures();
    397        this.mcDataDir = getMinecraftDir();
    398        this.saveLoader = new AnvilSaveConverter(new File(this.mcDataDir, "saves"));
    399        this.gameSettings = new GameSettings(this, this.mcDataDir);
    400        this.texturePackList = new TexturePackList(this.mcDataDir, this);
    401        this.renderEngine = new RenderEngine(this.texturePackList, this.gameSettings);
    402        this.loadScreen();
    403        this.fontRenderer = new FontRenderer(this.gameSettings, "/font/default.png", this.renderEngine, false);
    404        this.standardGalacticFontRenderer = new FontRenderer(this.gameSettings, "/font/alternate.png", this.renderEngine, false);
    405
    406        FMLClientHandler.instance().beginMinecraftLoading(this);
    407
    408        if (this.gameSettings.language != null)
    409        {
    410            StringTranslate.getInstance().setLanguage(this.gameSettings.language, false);
    411            this.fontRenderer.setUnicodeFlag(StringTranslate.getInstance().isUnicode());
    412            this.fontRenderer.setBidiFlag(StringTranslate.isBidirectional(this.gameSettings.language));
    413        }
    414
    415        ColorizerGrass.setGrassBiomeColorizer(this.renderEngine.getTextureContents("/misc/grasscolor.png"));
    416        ColorizerFoliage.setFoliageBiomeColorizer(this.renderEngine.getTextureContents("/misc/foliagecolor.png"));
    417        this.entityRenderer = new EntityRenderer(this);
    418        RenderManager.instance.itemRenderer = new ItemRenderer(this);
    419        this.statFileWriter = new StatFileWriter(this.session, this.mcDataDir);
    420        AchievementList.openInventory.setStatStringFormatter(new StatStringFormatKeyInv(this));
    421        this.loadScreen();
    422        Mouse.create();
    423        this.mouseHelper = new MouseHelper(this.mcCanvas, this.gameSettings);
    424        this.checkGLError("Pre startup");
    425        GL11.glEnable(GL11.GL_TEXTURE_2D);
    426        GL11.glShadeModel(GL11.GL_SMOOTH);
    427        GL11.glClearDepth(1.0D);
    428        GL11.glEnable(GL11.GL_DEPTH_TEST);
    429        GL11.glDepthFunc(GL11.GL_LEQUAL);
    430        GL11.glEnable(GL11.GL_ALPHA_TEST);
    431        GL11.glAlphaFunc(GL11.GL_GREATER, 0.1F);
    432        GL11.glCullFace(GL11.GL_BACK);
    433        GL11.glMatrixMode(GL11.GL_PROJECTION);
    434        GL11.glLoadIdentity();
    435        GL11.glMatrixMode(GL11.GL_MODELVIEW);
    436        this.checkGLError("Startup");
    437        this.sndManager.loadSoundSettings(this.gameSettings);
    438        this.renderGlobal = new RenderGlobal(this, this.renderEngine);
    439        this.renderEngine.func_94152_c();
    440        GL11.glViewport(0, 0, this.displayWidth, this.displayHeight);
    441        this.effectRenderer = new EffectRenderer(this.theWorld, this.renderEngine);
    442
    443        FMLClientHandler.instance().finishMinecraftLoading();
    444
    445        try
    446        {
    447            this.downloadResourcesThread = new ThreadDownloadResources(this.mcDataDir, this);
    448            this.downloadResourcesThread.start();
    449        }
    450        catch (Exception exception)
    451        {
    452            ;
    453        }
    454
    455        this.checkGLError("Post startup");
    456        this.ingameGUI = new GuiIngame(this);
    457
    458        if (this.serverName != null)
    459        {
    460            this.displayGuiScreen(new GuiConnecting(new GuiMainMenu(), this, this.serverName, this.serverPort));
    461        }
    462        else
    463        {
    464            this.displayGuiScreen(new GuiMainMenu());
    465        }
    466
    467        this.loadingScreen = new LoadingScreenRenderer(this);
    468
    469        if (this.gameSettings.fullScreen && !this.fullscreen)
    470        {
    471            this.toggleFullscreen();
    472        }
    473
    474        FMLClientHandler.instance().onInitializationComplete();
    475    }
    476
    477    /**
    478     * Displays a new screen.
    479     */
    480    private void loadScreen() throws LWJGLException
    481    {
    482        ScaledResolution scaledresolution = new ScaledResolution(this.gameSettings, this.displayWidth, this.displayHeight);
    483        GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);
    484        GL11.glMatrixMode(GL11.GL_PROJECTION);
    485        GL11.glLoadIdentity();
    486        GL11.glOrtho(0.0D, scaledresolution.getScaledWidth_double(), scaledresolution.getScaledHeight_double(), 0.0D, 1000.0D, 3000.0D);
    487        GL11.glMatrixMode(GL11.GL_MODELVIEW);
    488        GL11.glLoadIdentity();
    489        GL11.glTranslatef(0.0F, 0.0F, -2000.0F);
    490        GL11.glViewport(0, 0, this.displayWidth, this.displayHeight);
    491        GL11.glClearColor(0.0F, 0.0F, 0.0F, 0.0F);
    492        GL11.glDisable(GL11.GL_LIGHTING);
    493        GL11.glEnable(GL11.GL_TEXTURE_2D);
    494        GL11.glDisable(GL11.GL_FOG);
    495        Tessellator tessellator = Tessellator.instance;
    496        this.renderEngine.func_98187_b("/title/mojang.png");
    497        tessellator.startDrawingQuads();
    498        tessellator.setColorOpaque_I(16777215);
    499        tessellator.addVertexWithUV(0.0D, (double)this.displayHeight, 0.0D, 0.0D, 0.0D);
    500        tessellator.addVertexWithUV((double)this.displayWidth, (double)this.displayHeight, 0.0D, 0.0D, 0.0D);
    501        tessellator.addVertexWithUV((double)this.displayWidth, 0.0D, 0.0D, 0.0D, 0.0D);
    502        tessellator.addVertexWithUV(0.0D, 0.0D, 0.0D, 0.0D, 0.0D);
    503        tessellator.draw();
    504        GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
    505        tessellator.setColorOpaque_I(16777215);
    506        short short1 = 256;
    507        short short2 = 256;
    508        this.scaledTessellator((scaledresolution.getScaledWidth() - short1) / 2, (scaledresolution.getScaledHeight() - short2) / 2, 0, 0, short1, short2);
    509        GL11.glDisable(GL11.GL_LIGHTING);
    510        GL11.glDisable(GL11.GL_FOG);
    511        GL11.glEnable(GL11.GL_ALPHA_TEST);
    512        GL11.glAlphaFunc(GL11.GL_GREATER, 0.1F);
    513        Display.swapBuffers();
    514    }
    515
    516    /**
    517     * Loads Tessellator with a scaled resolution
    518     */
    519    public void scaledTessellator(int par1, int par2, int par3, int par4, int par5, int par6)
    520    {
    521        float f = 0.00390625F;
    522        float f1 = 0.00390625F;
    523        Tessellator tessellator = Tessellator.instance;
    524        tessellator.startDrawingQuads();
    525        tessellator.addVertexWithUV((double)(par1 + 0), (double)(par2 + par6), 0.0D, (double)((float)(par3 + 0) * f), (double)((float)(par4 + par6) * f1));
    526        tessellator.addVertexWithUV((double)(par1 + par5), (double)(par2 + par6), 0.0D, (double)((float)(par3 + par5) * f), (double)((float)(par4 + par6) * f1));
    527        tessellator.addVertexWithUV((double)(par1 + par5), (double)(par2 + 0), 0.0D, (double)((float)(par3 + par5) * f), (double)((float)(par4 + 0) * f1));
    528        tessellator.addVertexWithUV((double)(par1 + 0), (double)(par2 + 0), 0.0D, (double)((float)(par3 + 0) * f), (double)((float)(par4 + 0) * f1));
    529        tessellator.draw();
    530    }
    531
    532    /**
    533     * gets the working dir (OS specific) for minecraft
    534     */
    535    public static File getMinecraftDir()
    536    {
    537        if (minecraftDir == null)
    538        {
    539            minecraftDir = getAppDir("minecraft");
    540        }
    541
    542        return minecraftDir;
    543    }
    544
    545    /**
    546     * gets the working dir (OS specific) for the specific application (which is always minecraft)
    547     */
    548    public static File getAppDir(String par0Str)
    549    {
    550        String s1 = System.getProperty("user.home", ".");
    551        File file1;
    552
    553        switch (EnumOSHelper.field_90049_a[getOs().ordinal()])
    554        {
    555            case 1:
    556            case 2:
    557                file1 = new File(s1, '.' + par0Str + '/');
    558                break;
    559            case 3:
    560                String s2 = System.getenv("APPDATA");
    561
    562                if (s2 != null)
    563                {
    564                    file1 = new File(s2, "." + par0Str + '/');
    565                }
    566                else
    567                {
    568                    file1 = new File(s1, '.' + par0Str + '/');
    569                }
    570
    571                break;
    572            case 4:
    573                file1 = new File(s1, "Library/Application Support/" + par0Str);
    574                break;
    575            default:
    576                file1 = new File(s1, par0Str + '/');
    577        }
    578
    579        if (!file1.exists() && !file1.mkdirs())
    580        {
    581            throw new RuntimeException("The working directory could not be created: " + file1);
    582        }
    583        else
    584        {
    585            return file1;
    586        }
    587    }
    588
    589    public static EnumOS getOs()
    590    {
    591        String s = System.getProperty("os.name").toLowerCase();
    592        return s.contains("win") ? EnumOS.WINDOWS : (s.contains("mac") ? EnumOS.MACOS : (s.contains("solaris") ? EnumOS.SOLARIS : (s.contains("sunos") ? EnumOS.SOLARIS : (s.contains("linux") ? EnumOS.LINUX : (s.contains("unix") ? EnumOS.LINUX : EnumOS.UNKNOWN)))));
    593    }
    594
    595    /**
    596     * Returns the save loader that is currently being used
    597     */
    598    public ISaveFormat getSaveLoader()
    599    {
    600        return this.saveLoader;
    601    }
    602
    603    /**
    604     * Sets the argument GuiScreen as the main (topmost visible) screen.
    605     */
    606    public void displayGuiScreen(GuiScreen par1GuiScreen)
    607    {
    608        if (this.currentScreen != null)
    609        {
    610            this.currentScreen.onGuiClosed();
    611        }
    612
    613        this.statFileWriter.syncStats();
    614
    615        if (par1GuiScreen == null && this.theWorld == null)
    616        {
    617            par1GuiScreen = new GuiMainMenu();
    618        }
    619        else if (par1GuiScreen == null && this.thePlayer.getHealth() <= 0)
    620        {
    621            par1GuiScreen = new GuiGameOver();
    622        }
    623
    624        if (par1GuiScreen instanceof GuiMainMenu)
    625        {
    626            this.gameSettings.showDebugInfo = false;
    627            this.ingameGUI.getChatGUI().clearChatMessages();
    628        }
    629
    630        this.currentScreen = (GuiScreen)par1GuiScreen;
    631
    632        if (par1GuiScreen != null)
    633        {
    634            this.setIngameNotInFocus();
    635            ScaledResolution scaledresolution = new ScaledResolution(this.gameSettings, this.displayWidth, this.displayHeight);
    636            int i = scaledresolution.getScaledWidth();
    637            int j = scaledresolution.getScaledHeight();
    638            ((GuiScreen)par1GuiScreen).setWorldAndResolution(this, i, j);
    639            this.skipRenderWorld = false;
    640        }
    641        else
    642        {
    643            this.setIngameFocus();
    644        }
    645    }
    646
    647    /**
    648     * Checks for an OpenGL error. If there is one, prints the error ID and error string.
    649     */
    650    private void checkGLError(String par1Str)
    651    {
    652        int i = GL11.glGetError();
    653
    654        if (i != 0)
    655        {
    656            String s1 = GLU.gluErrorString(i);
    657            this.func_98033_al().func_98232_c("########## GL ERROR ##########");
    658            this.func_98033_al().func_98232_c("@ " + par1Str);
    659            this.func_98033_al().func_98232_c(i + ": " + s1);
    660        }
    661    }
    662
    663    /**
    664     * Shuts down the minecraft applet by stopping the resource downloads, and clearing up GL stuff; called when the
    665     * application (or web page) is exited.
    666     */
    667    public void shutdownMinecraftApplet()
    668    {
    669        try
    670        {
    671            this.statFileWriter.syncStats();
    672
    673            try
    674            {
    675                if (this.downloadResourcesThread != null)
    676                {
    677                    this.downloadResourcesThread.closeMinecraft();
    678                }
    679            }
    680            catch (Exception exception)
    681            {
    682                ;
    683            }
    684
    685            this.func_98033_al().func_98233_a("Stopping!");
    686
    687            try
    688            {
    689                this.loadWorld((WorldClient)null);
    690            }
    691            catch (Throwable throwable)
    692            {
    693                ;
    694            }
    695
    696            try
    697            {
    698                GLAllocation.deleteTexturesAndDisplayLists();
    699            }
    700            catch (Throwable throwable1)
    701            {
    702                ;
    703            }
    704
    705            this.sndManager.closeMinecraft();
    706            Mouse.destroy();
    707            Keyboard.destroy();
    708        }
    709        finally
    710        {
    711            Display.destroy();
    712
    713            if (!this.hasCrashed)
    714            {
    715                System.exit(0);
    716            }
    717        }
    718
    719        System.gc();
    720    }
    721
    722    public void run()
    723    {
    724        this.running = true;
    725
    726        try
    727        {
    728            this.startGame();
    729        }
    730        catch (Exception exception)
    731        {
    732            exception.printStackTrace();
    733            this.displayCrashReport(this.addGraphicsAndWorldToCrashReport(new CrashReport("Failed to start game", exception)));
    734            return;
    735        }
    736
    737        try
    738        {
    739            while (this.running)
    740            {
    741                if (this.hasCrashed && this.crashReporter != null)
    742                {
    743                    this.displayCrashReport(this.crashReporter);
    744                    return;
    745                }
    746
    747                if (this.refreshTexturePacksScheduled)
    748                {
    749                    this.refreshTexturePacksScheduled = false;
    750                    this.renderEngine.refreshTextures();
    751                }
    752
    753                try
    754                {
    755                    this.runGameLoop();
    756                }
    757                catch (OutOfMemoryError outofmemoryerror)
    758                {
    759                    this.freeMemory();
    760                    this.displayGuiScreen(new GuiMemoryErrorScreen());
    761                    System.gc();
    762                }
    763            }
    764        }
    765        catch (MinecraftError minecrafterror)
    766        {
    767            ;
    768        }
    769        catch (ReportedException reportedexception)
    770        {
    771            this.addGraphicsAndWorldToCrashReport(reportedexception.getCrashReport());
    772            this.freeMemory();
    773            reportedexception.printStackTrace();
    774            this.displayCrashReport(reportedexception.getCrashReport());
    775        }
    776        catch (Throwable throwable)
    777        {
    778            CrashReport crashreport = this.addGraphicsAndWorldToCrashReport(new CrashReport("Unexpected error", throwable));
    779            this.freeMemory();
    780            throwable.printStackTrace();
    781            this.displayCrashReport(crashreport);
    782        }
    783        finally
    784        {
    785            this.shutdownMinecraftApplet();
    786        }
    787    }
    788
    789    /**
    790     * Called repeatedly from run()
    791     */
    792    private void runGameLoop()
    793    {
    794        if (this.mcApplet != null && !this.mcApplet.isActive())
    795        {
    796            this.running = false;
    797        }
    798        else
    799        {
    800            AxisAlignedBB.getAABBPool().cleanPool();
    801
    802            if (this.theWorld != null)
    803            {
    804                this.theWorld.getWorldVec3Pool().clear();
    805            }
    806
    807            this.mcProfiler.startSection("root");
    808
    809            if (this.mcCanvas == null && Display.isCloseRequested())
    810            {
    811                this.shutdown();
    812            }
    813
    814            if (this.isGamePaused && this.theWorld != null)
    815            {
    816                float f = this.timer.renderPartialTicks;
    817                this.timer.updateTimer();
    818                this.timer.renderPartialTicks = f;
    819            }
    820            else
    821            {
    822                this.timer.updateTimer();
    823            }
    824
    825            long i = System.nanoTime();
    826            this.mcProfiler.startSection("tick");
    827
    828            for (int j = 0; j < this.timer.elapsedTicks; ++j)
    829            {
    830                this.runTick();
    831            }
    832
    833            this.mcProfiler.endStartSection("preRenderErrors");
    834            long k = System.nanoTime() - i;
    835            this.checkGLError("Pre render");
    836            RenderBlocks.fancyGrass = this.gameSettings.fancyGraphics;
    837            this.mcProfiler.endStartSection("sound");
    838            this.sndManager.setListener(this.thePlayer, this.timer.renderPartialTicks);
    839
    840            if (!this.isGamePaused)
    841            {
    842                this.sndManager.func_92071_g();
    843            }
    844
    845            this.mcProfiler.endSection();
    846            this.mcProfiler.startSection("render");
    847            this.mcProfiler.startSection("display");
    848            GL11.glEnable(GL11.GL_TEXTURE_2D);
    849
    850            if (!Keyboard.isKeyDown(65))
    851            {
    852                Display.update();
    853            }
    854
    855            if (this.thePlayer != null && this.thePlayer.isEntityInsideOpaqueBlock())
    856            {
    857                this.gameSettings.thirdPersonView = 0;
    858            }
    859
    860            this.mcProfiler.endSection();
    861
    862            if (!this.skipRenderWorld)
    863            {
    864                FMLCommonHandler.instance().onRenderTickStart(this.timer.renderPartialTicks);
    865                this.mcProfiler.endStartSection("gameRenderer");
    866                this.entityRenderer.updateCameraAndRender(this.timer.renderPartialTicks);
    867                this.mcProfiler.endSection();
    868                FMLCommonHandler.instance().onRenderTickEnd(this.timer.renderPartialTicks);
    869            }
    870
    871            GL11.glFlush();
    872            this.mcProfiler.endSection();
    873
    874            if (!Display.isActive() && this.fullscreen)
    875            {
    876                this.toggleFullscreen();
    877            }
    878
    879            if (this.gameSettings.showDebugInfo && this.gameSettings.showDebugProfilerChart)
    880            {
    881                if (!this.mcProfiler.profilingEnabled)
    882                {
    883                    this.mcProfiler.clearProfiling();
    884                }
    885
    886                this.mcProfiler.profilingEnabled = true;
    887                this.displayDebugInfo(k);
    888            }
    889            else
    890            {
    891                this.mcProfiler.profilingEnabled = false;
    892                this.prevFrameTime = System.nanoTime();
    893            }
    894
    895            this.guiAchievement.updateAchievementWindow();
    896            this.mcProfiler.startSection("root");
    897            Thread.yield();
    898
    899            if (Keyboard.isKeyDown(65))
    900            {
    901                Display.update();
    902            }
    903
    904            this.screenshotListener();
    905
    906            if (this.mcCanvas != null && !this.fullscreen && (this.mcCanvas.getWidth() != this.displayWidth || this.mcCanvas.getHeight() != this.displayHeight))
    907            {
    908                this.displayWidth = this.mcCanvas.getWidth();
    909                this.displayHeight = this.mcCanvas.getHeight();
    910
    911                if (this.displayWidth <= 0)
    912                {
    913                    this.displayWidth = 1;
    914                }
    915
    916                if (this.displayHeight <= 0)
    917                {
    918                    this.displayHeight = 1;
    919                }
    920
    921                this.resize(this.displayWidth, this.displayHeight);
    922            }
    923
    924            this.checkGLError("Post render");
    925            ++this.fpsCounter;
    926            boolean flag = this.isGamePaused;
    927            this.isGamePaused = this.isSingleplayer() && this.currentScreen != null && this.currentScreen.doesGuiPauseGame() && !this.theIntegratedServer.getPublic();
    928
    929            if (this.isIntegratedServerRunning() && this.thePlayer != null && this.thePlayer.sendQueue != null && this.isGamePaused != flag)
    930            {
    931                ((MemoryConnection)this.thePlayer.sendQueue.getNetManager()).setGamePaused(this.isGamePaused);
    932            }
    933
    934            while (getSystemTime() >= this.debugUpdateTime + 1000L)
    935            {
    936                debugFPS = this.fpsCounter;
    937                this.debug = debugFPS + " fps, " + WorldRenderer.chunksUpdated + " chunk updates";
    938                WorldRenderer.chunksUpdated = 0;
    939                this.debugUpdateTime += 1000L;
    940                this.fpsCounter = 0;
    941                this.usageSnooper.addMemoryStatsToSnooper();
    942
    943                if (!this.usageSnooper.isSnooperRunning())
    944                {
    945                    this.usageSnooper.startSnooper();
    946                }
    947            }
    948
    949            this.mcProfiler.endSection();
    950
    951            if (this.func_90020_K() > 0)
    952            {
    953                Display.sync(EntityRenderer.performanceToFps(this.func_90020_K()));
    954            }
    955        }
    956    }
    957
    958    private int func_90020_K()
    959    {
    960        return this.currentScreen != null && this.currentScreen instanceof GuiMainMenu ? 2 : this.gameSettings.limitFramerate;
    961    }
    962
    963    public void freeMemory()
    964    {
    965        try
    966        {
    967            memoryReserve = new byte[0];
    968            this.renderGlobal.deleteAllDisplayLists();
    969        }
    970        catch (Throwable throwable)
    971        {
    972            ;
    973        }
    974
    975        try
    976        {
    977            System.gc();
    978            AxisAlignedBB.getAABBPool().clearPool();
    979            this.theWorld.getWorldVec3Pool().clearAndFreeCache();
    980        }
    981        catch (Throwable throwable1)
    982        {
    983            ;
    984        }
    985
    986        try
    987        {
    988            System.gc();
    989            this.loadWorld((WorldClient)null);
    990        }
    991        catch (Throwable throwable2)
    992        {
    993            ;
    994        }
    995
    996        System.gc();
    997    }
    998
    999    /**
    1000     * checks if keys are down
    1001     */
    1002    private void screenshotListener()
    1003    {
    1004        if (Keyboard.isKeyDown(60))
    1005        {
    1006            if (!this.isTakingScreenshot)
    1007            {
    1008                this.isTakingScreenshot = true;
    1009                this.ingameGUI.getChatGUI().printChatMessage(ScreenShotHelper.saveScreenshot(minecraftDir, this.displayWidth, this.displayHeight));
    1010            }
    1011        }
    1012        else
    1013        {
    1014            this.isTakingScreenshot = false;
    1015        }
    1016    }
    1017
    1018    /**
    1019     * Update debugProfilerName in response to number keys in debug screen
    1020     */
    1021    private void updateDebugProfilerName(int par1)
    1022    {
    1023        List list = this.mcProfiler.getProfilingData(this.debugProfilerName);
    1024
    1025        if (list != null && !list.isEmpty())
    1026        {
    1027            ProfilerResult profilerresult = (ProfilerResult)list.remove(0);
    1028
    1029            if (par1 == 0)
    1030            {
    1031                if (profilerresult.field_76331_c.length() > 0)
    1032                {
    1033                    int j = this.debugProfilerName.lastIndexOf(".");
    1034
    1035                    if (j >= 0)
    1036                    {
    1037                        this.debugProfilerName = this.debugProfilerName.substring(0, j);
    1038                    }
    1039                }
    1040            }
    1041            else
    1042            {
    1043                --par1;
    1044
    1045                if (par1 < list.size() && !((ProfilerResult)list.get(par1)).field_76331_c.equals("unspecified"))
    1046                {
    1047                    if (this.debugProfilerName.length() > 0)
    1048                    {
    1049                        this.debugProfilerName = this.debugProfilerName + ".";
    1050                    }
    1051
    1052                    this.debugProfilerName = this.debugProfilerName + ((ProfilerResult)list.get(par1)).field_76331_c;
    1053                }
    1054            }
    1055        }
    1056    }
    1057
    1058    private void displayDebugInfo(long par1)
    1059    {
    1060        if (this.mcProfiler.profilingEnabled)
    1061        {
    1062            List list = this.mcProfiler.getProfilingData(this.debugProfilerName);
    1063            ProfilerResult profilerresult = (ProfilerResult)list.remove(0);
    1064            GL11.glClear(GL11.GL_DEPTH_BUFFER_BIT);
    1065            GL11.glMatrixMode(GL11.GL_PROJECTION);
    1066            GL11.glEnable(GL11.GL_COLOR_MATERIAL);
    1067            GL11.glLoadIdentity();
    1068            GL11.glOrtho(0.0D, (double)this.displayWidth, (double)this.displayHeight, 0.0D, 1000.0D, 3000.0D);
    1069            GL11.glMatrixMode(GL11.GL_MODELVIEW);
    1070            GL11.glLoadIdentity();
    1071            GL11.glTranslatef(0.0F, 0.0F, -2000.0F);
    1072            GL11.glLineWidth(1.0F);
    1073            GL11.glDisable(GL11.GL_TEXTURE_2D);
    1074            Tessellator tessellator = Tessellator.instance;
    1075            short short1 = 160;
    1076            int j = this.displayWidth - short1 - 10;
    1077            int k = this.displayHeight - short1 * 2;
    1078            GL11.glEnable(GL11.GL_BLEND);
    1079            tessellator.startDrawingQuads();
    1080            tessellator.setColorRGBA_I(0, 200);
    1081            tessellator.addVertex((double)((float)j - (float)short1 * 1.1F), (double)((float)k - (float)short1 * 0.6F - 16.0F), 0.0D);
    1082            tessellator.addVertex((double)((float)j - (float)short1 * 1.1F), (double)(k + short1 * 2), 0.0D);
    1083            tessellator.addVertex((double)((float)j + (float)short1 * 1.1F), (double)(k + short1 * 2), 0.0D);
    1084            tessellator.addVertex((double)((float)j + (float)short1 * 1.1F), (double)((float)k - (float)short1 * 0.6F - 16.0F), 0.0D);
    1085            tessellator.draw();
    1086            GL11.glDisable(GL11.GL_BLEND);
    1087            double d0 = 0.0D;
    1088            int l;
    1089
    1090            for (int i1 = 0; i1 < list.size(); ++i1)
    1091            {
    1092                ProfilerResult profilerresult1 = (ProfilerResult)list.get(i1);
    1093                l = MathHelper.floor_double(profilerresult1.field_76332_a / 4.0D) + 1;
    1094                tessellator.startDrawing(6);
    1095                tessellator.setColorOpaque_I(profilerresult1.func_76329_a());
    1096                tessellator.addVertex((double)j, (double)k, 0.0D);
    1097                int j1;
    1098                float f;
    1099                float f1;
    1100                float f2;
    1101
    1102                for (j1 = l; j1 >= 0; --j1)
    1103                {
    1104                    f = (float)((d0 + profilerresult1.field_76332_a * (double)j1 / (double)l) * Math.PI * 2.0D / 100.0D);
    1105                    f2 = MathHelper.sin(f) * (float)short1;
    1106                    f1 = MathHelper.cos(f) * (float)short1 * 0.5F;
    1107                    tessellator.addVertex((double)((float)j + f2), (double)((float)k - f1), 0.0D);
    1108                }
    1109
    1110                tessellator.draw();
    1111                tessellator.startDrawing(5);
    1112                tessellator.setColorOpaque_I((profilerresult1.func_76329_a() & 16711422) >> 1);
    1113
    1114                for (j1 = l; j1 >= 0; --j1)
    1115                {
    1116                    f = (float)((d0 + profilerresult1.field_76332_a * (double)j1 / (double)l) * Math.PI * 2.0D / 100.0D);
    1117                    f2 = MathHelper.sin(f) * (float)short1;
    1118                    f1 = MathHelper.cos(f) * (float)short1 * 0.5F;
    1119                    tessellator.addVertex((double)((float)j + f2), (double)((float)k - f1), 0.0D);
    1120                    tessellator.addVertex((double)((float)j + f2), (double)((float)k - f1 + 10.0F), 0.0D);
    1121                }
    1122
    1123                tessellator.draw();
    1124                d0 += profilerresult1.field_76332_a;
    1125            }
    1126
    1127            DecimalFormat decimalformat = new DecimalFormat("##0.00");
    1128            GL11.glEnable(GL11.GL_TEXTURE_2D);
    1129            String s = "";
    1130
    1131            if (!profilerresult.field_76331_c.equals("unspecified"))
    1132            {
    1133                s = s + "[0] ";
    1134            }
    1135
    1136            if (profilerresult.field_76331_c.length() == 0)
    1137            {
    1138                s = s + "ROOT ";
    1139            }
    1140            else
    1141            {
    1142                s = s + profilerresult.field_76331_c + " ";
    1143            }
    1144
    1145            l = 16777215;
    1146            this.fontRenderer.drawStringWithShadow(s, j - short1, k - short1 / 2 - 16, l);
    1147            this.fontRenderer.drawStringWithShadow(s = decimalformat.format(profilerresult.field_76330_b) + "%", j + short1 - this.fontRenderer.getStringWidth(s), k - short1 / 2 - 16, l);
    1148
    1149            for (int k1 = 0; k1 < list.size(); ++k1)
    1150            {
    1151                ProfilerResult profilerresult2 = (ProfilerResult)list.get(k1);
    1152                String s1 = "";
    1153
    1154                if (profilerresult2.field_76331_c.equals("unspecified"))
    1155                {
    1156                    s1 = s1 + "[?] ";
    1157                }
    1158                else
    1159                {
    1160                    s1 = s1 + "[" + (k1 + 1) + "] ";
    1161                }
    1162
    1163                s1 = s1 + profilerresult2.field_76331_c;
    1164                this.fontRenderer.drawStringWithShadow(s1, j - short1, k + short1 / 2 + k1 * 8 + 20, profilerresult2.func_76329_a());
    1165                this.fontRenderer.drawStringWithShadow(s1 = decimalformat.format(profilerresult2.field_76332_a) + "%", j + short1 - 50 - this.fontRenderer.getStringWidth(s1), k + short1 / 2 + k1 * 8 + 20, profilerresult2.func_76329_a());
    1166                this.fontRenderer.drawStringWithShadow(s1 = decimalformat.format(profilerresult2.field_76330_b) + "%", j + short1 - this.fontRenderer.getStringWidth(s1), k + short1 / 2 + k1 * 8 + 20, profilerresult2.func_76329_a());
    1167            }
    1168        }
    1169    }
    1170
    1171    /**
    1172     * Called when the window is closing. Sets 'running' to false which allows the game loop to exit cleanly.
    1173     */
    1174    public void shutdown()
    1175    {
    1176        this.running = false;
    1177    }
    1178
    1179    /**
    1180     * Will set the focus to ingame if the Minecraft window is the active with focus. Also clears any GUI screen
    1181     * currently displayed
    1182     */
    1183    public void setIngameFocus()
    1184    {
    1185        if (Display.isActive())
    1186        {
    1187            if (!this.inGameHasFocus)
    1188            {
    1189                this.inGameHasFocus = true;
    1190                this.mouseHelper.grabMouseCursor();
    1191                this.displayGuiScreen((GuiScreen)null);
    1192                this.leftClickCounter = 10000;
    1193            }
    1194        }
    1195    }
    1196
    1197    /**
    1198     * Resets the player keystate, disables the ingame focus, and ungrabs the mouse cursor.
    1199     */
    1200    public void setIngameNotInFocus()
    1201    {
    1202        if (this.inGameHasFocus)
    1203        {
    1204            KeyBinding.unPressAllKeys();
    1205            this.inGameHasFocus = false;
    1206            this.mouseHelper.ungrabMouseCursor();
    1207        }
    1208    }
    1209
    1210    /**
    1211     * Displays the ingame menu
    1212     */
    1213    public void displayInGameMenu()
    1214    {
    1215        if (this.currentScreen == null)
    1216        {
    1217            this.displayGuiScreen(new GuiIngameMenu());
    1218
    1219            if (this.isSingleplayer() && !this.theIntegratedServer.getPublic())
    1220            {
    1221                this.sndManager.pauseAllSounds();
    1222            }
    1223        }
    1224    }
    1225
    1226    private void sendClickBlockToController(int par1, boolean par2)
    1227    {
    1228        if (!par2)
    1229        {
    1230            this.leftClickCounter = 0;
    1231        }
    1232
    1233        if (par1 != 0 || this.leftClickCounter <= 0)
    1234        {
    1235            if (par2 && this.objectMouseOver != null && this.objectMouseOver.typeOfHit == EnumMovingObjectType.TILE && par1 == 0)
    1236            {
    1237                int j = this.objectMouseOver.blockX;
    1238                int k = this.objectMouseOver.blockY;
    1239                int l = this.objectMouseOver.blockZ;
    1240                this.playerController.onPlayerDamageBlock(j, k, l, this.objectMouseOver.sideHit);
    1241
    1242                if (this.thePlayer.canCurrentToolHarvestBlock(j, k, l))
    1243                {
    1244                    this.effectRenderer.addBlockHitEffects(j, k, l, this.objectMouseOver);
    1245                    this.thePlayer.swingItem();
    1246                }
    1247            }
    1248            else
    1249            {
    1250                this.playerController.resetBlockRemoving();
    1251            }
    1252        }
    1253    }
    1254
    1255    /**
    1256     * Called whenever the mouse is clicked. Button clicked is 0 for left clicking and 1 for right clicking. Args:
    1257     * buttonClicked
    1258     */
    1259    private void clickMouse(int par1)
    1260    {
    1261        if (par1 != 0 || this.leftClickCounter <= 0)
    1262        {
    1263            if (par1 == 0)
    1264            {
    1265                this.thePlayer.swingItem();
    1266            }
    1267
    1268            if (par1 == 1)
    1269            {
    1270                this.rightClickDelayTimer = 4;
    1271            }
    1272
    1273            boolean flag = true;
    1274            ItemStack itemstack = this.thePlayer.inventory.getCurrentItem();
    1275
    1276            if (this.objectMouseOver == null)
    1277            {
    1278                if (par1 == 0 && this.playerController.isNotCreative())
    1279                {
    1280                    this.leftClickCounter = 10;
    1281                }
    1282            }
    1283            else if (this.objectMouseOver.typeOfHit == EnumMovingObjectType.ENTITY)
    1284            {
    1285                if (par1 == 0)
    1286                {
    1287                    this.playerController.attackEntity(this.thePlayer, this.objectMouseOver.entityHit);
    1288                }
    1289
    1290                if (par1 == 1 && this.playerController.func_78768_b(this.thePlayer, this.objectMouseOver.entityHit))
    1291                {
    1292                    flag = false;
    1293                }
    1294            }
    1295            else if (this.objectMouseOver.typeOfHit == EnumMovingObjectType.TILE)
    1296            {
    1297                int j = this.objectMouseOver.blockX;
    1298                int k = this.objectMouseOver.blockY;
    1299                int l = this.objectMouseOver.blockZ;
    1300                int i1 = this.objectMouseOver.sideHit;
    1301
    1302                if (par1 == 0)
    1303                {
    1304                    this.playerController.clickBlock(j, k, l, this.objectMouseOver.sideHit);
    1305                }
    1306                else
    1307                {
    1308                    int j1 = itemstack != null ? itemstack.stackSize : 0;
    1309
    1310                    boolean result = !ForgeEventFactory.onPlayerInteract(thePlayer, Action.RIGHT_CLICK_BLOCK, j, k, l, i1).isCanceled();
    1311                    if (result && this.playerController.onPlayerRightClick(this.thePlayer, this.theWorld, itemstack, j, k, l, i1, this.objectMouseOver.hitVec))
    1312                    {
    1313                        flag = false;
    1314                        this.thePlayer.swingItem();
    1315                    }
    1316
    1317                    if (itemstack == null)
    1318                    {
    1319                        return;
    1320                    }
    1321
    1322                    if (itemstack.stackSize == 0)
    1323                    {
    1324                        this.thePlayer.inventory.mainInventory[this.thePlayer.inventory.currentItem] = null;
    1325                    }
    1326                    else if (itemstack.stackSize != j1 || this.playerController.isInCreativeMode())
    1327                    {
    1328                        this.entityRenderer.itemRenderer.resetEquippedProgress();
    1329                    }
    1330                }
    1331            }
    1332
    1333            if (flag && par1 == 1)
    1334            {
    1335                ItemStack itemstack1 = this.thePlayer.inventory.getCurrentItem();
    1336
    1337                boolean result = !ForgeEventFactory.onPlayerInteract(thePlayer, Action.RIGHT_CLICK_AIR, 0, 0, 0, -1).isCanceled();
    1338                if (result && itemstack1 != null && this.playerController.sendUseItem(this.thePlayer, this.theWorld, itemstack1))
    1339                {
    1340                    this.entityRenderer.itemRenderer.resetEquippedProgress2();
    1341                }
    1342            }
    1343        }
    1344    }
    1345
    1346    /**
    1347     * Toggles fullscreen mode.
    1348     */
    1349    public void toggleFullscreen()
    1350    {
    1351        try
    1352        {
    1353            this.fullscreen = !this.fullscreen;
    1354
    1355            if (this.fullscreen)
    1356            {
    1357                Display.setDisplayMode(Display.getDesktopDisplayMode());
    1358                this.displayWidth = Display.getDisplayMode().getWidth();
    1359                this.displayHeight = Display.getDisplayMode().getHeight();
    1360
    1361                if (this.displayWidth <= 0)
    1362                {
    1363                    this.displayWidth = 1;
    1364                }
    1365
    1366                if (this.displayHeight <= 0)
    1367                {
    1368                    this.displayHeight = 1;
    1369                }
    1370            }
    1371            else
    1372            {
    1373                if (this.mcCanvas != null)
    1374                {
    1375                    this.displayWidth = this.mcCanvas.getWidth();
    1376                    this.displayHeight = this.mcCanvas.getHeight();
    1377                }
    1378                else
    1379                {
    1380                    this.displayWidth = this.tempDisplayWidth;
    1381                    this.displayHeight = this.tempDisplayHeight;
    1382                }
    1383
    1384                if (this.displayWidth <= 0)
    1385                {
    1386                    this.displayWidth = 1;
    1387                }
    1388
    1389                if (this.displayHeight <= 0)
    1390                {
    1391                    this.displayHeight = 1;
    1392                }
    1393            }
    1394
    1395            if (this.currentScreen != null)
    1396            {
    1397                this.resize(this.displayWidth, this.displayHeight);
    1398            }
    1399
    1400            Display.setFullscreen(this.fullscreen);
    1401            Display.setVSyncEnabled(this.gameSettings.enableVsync);
    1402            Display.update();
    1403        }
    1404        catch (Exception exception)
    1405        {
    1406            exception.printStackTrace();
    1407        }
    1408    }
    1409
    1410    /**
    1411     * Called to resize the current screen.
    1412     */
    1413    private void resize(int par1, int par2)
    1414    {
    1415        this.displayWidth = par1 <= 0 ? 1 : par1;
    1416        this.displayHeight = par2 <= 0 ? 1 : par2;
    1417
    1418        if (this.currentScreen != null)
    1419        {
    1420            ScaledResolution scaledresolution = new ScaledResolution(this.gameSettings, par1, par2);
    1421            int k = scaledresolution.getScaledWidth();
    1422            int l = scaledresolution.getScaledHeight();
    1423            this.currentScreen.setWorldAndResolution(this, k, l);
    1424        }
    1425    }
    1426
    1427    /**
    1428     * Runs the current tick.
    1429     */
    1430    public void runTick()
    1431    {
    1432        FMLCommonHandler.instance().rescheduleTicks(Side.CLIENT);
    1433
    1434        if (this.rightClickDelayTimer > 0)
    1435        {
    1436            --this.rightClickDelayTimer;
    1437        }
    1438
    1439        FMLCommonHandler.instance().onPreClientTick();
    1440
    1441        this.mcProfiler.startSection("stats");
    1442        this.statFileWriter.func_77449_e();
    1443        this.mcProfiler.endStartSection("gui");
    1444
    1445        if (!this.isGamePaused)
    1446        {
    1447            this.ingameGUI.updateTick();
    1448        }
    1449
    1450        this.mcProfiler.endStartSection("pick");
    1451        this.entityRenderer.getMouseOver(1.0F);
    1452        this.mcProfiler.endStartSection("gameMode");
    1453
    1454        if (!this.isGamePaused && this.theWorld != null)
    1455        {
    1456            this.playerController.updateController();
    1457        }
    1458
    1459        this.renderEngine.func_98187_b("/terrain.png");
    1460        this.mcProfiler.endStartSection("textures");
    1461
    1462        if (!this.isGamePaused)
    1463        {
    1464            this.renderEngine.updateDynamicTextures();
    1465        }
    1466
    1467        if (this.currentScreen == null && this.thePlayer != null)
    1468        {
    1469            if (this.thePlayer.getHealth() <= 0)
    1470            {
    1471                this.displayGuiScreen((GuiScreen)null);
    1472            }
    1473            else if (this.thePlayer.isPlayerSleeping() && this.theWorld != null)
    1474            {
    1475                this.displayGuiScreen(new GuiSleepMP());
    1476            }
    1477        }
    1478        else if (this.currentScreen != null && this.currentScreen instanceof GuiSleepMP && !this.thePlayer.isPlayerSleeping())
    1479        {
    1480            this.displayGuiScreen((GuiScreen)null);
    1481        }
    1482
    1483        if (this.currentScreen != null)
    1484        {
    1485            this.leftClickCounter = 10000;
    1486        }
    1487
    1488        CrashReport crashreport;
    1489        CrashReportCategory crashreportcategory;
    1490
    1491        if (this.currentScreen != null)
    1492        {
    1493            try
    1494            {
    1495                this.currentScreen.handleInput();
    1496            }
    1497            catch (Throwable throwable)
    1498            {
    1499                crashreport = CrashReport.makeCrashReport(throwable, "Updating screen events");
    1500                crashreportcategory = crashreport.makeCategory("Affected screen");
    1501                crashreportcategory.addCrashSectionCallable("Screen name", new CallableUpdatingScreenName(this));
    1502                throw new ReportedException(crashreport);
    1503            }
    1504
    1505            if (this.currentScreen != null)
    1506            {
    1507                try
    1508                {
    1509                    this.currentScreen.guiParticles.update();
    1510                }
    1511                catch (Throwable throwable1)
    1512                {
    1513                    crashreport = CrashReport.makeCrashReport(throwable1, "Ticking screen particles");
    1514                    crashreportcategory = crashreport.makeCategory("Affected screen");
    1515                    crashreportcategory.addCrashSectionCallable("Screen name", new CallableParticleScreenName(this));
    1516                    throw new ReportedException(crashreport);
    1517                }
    1518
    1519                try
    1520                {
    1521                    this.currentScreen.updateScreen();
    1522                }
    1523                catch (Throwable throwable2)
    1524                {
    1525                    crashreport = CrashReport.makeCrashReport(throwable2, "Ticking screen");
    1526                    crashreportcategory = crashreport.makeCategory("Affected screen");
    1527                    crashreportcategory.addCrashSectionCallable("Screen name", new CallableTickingScreenName(this));
    1528                    throw new ReportedException(crashreport);
    1529                }
    1530            }
    1531        }
    1532
    1533        if (this.currentScreen == null || this.currentScreen.allowUserInput)
    1534        {
    1535            this.mcProfiler.endStartSection("mouse");
    1536
    1537            while (Mouse.next())
    1538            {
    1539                KeyBinding.setKeyBindState(Mouse.getEventButton() - 100, Mouse.getEventButtonState());
    1540
    1541                if (Mouse.getEventButtonState())
    1542                {
    1543                    KeyBinding.onTick(Mouse.getEventButton() - 100);
    1544                }
    1545
    1546                long i = getSystemTime() - this.systemTime;
    1547
    1548                if (i <= 200L)
    1549                {
    1550                    int j = Mouse.getEventDWheel();
    1551
    1552                    if (j != 0)
    1553                    {
    1554                        this.thePlayer.inventory.changeCurrentItem(j);
    1555
    1556                        if (this.gameSettings.noclip)
    1557                        {
    1558                            if (j > 0)
    1559                            {
    1560                                j = 1;
    1561                            }
    1562
    1563                            if (j < 0)
    1564                            {
    1565                                j = -1;
    1566                            }
    1567
    1568                            this.gameSettings.noclipRate += (float)j * 0.25F;
    1569                        }
    1570                    }
    1571
    1572                    if (this.currentScreen == null)
    1573                    {
    1574                        if (!this.inGameHasFocus && Mouse.getEventButtonState())
    1575                        {
    1576                            this.setIngameFocus();
    1577                        }
    1578                    }
    1579                    else if (this.currentScreen != null)
    1580                    {
    1581                        this.currentScreen.handleMouseInput();
    1582                    }
    1583                }
    1584            }
    1585
    1586            if (this.leftClickCounter > 0)
    1587            {
    1588                --this.leftClickCounter;
    1589            }
    1590
    1591            this.mcProfiler.endStartSection("keyboard");
    1592            boolean flag;
    1593
    1594            while (Keyboard.next())
    1595            {
    1596                KeyBinding.setKeyBindState(Keyboard.getEventKey(), Keyboard.getEventKeyState());
    1597
    1598                if (Keyboard.getEventKeyState())
    1599                {
    1600                    KeyBinding.onTick(Keyboard.getEventKey());
    1601                }
    1602
    1603                if (this.field_83002_am > 0L)
    1604                {
    1605                    if (getSystemTime() - this.field_83002_am >= 6000L)
    1606                    {
    1607                        throw new ReportedException(new CrashReport("Manually triggered debug crash", new Throwable()));
    1608                    }
    1609
    1610                    if (!Keyboard.isKeyDown(46) || !Keyboard.isKeyDown(61))
    1611                    {
    1612                        this.field_83002_am = -1L;
    1613                    }
    1614                }
    1615                else if (Keyboard.isKeyDown(46) && Keyboard.isKeyDown(61))
    1616                {
    1617                    this.field_83002_am = getSystemTime();
    1618                }
    1619
    1620                if (Keyboard.getEventKeyState())
    1621                {
    1622                    if (Keyboard.getEventKey() == 87)
    1623                    {
    1624                        this.toggleFullscreen();
    1625                    }
    1626                    else
    1627                    {
    1628                        if (this.currentScreen != null)
    1629                        {
    1630                            this.currentScreen.handleKeyboardInput();
    1631                        }
    1632                        else
    1633                        {
    1634                            if (Keyboard.getEventKey() == 1)
    1635                            {
    1636                                this.displayInGameMenu();
    1637                            }
    1638
    1639                            if (Keyboard.getEventKey() == 31 && Keyboard.isKeyDown(61))
    1640                            {
    1641                                this.forceReload();
    1642                            }
    1643
    1644                            if (Keyboard.getEventKey() == 20 && Keyboard.isKeyDown(61))
    1645                            {
    1646                                this.renderEngine.refreshTextures();
    1647                                this.renderGlobal.loadRenderers();
    1648                            }
    1649
    1650                            if (Keyboard.getEventKey() == 33 && Keyboard.isKeyDown(61))
    1651                            {
    1652                                flag = Keyboard.isKeyDown(42) | Keyboard.isKeyDown(54);
    1653                                this.gameSettings.setOptionValue(EnumOptions.RENDER_DISTANCE, flag ? -1 : 1);
    1654                            }
    1655
    1656                            if (Keyboard.getEventKey() == 30 && Keyboard.isKeyDown(61))
    1657                            {
    1658                                this.renderGlobal.loadRenderers();
    1659                            }
    1660
    1661                            if (Keyboard.getEventKey() == 35 && Keyboard.isKeyDown(61))
    1662                            {
    1663                                this.gameSettings.advancedItemTooltips = !this.gameSettings.advancedItemTooltips;
    1664                                this.gameSettings.saveOptions();
    1665                            }
    1666
    1667                            if (Keyboard.getEventKey() == 48 && Keyboard.isKeyDown(61))
    1668                            {
    1669                                RenderManager.field_85095_o = !RenderManager.field_85095_o;
    1670                            }
    1671
    1672                            if (Keyboard.getEventKey() == 25 && Keyboard.isKeyDown(61))
    1673                            {
    1674                                this.gameSettings.pauseOnLostFocus = !this.gameSettings.pauseOnLostFocus;
    1675                                this.gameSettings.saveOptions();
    1676                            }
    1677
    1678                            if (Keyboard.getEventKey() == 59)
    1679                            {
    1680                                this.gameSettings.hideGUI = !this.gameSettings.hideGUI;
    1681                            }
    1682
    1683                            if (Keyboard.getEventKey() == 61)
    1684                            {
    1685                                this.gameSettings.showDebugInfo = !this.gameSettings.showDebugInfo;
    1686                                this.gameSettings.showDebugProfilerChart = GuiScreen.isShiftKeyDown();
    1687                            }
    1688
    1689                            if (Keyboard.getEventKey() == 63)
    1690                            {
    1691                                ++this.gameSettings.thirdPersonView;
    1692
    1693                                if (this.gameSettings.thirdPersonView > 2)
    1694                                {
    1695                                    this.gameSettings.thirdPersonView = 0;
    1696                                }
    1697                            }
    1698
    1699                            if (Keyboard.getEventKey() == 66)
    1700                            {
    1701                                this.gameSettings.smoothCamera = !this.gameSettings.smoothCamera;
    1702                            }
    1703                        }
    1704
    1705                        int k;
    1706
    1707                        for (k = 0; k < 9; ++k)
    1708                        {
    1709                            if (Keyboard.getEventKey() == 2 + k)
    1710                            {
    1711                                this.thePlayer.inventory.currentItem = k;
    1712                            }
    1713                        }
    1714
    1715                        if (this.gameSettings.showDebugInfo && this.gameSettings.showDebugProfilerChart)
    1716                        {
    1717                            if (Keyboard.getEventKey() == 11)
    1718                            {
    1719                                this.updateDebugProfilerName(0);
    1720                            }
    1721
    1722                            for (k = 0; k < 9; ++k)
    1723                            {
    1724                                if (Keyboard.getEventKey() == 2 + k)
    1725                                {
    1726                                    this.updateDebugProfilerName(k + 1);
    1727                                }
    1728                            }
    1729                        }
    1730                    }
    1731                }
    1732            }
    1733
    1734            flag = this.gameSettings.chatVisibility != 2;
    1735
    1736            while (this.gameSettings.keyBindInventory.isPressed())
    1737            {
    1738                this.displayGuiScreen(new GuiInventory(this.thePlayer));
    1739            }
    1740
    1741            while (this.gameSettings.keyBindDrop.isPressed())
    1742            {
    1743                this.thePlayer.dropOneItem(GuiScreen.isCtrlKeyDown());
    1744            }
    1745
    1746            while (this.gameSettings.keyBindChat.isPressed() && flag)
    1747            {
    1748                this.displayGuiScreen(new GuiChat());
    1749            }
    1750
    1751            if (this.currentScreen == null && this.gameSettings.keyBindCommand.isPressed() && flag)
    1752            {
    1753                this.displayGuiScreen(new GuiChat("/"));
    1754            }
    1755
    1756            if (this.thePlayer.isUsingItem())
    1757            {
    1758                if (!this.gameSettings.keyBindUseItem.pressed)
    1759                {
    1760                    this.playerController.onStoppedUsingItem(this.thePlayer);
    1761                }
    1762
    1763                label379:
    1764
    1765                while (true)
    1766                {
    1767                    if (!this.gameSettings.keyBindAttack.isPressed())
    1768                    {
    1769                        while (this.gameSettings.keyBindUseItem.isPressed())
    1770                        {
    1771                            ;
    1772                        }
    1773
    1774                        while (true)
    1775                        {
    1776                            if (this.gameSettings.keyBindPickBlock.isPressed())
    1777                            {
    1778                                continue;
    1779                            }
    1780
    1781                            break label379;
    1782                        }
    1783                    }
    1784                }
    1785            }
    1786            else
    1787            {
    1788                while (this.gameSettings.keyBindAttack.isPressed())
    1789                {
    1790                    this.clickMouse(0);
    1791                }
    1792
    1793                while (this.gameSettings.keyBindUseItem.isPressed())
    1794                {
    1795                    this.clickMouse(1);
    1796                }
    1797
    1798                while (this.gameSettings.keyBindPickBlock.isPressed())
    1799                {
    1800                    this.clickMiddleMouseButton();
    1801                }
    1802            }
    1803
    1804            if (this.gameSettings.keyBindUseItem.pressed && this.rightClickDelayTimer == 0 && !this.thePlayer.isUsingItem())
    1805            {
    1806                this.clickMouse(1);
    1807            }
    1808
    1809            this.sendClickBlockToController(0, this.currentScreen == null && this.gameSettings.keyBindAttack.pressed && this.inGameHasFocus);
    1810        }
    1811
    1812        if (this.theWorld != null)
    1813        {
    1814            if (this.thePlayer != null)
    1815            {
    1816                ++this.joinPlayerCounter;
    1817
    1818                if (this.joinPlayerCounter == 30)
    1819                {
    1820                    this.joinPlayerCounter = 0;
    1821                    this.theWorld.joinEntityInSurroundings(this.thePlayer);
    1822                }
    1823            }
    1824
    1825            this.mcProfiler.endStartSection("gameRenderer");
    1826
    1827            if (!this.isGamePaused)
    1828            {
    1829                this.entityRenderer.updateRenderer();
    1830            }
    1831
    1832            this.mcProfiler.endStartSection("levelRenderer");
    1833
    1834            if (!this.isGamePaused)
    1835            {
    1836                this.renderGlobal.updateClouds();
    1837            }
    1838
    1839            this.mcProfiler.endStartSection("level");
    1840
    1841            if (!this.isGamePaused)
    1842            {
    1843                if (this.theWorld.lastLightningBolt > 0)
    1844                {
    1845                    --this.theWorld.lastLightningBolt;
    1846                }
    1847
    1848                this.theWorld.updateEntities();
    1849            }
    1850
    1851            if (!this.isGamePaused)
    1852            {
    1853                this.theWorld.setAllowedSpawnTypes(this.theWorld.difficultySetting > 0, true);
    1854
    1855                try
    1856                {
    1857                    this.theWorld.tick();
    1858                }
    1859                catch (Throwable throwable3)
    1860                {
    1861                    crashreport = CrashReport.makeCrashReport(throwable3, "Exception in world tick");
    1862
    1863                    if (this.theWorld == null)
    1864                    {
    1865                        crashreportcategory = crashreport.makeCategory("Affected level");
    1866                        crashreportcategory.addCrashSection("Problem", "Level is null!");
    1867                    }
    1868                    else
    1869                    {
    1870                        this.theWorld.addWorldInfoToCrashReport(crashreport);
    1871                    }
    1872
    1873                    throw new ReportedException(crashreport);
    1874                }
    1875            }
    1876
    1877            this.mcProfiler.endStartSection("animateTick");
    1878
    1879            if (!this.isGamePaused && this.theWorld != null)
    1880            {
    1881                this.theWorld.func_73029_E(MathHelper.floor_double(this.thePlayer.posX), MathHelper.floor_double(this.thePlayer.posY), MathHelper.floor_double(this.thePlayer.posZ));
    1882            }
    1883
    1884            this.mcProfiler.endStartSection("particles");
    1885
    1886            if (!this.isGamePaused)
    1887            {
    1888                this.effectRenderer.updateEffects();
    1889            }
    1890        }
    1891        else if (this.myNetworkManager != null)
    1892        {
    1893            this.mcProfiler.endStartSection("pendingConnection");
    1894            this.myNetworkManager.processReadPackets();
    1895        }
    1896
    1897        FMLCommonHandler.instance().onPostClientTick();
    1898
    1899        this.mcProfiler.endSection();
    1900        this.systemTime = getSystemTime();
    1901    }
    1902
    1903    /**
    1904     * Forces a reload of the sound manager and all the resources. Called in game by holding 'F3' and pressing 'S'.
    1905     */
    1906    private void forceReload()
    1907    {
    1908        this.func_98033_al().func_98233_a("FORCING RELOAD!");
    1909
    1910        if (this.sndManager != null)
    1911        {
    1912            this.sndManager.stopAllSounds();
    1913        }
    1914
    1915        this.sndManager = new SoundManager();
    1916        this.sndManager.loadSoundSettings(this.gameSettings);
    1917        this.downloadResourcesThread.reloadResources();
    1918    }
    1919
    1920    /**
    1921     * Arguments: World foldername,  World ingame name, WorldSettings
    1922     */
    1923    public void launchIntegratedServer(String par1Str, String par2Str, WorldSettings par3WorldSettings)
    1924    {
    1925        this.loadWorld((WorldClient)null);
    1926        System.gc();
    1927        ISaveHandler isavehandler = this.saveLoader.getSaveLoader(par1Str, false);
    1928        WorldInfo worldinfo = isavehandler.loadWorldInfo();
    1929
    1930        if (worldinfo == null && par3WorldSettings != null)
    1931        {
    1932            this.statFileWriter.readStat(StatList.createWorldStat, 1);
    1933            worldinfo = new WorldInfo(par3WorldSettings, par1Str);
    1934            isavehandler.saveWorldInfo(worldinfo);
    1935        }
    1936
    1937        if (par3WorldSettings == null)
    1938        {
    1939            par3WorldSettings = new WorldSettings(worldinfo);
    1940        }
    1941
    1942        this.statFileWriter.readStat(StatList.startGameStat, 1);
    1943
    1944        GameData.initializeServerGate(2);
    1945
    1946        this.theIntegratedServer = new IntegratedServer(this, par1Str, par2Str, par3WorldSettings);
    1947        this.theIntegratedServer.startServerThread();
    1948
    1949        MapDifference<Integer, ItemData> idDifferences = GameData.gateWorldLoadingForValidation();
    1950        if (idDifferences!=null)
    1951        {
    1952            FMLClientHandler.instance().warnIDMismatch(idDifferences, true);
    1953        }
    1954        else
    1955        {
    1956            GameData.releaseGate(true);
    1957            continueWorldLoading();
    1958        }
    1959
    1960    }
    1961
    1962    public void continueWorldLoading()
    1963    {
    1964        this.integratedServerIsRunning = true;
    1965        this.loadingScreen.displayProgressMessage(StatCollector.translateToLocal("menu.loadingLevel"));
    1966
    1967        while (!this.theIntegratedServer.serverIsInRunLoop())
    1968        {
    1969            String s2 = this.theIntegratedServer.getUserMessage();
    1970
    1971            if (s2 != null)
    1972            {
    1973                this.loadingScreen.resetProgresAndWorkingMessage(StatCollector.translateToLocal(s2));
    1974            }
    1975            else
    1976            {
    1977                this.loadingScreen.resetProgresAndWorkingMessage("");
    1978            }
    1979
    1980            try
    1981            {
    1982                Thread.sleep(200L);
    1983            }
    1984            catch (InterruptedException interruptedexception)
    1985            {
    1986                ;
    1987            }
    1988        }
    1989
    1990        this.displayGuiScreen((GuiScreen)null);
    1991
    1992        try
    1993        {
    1994            NetClientHandler netclienthandler = new NetClientHandler(this, this.theIntegratedServer);
    1995            this.myNetworkManager = netclienthandler.getNetManager();
    1996        }
    1997        catch (IOException ioexception)
    1998        {
    1999            this.displayCrashReport(this.addGraphicsAndWorldToCrashReport(new CrashReport("Connecting to integrated server", ioexception)));
    2000        }
    2001    }
    2002
    2003    /**
    2004     * unloads the current world first
    2005     */
    2006    public void loadWorld(WorldClient par1WorldClient)
    2007    {
    2008        this.loadWorld(par1WorldClient, "");
    2009    }
    2010
    2011    /**
    2012     * par2Str is displayed on the loading screen to the user unloads the current world first
    2013     */
    2014    public void loadWorld(WorldClient par1WorldClient, String par2Str)
    2015    {
    2016        this.statFileWriter.syncStats();
    2017
    2018        if (par1WorldClient == null)
    2019        {
    2020            NetClientHandler netclienthandler = this.getNetHandler();
    2021
    2022            if (netclienthandler != null)
    2023            {
    2024                netclienthandler.cleanup();
    2025            }
    2026
    2027            if (this.myNetworkManager != null)
    2028            {
    2029                this.myNetworkManager.closeConnections();
    2030            }
    2031
    2032            if (this.theIntegratedServer != null)
    2033            {
    2034                this.theIntegratedServer.initiateShutdown();
    2035                if (loadingScreen!=null)
    2036                {
    2037                    this.loadingScreen.resetProgresAndWorkingMessage("Shutting down internal server...");
    2038                }
    2039                while (!theIntegratedServer.isServerStopped())
    2040                {
    2041                    try
    2042                    {
    2043                        Thread.sleep(10);
    2044                    }
    2045                    catch (InterruptedException ie) {}
    2046                }
    2047            }
    2048
    2049            this.theIntegratedServer = null;
    2050        }
    2051
    2052        this.renderViewEntity = null;
    2053        this.myNetworkManager = null;
    2054
    2055        if (this.loadingScreen != null)
    2056        {
    2057            this.loadingScreen.resetProgressAndMessage(par2Str);
    2058            this.loadingScreen.resetProgresAndWorkingMessage("");
    2059        }
    2060
    2061        if (par1WorldClient == null && this.theWorld != null)
    2062        {
    2063            if (this.texturePackList.getIsDownloading())
    2064            {
    2065                this.texturePackList.onDownloadFinished();
    2066            }
    2067
    2068            this.setServerData((ServerData)null);
    2069            this.integratedServerIsRunning = false;
    2070        }
    2071
    2072        this.sndManager.playStreaming((String)null, 0.0F, 0.0F, 0.0F);
    2073        this.sndManager.stopAllSounds();
    2074        this.theWorld = par1WorldClient;
    2075
    2076        if (par1WorldClient != null)
    2077        {
    2078            if (this.renderGlobal != null)
    2079            {
    2080                this.renderGlobal.setWorldAndLoadRenderers(par1WorldClient);
    2081            }
    2082
    2083            if (this.effectRenderer != null)
    2084            {
    2085                this.effectRenderer.clearEffects(par1WorldClient);
    2086            }
    2087
    2088            if (this.thePlayer == null)
    2089            {
    2090                this.thePlayer = this.playerController.func_78754_a(par1WorldClient);
    2091                this.playerController.flipPlayer(this.thePlayer);
    2092            }
    2093
    2094            this.thePlayer.preparePlayerToSpawn();
    2095            par1WorldClient.spawnEntityInWorld(this.thePlayer);
    2096            this.thePlayer.movementInput = new MovementInputFromOptions(this.gameSettings);
    2097            this.playerController.setPlayerCapabilities(this.thePlayer);
    2098            this.renderViewEntity = this.thePlayer;
    2099        }
    2100        else
    2101        {
    2102            this.saveLoader.flushCache();
    2103            this.thePlayer = null;
    2104        }
    2105
    2106        System.gc();
    2107        this.systemTime = 0L;
    2108    }
    2109
    2110    /**
    2111     * Installs a resource. Currently only sounds are download so this method just adds them to the SoundManager.
    2112     */
    2113    public void installResource(String par1Str, File par2File)
    2114    {
    2115        int i = par1Str.indexOf("/");
    2116        String s1 = par1Str.substring(0, i);
    2117        par1Str = par1Str.substring(i + 1);
    2118
    2119        if (s1.equalsIgnoreCase("sound3"))
    2120        {
    2121            this.sndManager.addSound(par1Str, par2File);
    2122        }
    2123        else if (s1.equalsIgnoreCase("streaming"))
    2124        {
    2125            this.sndManager.addStreaming(par1Str, par2File);
    2126        }
    2127        else if (!s1.equalsIgnoreCase("music") && !s1.equalsIgnoreCase("newmusic"))
    2128        {
    2129            if (s1.equalsIgnoreCase("lang"))
    2130            {
    2131                StringTranslate.getInstance().func_94519_a(par1Str, par2File);
    2132            }
    2133        }
    2134        else
    2135        {
    2136            this.sndManager.addMusic(par1Str, par2File);
    2137        }
    2138    }
    2139
    2140    /**
    2141     * A String of renderGlobal.getDebugInfoRenders
    2142     */
    2143    public String debugInfoRenders()
    2144    {
    2145        return this.renderGlobal.getDebugInfoRenders();
    2146    }
    2147
    2148    /**
    2149     * Gets the information in the F3 menu about how many entities are infront/around you
    2150     */
    2151    public String getEntityDebug()
    2152    {
    2153        return this.renderGlobal.getDebugInfoEntities();
    2154    }
    2155
    2156    /**
    2157     * Gets the name of the world's current chunk provider
    2158     */
    2159    public String getWorldProviderName()
    2160    {
    2161        return this.theWorld.getProviderName();
    2162    }
    2163
    2164    /**
    2165     * A String of how many entities are in the world
    2166     */
    2167    public String debugInfoEntities()
    2168    {
    2169        return "P: " + this.effectRenderer.getStatistics() + ". T: " + this.theWorld.getDebugLoadedEntities();
    2170    }
    2171
    2172    public void setDimensionAndSpawnPlayer(int par1)
    2173    {
    2174        this.theWorld.setSpawnLocation();
    2175        this.theWorld.removeAllEntities();
    2176        int j = 0;
    2177
    2178        if (this.thePlayer != null)
    2179        {
    2180            j = this.thePlayer.entityId;
    2181            this.theWorld.removeEntity(this.thePlayer);
    2182        }
    2183
    2184        this.renderViewEntity = null;
    2185        this.thePlayer = this.playerController.func_78754_a(this.theWorld);
    2186        this.thePlayer.dimension = par1;
    2187        this.renderViewEntity = this.thePlayer;
    2188        this.thePlayer.preparePlayerToSpawn();
    2189        this.theWorld.spawnEntityInWorld(this.thePlayer);
    2190        this.playerController.flipPlayer(this.thePlayer);
    2191        this.thePlayer.movementInput = new MovementInputFromOptions(this.gameSettings);
    2192        this.thePlayer.entityId = j;
    2193        this.playerController.setPlayerCapabilities(this.thePlayer);
    2194
    2195        if (this.currentScreen instanceof GuiGameOver)
    2196        {
    2197            this.displayGuiScreen((GuiScreen)null);
    2198        }
    2199    }
    2200
    2201    /**
    2202     * Sets whether this is a demo or not.
    2203     */
    2204    void setDemo(boolean par1)
    2205    {
    2206        this.isDemo = par1;
    2207    }
    2208
    2209    /**
    2210     * Gets whether this is a demo or not.
    2211     */
    2212    public final boolean isDemo()
    2213    {
    2214        return this.isDemo;
    2215    }
    2216
    2217    /**
    2218     * Returns the NetClientHandler.
    2219     */
    2220    public NetClientHandler getNetHandler()
    2221    {
    2222        return this.thePlayer != null ? this.thePlayer.sendQueue : null;
    2223    }
    2224
    2225    public static void main(String[] par0ArrayOfStr)
    2226    {
    2227        FMLRelauncher.handleClientRelaunch(new ArgsWrapper(par0ArrayOfStr));
    2228    }
    2229
    2230    public static void fmlReentry(ArgsWrapper wrapper)
    2231    {
    2232        String[] par0ArrayOfStr = wrapper.args;
    2233        HashMap hashmap = new HashMap();
    2234        boolean flag = false;
    2235        boolean flag1 = true;
    2236        boolean flag2 = false;
    2237        String s = "Player" + getSystemTime() % 1000L;
    2238        String s1 = s;
    2239
    2240        if (par0ArrayOfStr.length > 0)
    2241        {
    2242            s1 = par0ArrayOfStr[0];
    2243        }
    2244
    2245        String s2 = "-";
    2246
    2247        if (par0ArrayOfStr.length > 1)
    2248        {
    2249            s2 = par0ArrayOfStr[1];
    2250        }
    2251
    2252        ArrayList arraylist = new ArrayList();
    2253
    2254        for (int i = 2; i < par0ArrayOfStr.length; ++i)
    2255        {
    2256            String s3 = par0ArrayOfStr[i];
    2257            String s4 = i == par0ArrayOfStr.length - 1 ? null : par0ArrayOfStr[i + 1];
    2258            boolean flag3 = false;
    2259
    2260            if (!s3.equals("-demo") && !s3.equals("--demo"))
    2261            {
    2262                if (s3.equals("--applet"))
    2263                {
    2264                    flag1 = false;
    2265                }
    2266                else if (s3.equals("--password") && s4 != null)
    2267                {
    2268                    String[] astring1 = HttpUtil.loginToMinecraft((ILogAgent)null, s1, s4);
    2269
    2270                    if (astring1 != null)
    2271                    {
    2272                        s1 = astring1[0];
    2273                        s2 = astring1[1];
    2274                        arraylist.add("Logged in insecurely as " + s1);
    2275                    }
    2276                    else
    2277                    {
    2278                        arraylist.add("Could not log in as " + s1 + " with given password");
    2279                    }
    2280
    2281                    flag3 = true;
    2282                }
    2283            }
    2284            else
    2285            {
    2286                flag = true;
    2287            }
    2288
    2289            if (flag3)
    2290            {
    2291                ++i;
    2292            }
    2293        }
    2294
    2295        if (s1.contains("@") && s2.length() <= 1)
    2296        {
    2297            s1 = s;
    2298        }
    2299
    2300        hashmap.put("demo", "" + flag);
    2301        hashmap.put("stand-alone", "" + flag1);
    2302        hashmap.put("username", s1);
    2303        hashmap.put("fullscreen", "" + flag2);
    2304        hashmap.put("sessionid", s2);
    2305        Frame frame = new Frame();
    2306        frame.setTitle("Minecraft");
    2307        frame.setBackground(Color.BLACK);
    2308        JPanel jpanel = new JPanel();
    2309        frame.setLayout(new BorderLayout());
    2310        jpanel.setPreferredSize(new Dimension(854, 480));
    2311        frame.add(jpanel, "Center");
    2312        frame.pack();
    2313        frame.setLocationRelativeTo((Component)null);
    2314        frame.setVisible(true);
    2315        frame.addWindowListener(new GameWindowListener());
    2316        MinecraftFakeLauncher minecraftfakelauncher = new MinecraftFakeLauncher(hashmap);
    2317        MinecraftApplet minecraftapplet = new MinecraftApplet();
    2318        minecraftapplet.setStub(minecraftfakelauncher);
    2319        minecraftfakelauncher.setLayout(new BorderLayout());
    2320        minecraftfakelauncher.add(minecraftapplet, "Center");
    2321        minecraftfakelauncher.validate();
    2322        frame.removeAll();
    2323        frame.setLayout(new BorderLayout());
    2324        frame.add(minecraftfakelauncher, "Center");
    2325        frame.validate();
    2326        minecraftapplet.init();
    2327        Iterator iterator = arraylist.iterator();
    2328
    2329        while (iterator.hasNext())
    2330        {
    2331            String s5 = (String)iterator.next();
    2332            getMinecraft().func_98033_al().func_98233_a(s5);
    2333        }
    2334
    2335        minecraftapplet.start();
    2336        Runtime.getRuntime().addShutdownHook(new ThreadShutdown());
    2337    }
    2338
    2339    public static boolean isGuiEnabled()
    2340    {
    2341        return theMinecraft == null || !theMinecraft.gameSettings.hideGUI;
    2342    }
    2343
    2344    public static boolean isFancyGraphicsEnabled()
    2345    {
    2346        return theMinecraft != null && theMinecraft.gameSettings.fancyGraphics;
    2347    }
    2348
    2349    /**
    2350     * Returns if ambient occlusion is enabled
    2351     */
    2352    public static boolean isAmbientOcclusionEnabled()
    2353    {
    2354        return theMinecraft != null && theMinecraft.gameSettings.ambientOcclusion != 0;
    2355    }
    2356
    2357    /**
    2358     * Returns true if the message is a client command and should not be sent to the server. However there are no such
    2359     * commands at this point in time.
    2360     */
    2361    public boolean handleClientCommand(String par1Str)
    2362    {
    2363        return !par1Str.startsWith("/") ? false : false;
    2364    }
    2365
    2366    /**
    2367     * Called when the middle mouse button gets clicked
    2368     */
    2369    private void clickMiddleMouseButton()
    2370    {
    2371        if (this.objectMouseOver != null)
    2372        {
    2373            boolean flag = this.thePlayer.capabilities.isCreativeMode;
    2374            int k;
    2375
    2376            if (!ForgeHooks.onPickBlock(this.objectMouseOver, this.thePlayer, this.theWorld))
    2377            {
    2378                return;
    2379            }
    2380
    2381            if (flag)
    2382            {
    2383                k = this.thePlayer.inventoryContainer.inventorySlots.size() - 9 + this.thePlayer.inventory.currentItem;
    2384                this.playerController.sendSlotPacket(this.thePlayer.inventory.getStackInSlot(this.thePlayer.inventory.currentItem), k);
    2385            }
    2386        }
    2387    }
    2388
    2389    /**
    2390     * adds core server Info (GL version , Texture pack, isModded, type), and the worldInfo to the crash report
    2391     */
    2392    public CrashReport addGraphicsAndWorldToCrashReport(CrashReport par1CrashReport)
    2393    {
    2394        par1CrashReport.func_85056_g().addCrashSectionCallable("LWJGL", new CallableLWJGLVersion(this));
    2395        par1CrashReport.func_85056_g().addCrashSectionCallable("OpenGL", new CallableGLInfo(this));
    2396        par1CrashReport.func_85056_g().addCrashSectionCallable("Is Modded", new CallableModded(this));
    2397        par1CrashReport.func_85056_g().addCrashSectionCallable("Type", new CallableType2(this));
    2398        par1CrashReport.func_85056_g().addCrashSectionCallable("Texture Pack", new CallableTexturePack(this));
    2399        par1CrashReport.func_85056_g().addCrashSectionCallable("Profiler Position", new CallableClientProfiler(this));
    2400        par1CrashReport.func_85056_g().addCrashSectionCallable("Vec3 Pool Size", new CallableClientMemoryStats(this));
    2401
    2402        if (this.theWorld != null)
    2403        {
    2404            this.theWorld.addWorldInfoToCrashReport(par1CrashReport);
    2405        }
    2406
    2407        return par1CrashReport;
    2408    }
    2409
    2410    /**
    2411     * Return the singleton Minecraft instance for the game
    2412     */
    2413    public static Minecraft getMinecraft()
    2414    {
    2415        return theMinecraft;
    2416    }
    2417
    2418    /**
    2419     * Sets refreshTexturePacksScheduled to true, triggering a texture pack refresh next time the while(running) loop is
    2420     * run
    2421     */
    2422    public void scheduleTexturePackRefresh()
    2423    {
    2424        this.refreshTexturePacksScheduled = true;
    2425    }
    2426
    2427    public void addServerStatsToSnooper(PlayerUsageSnooper par1PlayerUsageSnooper)
    2428    {
    2429        par1PlayerUsageSnooper.addData("fps", Integer.valueOf(debugFPS));
    2430        par1PlayerUsageSnooper.addData("texpack_name", this.texturePackList.getSelectedTexturePack().getTexturePackFileName());
    2431        par1PlayerUsageSnooper.addData("vsync_enabled", Boolean.valueOf(this.gameSettings.enableVsync));
    2432        par1PlayerUsageSnooper.addData("display_frequency", Integer.valueOf(Display.getDisplayMode().getFrequency()));
    2433        par1PlayerUsageSnooper.addData("display_type", this.fullscreen ? "fullscreen" : "windowed");
    2434
    2435        if (this.theIntegratedServer != null && this.theIntegratedServer.getPlayerUsageSnooper() != null)
    2436        {
    2437            par1PlayerUsageSnooper.addData("snooper_partner", this.theIntegratedServer.getPlayerUsageSnooper().getUniqueID());
    2438        }
    2439    }
    2440
    2441    public void addServerTypeToSnooper(PlayerUsageSnooper par1PlayerUsageSnooper)
    2442    {
    2443        par1PlayerUsageSnooper.addData("opengl_version", GL11.glGetString(GL11.GL_VERSION));
    2444        par1PlayerUsageSnooper.addData("opengl_vendor", GL11.glGetString(GL11.GL_VENDOR));
    2445        par1PlayerUsageSnooper.addData("client_brand", ClientBrandRetriever.getClientModName());
    2446        par1PlayerUsageSnooper.addData("applet", Boolean.valueOf(this.hideQuitButton));
    2447        ContextCapabilities contextcapabilities = GLContext.getCapabilities();
    2448        par1PlayerUsageSnooper.addData("gl_caps[ARB_multitexture]", Boolean.valueOf(contextcapabilities.GL_ARB_multitexture));
    2449        par1PlayerUsageSnooper.addData("gl_caps[ARB_multisample]", Boolean.valueOf(contextcapabilities.GL_ARB_multisample));
    2450        par1PlayerUsageSnooper.addData("gl_caps[ARB_texture_cube_map]", Boolean.valueOf(contextcapabilities.GL_ARB_texture_cube_map));
    2451        par1PlayerUsageSnooper.addData("gl_caps[ARB_vertex_blend]", Boolean.valueOf(contextcapabilities.GL_ARB_vertex_blend));
    2452        par1PlayerUsageSnooper.addData("gl_caps[ARB_matrix_palette]", Boolean.valueOf(contextcapabilities.GL_ARB_matrix_palette));
    2453        par1PlayerUsageSnooper.addData("gl_caps[ARB_vertex_program]", Boolean.valueOf(contextcapabilities.GL_ARB_vertex_program));
    2454        par1PlayerUsageSnooper.addData("gl_caps[ARB_vertex_shader]", Boolean.valueOf(contextcapabilities.GL_ARB_vertex_shader));
    2455        par1PlayerUsageSnooper.addData("gl_caps[ARB_fragment_program]", Boolean.valueOf(contextcapabilities.GL_ARB_fragment_program));
    2456        par1PlayerUsageSnooper.addData("gl_caps[ARB_fragment_shader]", Boolean.valueOf(contextcapabilities.GL_ARB_fragment_shader));
    2457        par1PlayerUsageSnooper.addData("gl_caps[ARB_shader_objects]", Boolean.valueOf(contextcapabilities.GL_ARB_shader_objects));
    2458        par1PlayerUsageSnooper.addData("gl_caps[ARB_vertex_buffer_object]", Boolean.valueOf(contextcapabilities.GL_ARB_vertex_buffer_object));
    2459        par1PlayerUsageSnooper.addData("gl_caps[ARB_framebuffer_object]", Boolean.valueOf(contextcapabilities.GL_ARB_framebuffer_object));
    2460        par1PlayerUsageSnooper.addData("gl_caps[ARB_pixel_buffer_object]", Boolean.valueOf(contextcapabilities.GL_ARB_pixel_buffer_object));
    2461        par1PlayerUsageSnooper.addData("gl_caps[ARB_uniform_buffer_object]", Boolean.valueOf(contextcapabilities.GL_ARB_uniform_buffer_object));
    2462        par1PlayerUsageSnooper.addData("gl_caps[ARB_texture_non_power_of_two]", Boolean.valueOf(contextcapabilities.GL_ARB_texture_non_power_of_two));
    2463        par1PlayerUsageSnooper.addData("gl_caps[gl_max_vertex_uniforms]", Integer.valueOf(GL11.glGetInteger(GL20.GL_MAX_VERTEX_UNIFORM_COMPONENTS)));
    2464        par1PlayerUsageSnooper.addData("gl_caps[gl_max_fragment_uniforms]", Integer.valueOf(GL11.glGetInteger(GL20.GL_MAX_FRAGMENT_UNIFORM_COMPONENTS)));
    2465        par1PlayerUsageSnooper.addData("gl_max_texture_size", Integer.valueOf(getGLMaximumTextureSize()));
    2466    }
    2467
    2468    /**
    2469     * Used in the usage snooper.
    2470     */
    2471    public static int getGLMaximumTextureSize()
    2472    {
    2473        for (int i = 16384; i > 0; i >>= 1)
    2474        {
    2475            GL11.glTexImage2D(GL11.GL_PROXY_TEXTURE_2D, 0, GL11.GL_RGBA, i, i, 0, GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE, (ByteBuffer)null);
    2476            int j = GL11.glGetTexLevelParameteri(GL11.GL_PROXY_TEXTURE_2D, 0, GL11.GL_TEXTURE_WIDTH);
    2477
    2478            if (j != 0)
    2479            {
    2480                return i;
    2481            }
    2482        }
    2483
    2484        return -1;
    2485    }
    2486
    2487    /**
    2488     * Returns whether snooping is enabled or not.
    2489     */
    2490    public boolean isSnooperEnabled()
    2491    {
    2492        return this.gameSettings.snooperEnabled;
    2493    }
    2494
    2495    /**
    2496     * Set the current ServerData instance.
    2497     */
    2498    public void setServerData(ServerData par1ServerData)
    2499    {
    2500        this.currentServerData = par1ServerData;
    2501    }
    2502
    2503    /**
    2504     * Get the current ServerData instance.
    2505     */
    2506    public ServerData getServerData()
    2507    {
    2508        return this.currentServerData;
    2509    }
    2510
    2511    public boolean isIntegratedServerRunning()
    2512    {
    2513        return this.integratedServerIsRunning;
    2514    }
    2515
    2516    /**
    2517     * Returns true if there is only one player playing, and the current server is the integrated one.
    2518     */
    2519    public boolean isSingleplayer()
    2520    {
    2521        return this.integratedServerIsRunning && this.theIntegratedServer != null;
    2522    }
    2523
    2524    /**
    2525     * Returns the currently running integrated server
    2526     */
    2527    public IntegratedServer getIntegratedServer()
    2528    {
    2529        return this.theIntegratedServer;
    2530    }
    2531
    2532    public static void stopIntegratedServer()
    2533    {
    2534        if (theMinecraft != null)
    2535        {
    2536            IntegratedServer integratedserver = theMinecraft.getIntegratedServer();
    2537
    2538            if (integratedserver != null)
    2539            {
    2540                integratedserver.stopServer();
    2541            }
    2542        }
    2543    }
    2544
    2545    /**
    2546     * Returns the PlayerUsageSnooper instance.
    2547     */
    2548    public PlayerUsageSnooper getPlayerUsageSnooper()
    2549    {
    2550        return this.usageSnooper;
    2551    }
    2552
    2553    /**
    2554     * Gets the system time in milliseconds.
    2555     */
    2556    public static long getSystemTime()
    2557    {
    2558        return Sys.getTime() * 1000L / Sys.getTimerResolution();
    2559    }
    2560
    2561    /**
    2562     * Returns whether we're in full screen or not.
    2563     */
    2564    public boolean isFullScreen()
    2565    {
    2566        return this.fullscreen;
    2567    }
    2568
    2569    public ILogAgent func_98033_al()
    2570    {
    2571        return this.field_94139_O;
    2572    }
    2573}