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