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