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