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