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