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