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