/src/main/java/org/spoutcraft/client/SpoutClient.java
Java | 615 lines | 491 code | 85 blank | 39 comment | 96 complexity | e2393055b95d439dfb60a321070a5151 MD5 | raw file
1/*
2 * This file is part of Hysteria-Spoutcraft.
3 *
4 * Copyright (c) 2011 Hysteria Group <http://www.hysteria.us.pn/>
5 * Hysteria-Spoutcraft is licensed under the GNU Lesser General Public License.
6 *
7 * Hysteria-Spoutcraft is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU Lesser General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * Hysteria-Spoutcraft is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 */
20/*
21 * This file is part of Spoutcraft.
22 *
23 * Copyright (c) 2011 Spout LLC <http://www.spout.org/>
24 * Spoutcraft is licensed under the GNU Lesser General Public License.
25 *
26 * Spoutcraft is free software: you can redistribute it and/or modify
27 * it under the terms of the GNU Lesser General Public License as published by
28 * the Free Software Foundation, either version 3 of the License, or
29 * (at your option) any later version.
30 *
31 * Spoutcraft is distributed in the hope that it will be useful,
32 * but WITHOUT ANY WARRANTY; without even the implied warranty of
33 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
34 * GNU Lesser General Public License for more details.
35 *
36 * You should have received a copy of the GNU Lesser General Public License
37 * along with this program. If not, see <http://www.gnu.org/licenses/>.
38 */
39package org.spoutcraft.client;
40
41import java.io.File;
42import java.util.HashMap;
43import java.util.Iterator;
44import java.util.LinkedList;
45import java.util.logging.Logger;
46
47import org.newdawn.slick.util.Log;
48import org.newdawn.slick.util.LogSystem;
49
50import net.minecraft.client.Minecraft;
51import net.minecraft.src.Entity;
52import net.minecraft.src.EntityClientPlayerMP;
53import net.minecraft.src.EntityPlayer;
54import net.minecraft.src.Packet;
55import net.minecraft.src.WorldClient;
56
57import org.spoutcraft.api.Client;
58import org.spoutcraft.api.Spoutcraft;
59import org.spoutcraft.api.gui.Keyboard;
60import org.spoutcraft.api.gui.RenderDelegate;
61import org.spoutcraft.api.gui.WidgetManager;
62import org.spoutcraft.api.inventory.MaterialManager;
63import org.spoutcraft.api.keyboard.KeyBindingManager;
64import org.spoutcraft.api.material.MaterialData;
65import org.spoutcraft.api.player.BiomeManager;
66import org.spoutcraft.api.player.SkyManager;
67import org.spoutcraft.api.property.PropertyObject;
68import org.spoutcraft.client.config.Configuration;
69import org.spoutcraft.client.config.MipMapUtils;
70import org.spoutcraft.client.controls.SimpleKeyBindingManager;
71import org.spoutcraft.client.entity.CraftEntity;
72import org.spoutcraft.client.gui.MCRenderDelegate;
73import org.spoutcraft.client.gui.SimpleKeyManager;
74import org.spoutcraft.client.gui.SimpleWidgetManager;
75import org.spoutcraft.client.gui.minimap.MinimapConfig;
76import org.spoutcraft.client.gui.server.ServerManager;
77import org.spoutcraft.client.gui.texturepacks.TexturePacksDatabaseModel;
78import org.spoutcraft.client.gui.texturepacks.TexturePacksModel;
79import org.spoutcraft.client.inventory.SimpleMaterialManager;
80import org.spoutcraft.client.io.CRCManager;
81import org.spoutcraft.client.io.CustomTextureManager;
82import org.spoutcraft.client.io.FileDownloadThread;
83import org.spoutcraft.client.io.FileUtil;
84import org.spoutcraft.client.packet.CustomPacket;
85import org.spoutcraft.client.packet.PacketEntityInformation;
86import org.spoutcraft.client.packet.PacketManager;
87import org.spoutcraft.client.player.ClientPlayer;
88import org.spoutcraft.client.player.SimpleBiomeManager;
89import org.spoutcraft.client.player.SimpleSkyManager;
90
91public class SpoutClient extends PropertyObject implements Client {
92 private static SpoutClient instance = null;
93 private static final Thread dataMiningThread = new DataMiningThread();
94 private static final String version = "Unknown Version";
95 public static final String spoutcraftVersion = "1.5.2";
96
97 private final SimpleSkyManager skyManager = new SimpleSkyManager();
98 private final PacketManager packetManager = new PacketManager();
99 private final BiomeManager biomeManager = new SimpleBiomeManager();
100 private final MaterialManager materialManager = new SimpleMaterialManager();
101 private final RenderDelegate render = new MCRenderDelegate();
102 private final KeyBindingManager bindingManager = new SimpleKeyBindingManager();
103 private final Logger log = Logger.getLogger(SpoutClient.class.getName());
104 private final ServerManager serverManager = new ServerManager();
105 private long tick = 0;
106 private long inWorldTicks = 0;
107 private Thread clipboardThread = null;
108 private long server = -1L;
109 public ClientPlayer player = null;
110 private boolean cheatsky = false;
111 private boolean forcesky = false;
112 private boolean showsky = true;
113 private boolean cheatclearwater = false;
114 private boolean forceclearwater = false;
115 private boolean showclearwater = true;
116 private boolean cheatstars = false;
117 private boolean forcestars = true;
118 private boolean showstars = true;
119 private boolean cheatweather = false;
120 private boolean forceweather = true;
121 private boolean showweather = true;
122 private boolean time = false;
123 private boolean coords = false;
124 private boolean entitylabel = false;
125 private boolean cheatvoidfog = false;
126 private boolean forcevoidfog = true;
127 private boolean showvoidfog = true;
128 private boolean flySpeed = false;
129 private Mode clientMode = Mode.Menu;
130 private TexturePacksModel textureModel = new TexturePacksModel();
131 private TexturePacksDatabaseModel textureDatabaseModel = new TexturePacksDatabaseModel();
132 private String addonFolder = Minecraft.getMinecraftDir() + File.separator + "addons";
133 private final WidgetManager widgetManager = new SimpleWidgetManager();
134 private final HashMap<String, Boolean> permissions = new HashMap<String, Boolean>();
135 private boolean active = false;
136
137 private SpoutClient() {
138 instance = this;
139 if (!Thread.currentThread().getName().equals("Minecraft main thread")) {
140 throw new SecurityException("Main thread name mismatch");
141 }
142 //System.setSecurityManager(securityManager);
143
144 ((SimpleKeyBindingManager)bindingManager).load();
145 serverManager.init();
146 Log.setVerbose(false);
147 Log.setLogSystem(new SilencedLogSystem());
148 }
149
150 private class SilencedLogSystem implements LogSystem {
151 @Override
152 public void debug(String debug) {}
153 @Override
154 public void error(Throwable t) {}
155 @Override
156 public void error(String error) {}
157 @Override
158 public void error(String error, Throwable t) {}
159 @Override
160 public void info(String info) {}
161 @Override
162 public void warn(String warn) {}
163 @Override
164 public void warn(String warn, Throwable t) {}
165 }
166
167 static {
168 dataMiningThread.start();
169 Packet.addIdClassMapping(195, true, true, CustomPacket.class);
170 Configuration.read();
171 Keyboard.setKeyManager(new SimpleKeyManager());
172 FileUtil.migrateOldFiles();
173 }
174
175 public static SpoutClient getInstance() {
176 if (instance == null) {
177 Spoutcraft.setClient(new SpoutClient());
178 System.out.println("Starting SpoutClient. Available Memory: " + Runtime.getRuntime().maxMemory() / (1024*1024) + " mb");
179 }
180 return instance;
181 }
182
183 public static String getClientVersion() {
184 return version;
185 }
186
187 public static boolean hasAvailableRAM() {
188 return Runtime.getRuntime().maxMemory() > 756L;
189 }
190
191 public long getServerVersion() {
192 return server;
193 }
194
195 public SkyManager getSkyManager() {
196 return skyManager;
197 }
198
199 public PacketManager getPacketManager() {
200 return packetManager;
201 }
202
203 public ClientPlayer getActivePlayer() {
204 return player;
205 }
206
207 public BiomeManager getBiomeManager() {
208 return biomeManager;
209 }
210
211 public MaterialManager getMaterialManager() {
212 return materialManager;
213 }
214
215 public net.minecraft.src.World getRawWorld() {
216 if (getHandle() == null) {
217 return null;
218 }
219 return getHandle().theWorld;
220 }
221
222 public boolean isSkyCheat() {
223 return cheatsky || !getHandle().isMultiplayerWorld() || !isSpoutEnabled();
224 }
225
226 public boolean isForceSky() {
227 return forcesky || !getHandle().isMultiplayerWorld() || !isSpoutEnabled();
228 }
229
230 public boolean isShowSky() {
231 return showsky || !getHandle().isMultiplayerWorld() || !isSpoutEnabled();
232 }
233
234 public boolean isClearWaterCheat() {
235 return cheatclearwater || !getHandle().isMultiplayerWorld() || !isSpoutEnabled();
236 }
237 public boolean isForceClearWater() {
238 return forceclearwater || !getHandle().isMultiplayerWorld() || !isSpoutEnabled();
239 }
240
241 public boolean isShowClearWater() {
242 return showclearwater || !getHandle().isMultiplayerWorld() || !isSpoutEnabled();
243 }
244
245 public boolean isStarsCheat() {
246 return cheatstars || !getHandle().isMultiplayerWorld() || !isSpoutEnabled();
247 }
248
249 public boolean isForceStars() {
250 return forcestars || !getHandle().isMultiplayerWorld() || !isSpoutEnabled();
251 }
252
253 public boolean isShowStars() {
254 return showstars || !getHandle().isMultiplayerWorld() || !isSpoutEnabled();
255 }
256
257 public boolean isWeatherCheat() {
258 return cheatweather || !getHandle().isMultiplayerWorld() || !isSpoutEnabled();
259 }
260
261 public boolean isForceWeather() {
262 return forceweather || !getHandle().isMultiplayerWorld() || !isSpoutEnabled();
263 }
264
265 public boolean isShowWeather() {
266 return showweather || !getHandle().isMultiplayerWorld() || !isSpoutEnabled();
267 }
268
269 public boolean isTimeCheat() {
270 return time || !getHandle().isMultiplayerWorld() || !isSpoutEnabled();
271 }
272
273 public boolean isCoordsCheat() {
274 return coords || !getHandle().isMultiplayerWorld() || !isSpoutEnabled();
275 }
276
277 public boolean isEntityLabelCheat() {
278 return entitylabel || !getHandle().isMultiplayerWorld() || !isSpoutEnabled();
279 }
280
281 public boolean isFlySpeedCheat() {
282 return flySpeed || !getHandle().isMultiplayerWorld() || !isSpoutEnabled();
283 }
284
285 public boolean isVoidFogCheat() {
286 return cheatvoidfog || !getHandle().isMultiplayerWorld() || !isSpoutEnabled();
287 }
288
289 public boolean isForceVoidFog() {
290 return forcevoidfog || !getHandle().isMultiplayerWorld() || !isSpoutEnabled();
291 }
292
293 public boolean isShowVoidFog() {
294 return showvoidfog || !getHandle().isMultiplayerWorld() || !isSpoutEnabled();
295 }
296
297 public void setVisualCheats(boolean tsky, boolean fsky, boolean ssky, boolean tclearwater, boolean fclearwater, boolean sclearwater, boolean tstars, boolean fstars, boolean sstars, boolean tweather, boolean fweather, boolean sweather, boolean ttime, boolean tcoords, boolean tentitylabel, boolean tvoidfog, boolean fvoidfog, boolean svoidfog, boolean tflyspeed) {
298 this.cheatsky = tsky;
299 this.forcesky = fsky;
300 this.showsky = ssky;
301 this.cheatclearwater = tclearwater;
302 this.forceclearwater = fclearwater;
303 this.showclearwater = sclearwater;
304 this.cheatstars = tstars;
305 this.forcestars = fstars;
306 this.showstars = sstars;
307 this.cheatweather = tweather;
308 this.forceweather = fweather;
309 this.showweather = sweather;
310 this.time = ttime;
311 this.coords = tcoords;
312 this.entitylabel = tentitylabel;
313 this.cheatvoidfog = tvoidfog;
314 this.forcevoidfog = fvoidfog;
315 this.showvoidfog = svoidfog;
316 this.flySpeed = tflyspeed;
317
318 if (!isTimeCheat()) {
319 Configuration.setTime(0);
320 }
321
322 if (cheatweather) {
323 Configuration.cheatweather = true;
324 } else {
325 Configuration.cheatweather = false;
326 }
327
328 if (cheatsky) {
329 Configuration.cheatsky = true;
330 } else {
331 Configuration.cheatsky = false;
332 }
333
334 if (cheatstars) {
335 Configuration.cheatstars = true;
336 } else {
337 Configuration.cheatstars = false;
338 }
339
340 if (cheatvoidfog) {
341 Configuration.cheatvoidFog = true;
342 } else {
343 Configuration.cheatvoidFog = false;
344 }
345
346 if (cheatclearwater) {
347 Configuration.cheatclearWater = true;
348 } else {
349 Configuration.cheatclearWater = false;
350 }
351
352 if (isForceWeather()) {
353 if (isShowWeather()) {
354 Configuration.setWeather(true);
355 } else {
356 Configuration.setWeather(false);
357 }
358 }
359
360 if (isForceStars()) {
361 if (isShowStars()) {
362 Configuration.setStars(true);
363 } else {
364 Configuration.setStars(false);
365 }
366 }
367
368 if (isForceSky()) {
369 if (isShowSky()) {
370 Configuration.setSky(true);
371 } else {
372 Configuration.setSky(false);
373 }
374 }
375
376 if (isForceClearWater()) {
377 if (isShowClearWater()) {
378 Configuration.setClearWater(true);
379 } else {
380 Configuration.setClearWater(false);
381 }
382 }
383
384 if (isForceWeather()) {
385 if (isShowWeather()) {
386 Configuration.setWeather(true);
387 } else {
388 Configuration.setWeather(false);
389 }
390 }
391
392 if (isForceVoidFog()) {
393 if (isShowVoidFog()) {
394 Configuration.setVoidFog(true);
395 } else {
396 Configuration.setVoidFog(false);
397 }
398 }
399 }
400
401 public boolean isSpoutEnabled() {
402 return server >= 0;
403 }
404
405 public void setSpoutVersion(long version) {
406 server = version;
407 }
408
409 public boolean isSpoutActive() {
410 return active;
411 }
412
413 public void setSpoutActive(boolean active) {
414 this.active = active;
415 }
416
417 public void onTick() {
418 tick++;
419 Configuration.onTick();
420 getHandle().mcProfiler.startSection("httpdownloads");
421 FileDownloadThread.getInstance().onTick();
422 getHandle().mcProfiler.endStartSection("packet_decompression");
423 PacketDecompressionThread.onTick();
424 getHandle().mcProfiler.endStartSection("widgets");
425 player.getMainScreen().onTick();
426 getHandle().mcProfiler.endStartSection("mipmapping");
427 MipMapUtils.onTick();
428 getHandle().mcProfiler.endStartSection("special_effects");
429 if (Minecraft.theMinecraft.theWorld != null) {
430 Minecraft.theMinecraft.theWorld.doColorfulStuff();
431 inWorldTicks++;
432 }
433 getHandle().mcProfiler.endStartSection("entity_info");
434 if (isSpoutEnabled()) {
435 LinkedList<CraftEntity> processed = new LinkedList<CraftEntity>();
436 Iterator<Entity> i = Entity.toProcess.iterator();
437 while (i.hasNext()) {
438 Entity next = i.next();
439 if (next.spoutEnty != null) {
440 processed.add((CraftEntity) next.spoutEnty);
441 }
442 }
443 Entity.toProcess.clear();
444 if (processed.size() > 0) {
445 getPacketManager().sendSpoutPacket(new PacketEntityInformation(processed));
446 }
447 }
448 getHandle().mcProfiler.endSection();
449 }
450
451 public long getTick() {
452 return tick;
453 }
454
455 public long getInWorldTicks() {
456 return inWorldTicks;
457 }
458
459 public void onWorldExit() {
460 FileUtil.deleteTempDirectory();
461 CustomTextureManager.resetTextures();
462 CRCManager.clear();
463 if (clipboardThread != null) {
464 clipboardThread.interrupt();
465 clipboardThread = null;
466 }
467 Minecraft.theMinecraft.sndManager.stopMusic();
468 PacketDecompressionThread.endThread();
469 MaterialData.reset();
470 FileDownloadThread.preCacheCompleted.lazySet(0);
471 server = -1L;
472 inWorldTicks = 0L;
473 MaterialData.reset();
474 MinimapConfig.getInstance().getServerWaypoints().clear();
475 }
476
477 public void onWorldEnter() {
478 if (player == null) {
479 player = ClientPlayer.getInstance();
480 player.setPlayer(getHandle().thePlayer);
481 getHandle().thePlayer.spoutEnty = player;
482 }
483 if (player.getHandle() instanceof EntityClientPlayerMP && isSpoutEnabled()) {
484 clipboardThread = new ClipboardThread((EntityClientPlayerMP)player.getHandle());
485 clipboardThread.start();
486 } else if (clipboardThread != null) {
487 clipboardThread.interrupt();
488 clipboardThread = null;
489 }
490 PacketDecompressionThread.startThread();
491 MipMapUtils.initializeMipMaps();
492 MipMapUtils.update();
493 player.getMainScreen().toggleSurvivalHUD(!Minecraft.theMinecraft.playerController.isInCreativeMode());
494 inWorldTicks = 0L;
495 MinimapConfig.getInstance().getServerWaypoints().clear();
496 }
497
498 public static Minecraft getHandle() {
499 return Minecraft.theMinecraft;
500 }
501
502 public EntityPlayer getPlayerFromId(int id) {
503 if (getHandle().thePlayer.entityId == id) {
504 return getHandle().thePlayer;
505 }
506 WorldClient world = (WorldClient)getHandle().theWorld;
507 Entity e = world.getEntityByID(id);
508 if (e instanceof EntityPlayer) {
509 return (EntityPlayer) e;
510 }
511 return null;
512 }
513
514 public Entity getEntityFromId(int id) {
515 if (getHandle().thePlayer.entityId == id) {
516 return getHandle().thePlayer;
517 }
518 WorldClient world = (WorldClient)getHandle().theWorld;
519 return world.getEntityByID(id);
520 }
521
522 public Logger getLogger() {
523 return log;
524 }
525
526 public Mode getMode() {
527 return clientMode;
528 }
529
530 public void setMode(Mode clientMode) {
531 this.clientMode = clientMode;
532 }
533
534 public String getName() {
535 return "Spoutcraft";
536 }
537
538 public RenderDelegate getRenderDelegate() {
539 return render;
540 }
541
542 public File getUpdateFolder() {
543 return new File(Minecraft.getMinecraftDir(), "addons" + File.separator + "updates");
544 }
545
546 public String getVersion() {
547 return version;
548 }
549
550 public KeyBindingManager getKeyBindingManager() {
551 return bindingManager;
552 }
553
554 public File getAddonFolder() {
555 return new File(addonFolder);
556 }
557
558 public File getAudioCache() {
559 return getTemporaryCache();
560 }
561
562 public File getTemporaryCache() {
563 return FileUtil.getTempDir();
564 }
565
566 public File getTextureCache() {
567 return getTemporaryCache();
568 }
569
570 public File getTexturePackFolder() {
571 return FileUtil.getTexturePackDir();
572 }
573
574 public File getSelectedTexturePackZip() {
575 return FileUtil.getSelectedTexturePackZip();
576 }
577
578 public File getStatsFolder() {
579 return FileUtil.getStatsDir();
580 }
581
582 public ServerManager getServerManager() {
583 return instance.serverManager;
584 }
585
586 public TexturePacksModel getTexturePacksModel() {
587 return textureModel;
588 }
589
590 public TexturePacksDatabaseModel getTexturePacksDatabaseModel() {
591 return textureDatabaseModel;
592 }
593
594 public WidgetManager getWidgetManager() {
595 return widgetManager;
596 }
597
598 @Override
599 public boolean hasPermission(String node) {
600 Boolean allow = permissions.get(node);
601 if (allow != null) {
602 return allow;
603 } else {
604 return true;
605 }
606 }
607
608 public void setPermission(String node, boolean allow) {
609 permissions.put(node, allow);
610 }
611
612 public void clearPermissions() {
613 permissions.clear();
614 }
615}