Thread: Improved cache downloader [md5 checksum]

Page 1 of 2 12 LastLast
Results 1 to 10 of 14
  1. #1 Improved cache downloader [md5 checksum] 
    Registered Member Rememberm3's Avatar
    Join Date
    Aug 2013
    Posts
    1,716
    Thanks given
    56
    Thanks received
    108
    Rep Power
    129
    This is a cache downloader I coded for learning purposes and I thought that maybe you guys wanted to see it.
    This is for all bases.

    This cache downloader updates the new files if you upload them, you don't have to upload a whole new client.

    [How to implement this into the client]
    - First you have to download this folder.
    - Put the folder in your client folder where all the java files are located.

    - Open client.java and look for "public client".
    You should find something like this:
    Code:
    public Client() {
    		LP = 0.0F;
    		alertHandler = new AlertHandler(this);
    		xpAddedPos = expAdded = 0;
    		xpLock = false;
    		xpCounter = 0;
    		clanTitles = new String[500];
    		consoleInput = "";
    		consoleOpen = false;
    		consoleMessages = new String[17];
    		fullscreenInterfaceID = -1;
    		chatRights = new int[500];
    		chatTypeView = 0;
    		clanChatMode = 0;
    		cButtonHPos = -1;
    		cButtonCPos = 0;
    		imageLoader = null;
    		//if (Config.usingLocal) {
    			server = Config.LOCALHOST_IP;
    	//	} else {
    			//server = Config.VPS_IP;
    	//	}
    		anIntArrayArray825 = new int[104][104];
    		friendsNodeIDs = new int[200];
    		groundArray = new NodeList[4][104][104];
    		aBoolean831 = false;
    		aStream_834 = new Buffer(new byte[30000]);
    		npcArray = new Npc[16384];
    		npcIndices = new int[16384];
    		anIntArray840 = new int[1000];
    		aStream_847 = Buffer.create();
    		aBoolean848 = true;
    		openInterfaceID = -1;
    		currentExp = new int[SkillConstants.skillsCount];
    		aBoolean872 = false;
    		anIntArray873 = new int[5];
    		anInt874 = -1;
    		aBooleanArray876 = new boolean[5];
    		drawFlames = false;
    		reportAbuseInput = "";
    		unknownInt10 = -1;
    		menuOpen = false;
    		inputString = "";
    		maxPlayers = 2048;
    		myPlayerIndex = 2047;
    		playerArray = new Player[maxPlayers];
    		playerIndices = new int[maxPlayers];
    		anIntArray894 = new int[maxPlayers];
    		aStreamArray895s = new Buffer[maxPlayers];
    		anInt897 = 1;
    		anIntArrayArray901 = new int[104][104];
    		aByteArray912 = new byte[16384];
    		currentStats = new int[SkillConstants.skillsCount];
    		ignoreListAsLongs = new long[100];
    		loadingError = false;
    		anIntArray928 = new int[5];
    		anIntArrayArray929 = new int[104][104];
    		chatTypes = new int[500];
    		chatNames = new String[500];
    		chatMessages = new String[500];
    		chatButtons = new Sprite[4];
    		sideIcons = new Sprite[15];
    		scrollPart = new Sprite[12];
    		scrollBar = new Sprite[6];
    		aBoolean954 = true;
    		friendsListAsLongs = new long[200];
    		currentSong = -1;
    		drawingFlames = false;
    		spriteDrawX = -1;
    		spriteDrawY = -1;
    		anIntArray968 = new int[33];
    		anIntArray969 = new int[256];
    		decompressors = new Decompressor[5];
    		variousSettings = new int[2000];
    		aBoolean972 = false;
    		anInt975 = 50;
    		anIntArray976 = new int[anInt975];
    		anIntArray977 = new int[anInt975];
    		anIntArray978 = new int[anInt975];
    		anIntArray979 = new int[anInt975];
    		anIntArray980 = new int[anInt975];
    		anIntArray981 = new int[anInt975];
    		anIntArray982 = new int[anInt975];
    		aStringArray983 = new String[anInt975];
    		anInt985 = -1;
    		hitMarks = new Sprite[20];
    		hitMark = new Sprite[20];
    		hitIcon = new Sprite[20];
    		hitMarks562 = new Sprite[4];
    		anIntArray990 = new int[5];
    		aBoolean994 = false;
    		amountOrNameInput = "";
    		aClass19_1013 = new NodeList();
    		aBoolean1017 = false;
    		anInt1018 = -1;
    		anIntArray1030 = new int[5];
    		aBoolean1031 = false;
    		mapFunctions = new Sprite[100];
    		dialogID = -1;
    		maxStats = new int[SkillConstants.skillsCount];
    		anIntArray1045 = new int[2000];
    		aBoolean1047 = true;
    		anIntArray1052 = new int[152];
    		anIntArray1229 = new int[152];
    		anInt1054 = -1;
    		aClass19_1056 = new NodeList();
    		anIntArray1057 = new int[33];
    		aClass9_1059 = new RSInterface();
    		mapScenes = new Background[100];
    		anIntArray1065 = new int[7];
    		anIntArray1072 = new int[1000];
    		anIntArray1073 = new int[1000];
    		aBoolean1080 = false;
    		friendsList = new String[200];
    		inStream = Buffer.create();
    		expectedCRCs = new int[9];
    		menuActionCmd2 = new int[500];
    		menuActionCmd3 = new int[500];
    		menuActionID = new int[500];
    		menuActionCmd1 = new int[500];
    		headIcons = new Sprite[20];
    		skullIcons = new Sprite[20];
    		headIconsHint = new Sprite[20];
    		tabAreaAltered = false;
    		aString1121 = "";
    		atPlayerActions = new String[5];
    		atPlayerArray = new boolean[5];
    		anIntArrayArrayArray1129 = new int[4][13][13];
    		anInt1132 = 2;
    		aClass30_Sub2_Sub1_Sub1Array1140 = new Sprite[1000];
    		aBoolean1141 = false;
    		aBoolean1149 = false;
    		crosses = new Sprite[8];
    		musicEnabled = true;
    		loggedIn = false;
    		canMute = false;
    		aBoolean1159 = false;
    		aBoolean1160 = false;
    		anInt1171 = 1;
    		myUsername = "";
    		myPassword = "";
    		genericLoadingError = false;
    		reportAbuseInterfaceID = -1;
    		aClass19_1179 = new NodeList();
    		anInt1184 = 128;
    		invOverlayInterfaceID = -1;
    		buffer = Buffer.create();
    		menuActionName = new String[500];
    		anIntArray1203 = new int[5];
    		anIntArray1207 = new int[50];
    		anInt1210 = 2;
    		anInt1211 = 78;
    		promptInput = "";
    		modIcons = new Sprite[10];
    		newModIcons = new Sprite[1];
    		tabID = 3;
    		inputTaken = false;
    		songChanging = true;
    		aClass11Array1230 = new CollisionMap[4];
    		anIntArray1240 = new int[100];
    		anIntArray1241 = new int[50];
    		aBoolean1242 = false;
    		anIntArray1250 = new int[50];
    		rsAlreadyLoaded = false;
    		welcomeScreenRaised = false;
    		messagePromptRaised = false;
    		loginMessage1 = "";
    		loginMessage2 = "Welcome to Mistex!";
    		backDialogID = -1;
    		anInt1279 = 2;
    		bigX = new int[4000];
    		bigY = new int[4000];
    		anInt1289 = -1;
    	}
    - Add
    Code:
    		Status.setClient(this);
    before the last "}", like this:
    Code:
    public Client() {
    		LP = 0.0F;
    		alertHandler = new AlertHandler(this);
    		xpAddedPos = expAdded = 0;
    		xpLock = false;
    		xpCounter = 0;
    		clanTitles = new String[500];
    		consoleInput = "";
    		consoleOpen = false;
    		consoleMessages = new String[17];
    		fullscreenInterfaceID = -1;
    		chatRights = new int[500];
    		chatTypeView = 0;
    		clanChatMode = 0;
    		cButtonHPos = -1;
    		cButtonCPos = 0;
    		imageLoader = null;
    		//if (Config.usingLocal) {
    			server = Config.LOCALHOST_IP;
    	//	} else {
    			//server = Config.VPS_IP;
    	//	}
    		anIntArrayArray825 = new int[104][104];
    		friendsNodeIDs = new int[200];
    		groundArray = new NodeList[4][104][104];
    		aBoolean831 = false;
    		aStream_834 = new Buffer(new byte[30000]);
    		npcArray = new Npc[16384];
    		npcIndices = new int[16384];
    		anIntArray840 = new int[1000];
    		aStream_847 = Buffer.create();
    		aBoolean848 = true;
    		openInterfaceID = -1;
    		currentExp = new int[SkillConstants.skillsCount];
    		aBoolean872 = false;
    		anIntArray873 = new int[5];
    		anInt874 = -1;
    		aBooleanArray876 = new boolean[5];
    		drawFlames = false;
    		reportAbuseInput = "";
    		unknownInt10 = -1;
    		menuOpen = false;
    		inputString = "";
    		maxPlayers = 2048;
    		myPlayerIndex = 2047;
    		playerArray = new Player[maxPlayers];
    		playerIndices = new int[maxPlayers];
    		anIntArray894 = new int[maxPlayers];
    		aStreamArray895s = new Buffer[maxPlayers];
    		anInt897 = 1;
    		anIntArrayArray901 = new int[104][104];
    		aByteArray912 = new byte[16384];
    		currentStats = new int[SkillConstants.skillsCount];
    		ignoreListAsLongs = new long[100];
    		loadingError = false;
    		anIntArray928 = new int[5];
    		anIntArrayArray929 = new int[104][104];
    		chatTypes = new int[500];
    		chatNames = new String[500];
    		chatMessages = new String[500];
    		chatButtons = new Sprite[4];
    		sideIcons = new Sprite[15];
    		scrollPart = new Sprite[12];
    		scrollBar = new Sprite[6];
    		aBoolean954 = true;
    		friendsListAsLongs = new long[200];
    		currentSong = -1;
    		drawingFlames = false;
    		spriteDrawX = -1;
    		spriteDrawY = -1;
    		anIntArray968 = new int[33];
    		anIntArray969 = new int[256];
    		decompressors = new Decompressor[5];
    		variousSettings = new int[2000];
    		aBoolean972 = false;
    		anInt975 = 50;
    		anIntArray976 = new int[anInt975];
    		anIntArray977 = new int[anInt975];
    		anIntArray978 = new int[anInt975];
    		anIntArray979 = new int[anInt975];
    		anIntArray980 = new int[anInt975];
    		anIntArray981 = new int[anInt975];
    		anIntArray982 = new int[anInt975];
    		aStringArray983 = new String[anInt975];
    		anInt985 = -1;
    		hitMarks = new Sprite[20];
    		hitMark = new Sprite[20];
    		hitIcon = new Sprite[20];
    		hitMarks562 = new Sprite[4];
    		anIntArray990 = new int[5];
    		aBoolean994 = false;
    		amountOrNameInput = "";
    		aClass19_1013 = new NodeList();
    		aBoolean1017 = false;
    		anInt1018 = -1;
    		anIntArray1030 = new int[5];
    		aBoolean1031 = false;
    		mapFunctions = new Sprite[100];
    		dialogID = -1;
    		maxStats = new int[SkillConstants.skillsCount];
    		anIntArray1045 = new int[2000];
    		aBoolean1047 = true;
    		anIntArray1052 = new int[152];
    		anIntArray1229 = new int[152];
    		anInt1054 = -1;
    		aClass19_1056 = new NodeList();
    		anIntArray1057 = new int[33];
    		aClass9_1059 = new RSInterface();
    		mapScenes = new Background[100];
    		anIntArray1065 = new int[7];
    		anIntArray1072 = new int[1000];
    		anIntArray1073 = new int[1000];
    		aBoolean1080 = false;
    		friendsList = new String[200];
    		inStream = Buffer.create();
    		expectedCRCs = new int[9];
    		menuActionCmd2 = new int[500];
    		menuActionCmd3 = new int[500];
    		menuActionID = new int[500];
    		menuActionCmd1 = new int[500];
    		headIcons = new Sprite[20];
    		skullIcons = new Sprite[20];
    		headIconsHint = new Sprite[20];
    		tabAreaAltered = false;
    		aString1121 = "";
    		atPlayerActions = new String[5];
    		atPlayerArray = new boolean[5];
    		anIntArrayArrayArray1129 = new int[4][13][13];
    		anInt1132 = 2;
    		aClass30_Sub2_Sub1_Sub1Array1140 = new Sprite[1000];
    		aBoolean1141 = false;
    		aBoolean1149 = false;
    		crosses = new Sprite[8];
    		musicEnabled = true;
    		loggedIn = false;
    		canMute = false;
    		aBoolean1159 = false;
    		aBoolean1160 = false;
    		anInt1171 = 1;
    		myUsername = "";
    		myPassword = "";
    		genericLoadingError = false;
    		reportAbuseInterfaceID = -1;
    		aClass19_1179 = new NodeList();
    		anInt1184 = 128;
    		invOverlayInterfaceID = -1;
    		buffer = Buffer.create();
    		menuActionName = new String[500];
    		anIntArray1203 = new int[5];
    		anIntArray1207 = new int[50];
    		anInt1210 = 2;
    		anInt1211 = 78;
    		promptInput = "";
    		modIcons = new Sprite[10];
    		newModIcons = new Sprite[1];
    		tabID = 3;
    		inputTaken = false;
    		songChanging = true;
    		aClass11Array1230 = new CollisionMap[4];
    		anIntArray1240 = new int[100];
    		anIntArray1241 = new int[50];
    		aBoolean1242 = false;
    		anIntArray1250 = new int[50];
    		rsAlreadyLoaded = false;
    		welcomeScreenRaised = false;
    		messagePromptRaised = false;
    		loginMessage1 = "";
    		loginMessage2 = "Welcome to Mistex!";
    		backDialogID = -1;
    		anInt1279 = 2;
    		bigX = new int[4000];
    		bigY = new int[4000];
    		anInt1289 = -1;
    		Status.setClient(this);
    	}
    - Look for "startup()". You should find someting like this:
    Code:
    void startUp() {
    		drawSmoothLoadingText(20, "Starting up");
    		loginRenderer = new LoginRenderer(this);
    		Config.determineClient();
    		for (int index = 0; index < 25; index++) {
    			bubbles.add(new Bubble());
    		}
    
    
    		if (Signlink.sunjava)
    			super.minDelay = 5;
    		if (Signlink.cache_dat != null) {
    			for (int i = 0; i < 5; i++)
    				decompressors[i] = new Decompressor(Signlink.cache_dat, Signlink.cache_idx[i], i + 1);
    		}
    		try {
    			titleStreamLoader = streamLoaderForName(1, "title screen", "title", expectedCRCs[1], 25);
    			smallText = new TextDrawingArea(false, "p11_full", titleStreamLoader);
    			smallHit = new TextDrawingArea(false, "hit_full", titleStreamLoader);
    			bigHit = new TextDrawingArea(true, "critical_full", titleStreamLoader);
    			aTextDrawingArea_1271 = new TextDrawingArea(false, "p12_full", titleStreamLoader);
    			fancyFont = new TextDrawingArea(false, "q8_full", titleStreamLoader);
    			chatTextDrawingArea = new TextDrawingArea(false, "b12_full", titleStreamLoader);
    			newSmallFont = new RSFont(false, "p11_full", titleStreamLoader);
    			newRegularFont = new RSFont(false, "p12_full", titleStreamLoader);
    			newNormalFont = new RSFont(false, "p12_full", titleStreamLoader);
    			newBoldFont = new RSFont(false, "b12_full", titleStreamLoader);
    			newFancyFont = new RSFont(false, "q8_full", titleStreamLoader);
    			boldFont = new TextDrawingArea(false, "b12_full", titleStreamLoader);
    			normalFont = new TextDrawingArea(false, "p12_full", titleStreamLoader);
    			aTextDrawingArea_1273 = new TextDrawingArea(true, "q8_full", titleStreamLoader);
    			drawLogo();
    			loadTitleScreen();
    			Archive jagexArchive = streamLoaderForName(2, "config", "config", expectedCRCs[2], 30);
    			Archive streamLoader_1 = streamLoaderForName(3, "interface", "interface", expectedCRCs[3], 35);
    			Archive streamLoader_2 = streamLoaderForName(4, "2d graphics", "media", expectedCRCs[4], 40);
    			Archive streamLoader_3 = streamLoaderForName(6, "textures", "textures", expectedCRCs[6], 45);
    			Archive streamLoader_4 = streamLoaderForName(7, "chat system", "wordenc", expectedCRCs[7], 50);
    			streamLoaderForName(8, "sound effects", "sounds", expectedCRCs[8], 55);
    			byteGroundArray = new byte[4][104][104];
    			intGroundArray = new int[4][105][105];
    			worldController = new Scene(intGroundArray);
    			for (int j = 0; j < 4; j++)
    				aClass11Array1230[j] = new CollisionMap();
    
    			aClass30_Sub2_Sub1_Sub1_1263 = new Sprite(512, 512);
    			Archive streamLoader_6 = streamLoaderForName(5, "update list", "versionlist", expectedCRCs[5], 60);
                drawSmoothLoadingText(60, "Connecting to update server");
    			onDemandFetcher = new OnDemandFetcher();
    			onDemandFetcher.start(streamLoader_6, this);
    			Class36.method528(onDemandFetcher.getAnimCount());
    			Model.method459(onDemandFetcher.getModelCount(), onDemandFetcher);
                drawSmoothLoadingText(80, "Unpacking media");
    			ImageLoader.loadImageData(jagexArchive);
    			imageLoader = ImageLoader.image;
    			SkillOrbHandler.loadImages();
    			HPBarFull = new Sprite(Signlink.findcachedir() + "Interfaces/Player/HP0.png", 1);
    			HPBarEmpty = new Sprite(Signlink.findcachedir() + "Interfaces/Player/HP1.png", 1);
    			multiOverlay = new Sprite(streamLoader_2, "overlay_multiway", 0);
    			mapBack = new Background(streamLoader_2, "mapback", 0);
    			try {
    				SpriteLoader.loadSprites(streamLoader_2);
    				cacheSprite = SpriteLoader.sprites;
    			} catch (Exception e) {
    				System.out.println("Unable to load sprite cache.");
    			}
    			alertBack = new Sprite("Alert/alertback");
    			alertBorder = new Sprite("Alert/alertborder");
    			alertBorderH = new Sprite("Alert/alertborderh");
    			for (int index = 0; index < clanIcons.length; index++) {
    				clanIcons[index] = new Sprite("/Interfaces/Clan Chat/Icons/" + index);
    			}
    			for (int c1 = 0; c1 < 1; c1++)
    				newModIcons[c1] = new Sprite("Player/CROWN_" + c1);
    			for (int c1 = 0; c1 <= 3; c1++)
    				chatButtons[c1] = new Sprite(streamLoader_2, "chatbuttons", c1);
    			for (int j3 = 0; j3 <= 14; j3++)
    				sideIcons[j3] = new Sprite(streamLoader_2, "sideicons", j3);
    			for (int index = 0; index < 12; index++) {
    				scrollPart[index] = new Sprite("Scrollbar/b " + index);
    			}
    			for (int index = 0; index < 6; index++) {
    				scrollBar[index] = new Sprite("Scrollbar/s " + index);
    			}
    			compass = new Sprite(streamLoader_2, "compass", 0);
    			for (int s562 = 0; s562 < 4; s562++)
    				hitMarks562[s562] = new Sprite("Hitmarks/SPLAT_" + s562);
    			try {
    				for (int k3 = 0; k3 < 100; k3++)
    					mapScenes[k3] = new Background(streamLoader_2, "mapscene", k3);
    			} catch (Exception _ex) {
    			}
    			try {
    				for (int l3 = 0; l3 < 100; l3++)
    					mapFunctions[l3] = new Sprite(streamLoader_2, "mapfunction", l3);
    			} catch (Exception _ex) {
    			}
    			try {
    				for (int i4 = 0; i4 < 20; i4++)
    					hitMarks[i4] = new Sprite(streamLoader_2, "hitmarks", i4);
    			} catch (Exception _ex) {
    			}
    			try {
    				for (int h1 = 0; h1 < 6; h1++)
    					headIconsHint[h1] = new Sprite(streamLoader_2, "headicons_hint", h1);
    			} catch (Exception _ex) {
    			}
    			try {
    				for (int j4 = 0; j4 < 8; j4++)
    					headIcons[j4] = new Sprite(streamLoader_2, "headicons_prayer", j4);
    				for (int idx = 0; idx < 18; idx++)
    					headIcons[idx] = new Sprite("Player/Prayer/Prayer " + idx);
    				for (int j45 = 0; j45 < 3; j45++)
    					skullIcons[j45] = new Sprite(streamLoader_2, "headicons_pk", j45);
    			} catch (Exception _ex) {
    			}
    			try {
    				for (int i = 0; i < currencyImageAmount; i++) {
    					currencyImage[i] = new Sprite("/Shop/currency " + i);
    				}
    
    			} catch (Exception _ex) {
    			}
    			mapFlag = new Sprite(streamLoader_2, "mapmarker", 0);
    			mapMarker = new Sprite(streamLoader_2, "mapmarker", 1);
    			duelArena = new Sprite(streamLoader_2, "duel_arena", 0);
    			scrollBar1 = new Sprite(streamLoader_2, "scrollbar", 0);
    			scrollBar2 = new Sprite(streamLoader_2, "scrollbar", 1);
    			notInWild = new Sprite("/PvP/NOTINWILD1 0");
    			inWild = new Sprite("/PvP/INWILD1 0");
    			inTimer = new Sprite("/PvP/INCOUNT1 0");
    			for (int k4 = 0; k4 < 8; k4++)
    				crosses[k4] = new Sprite(streamLoader_2, "cross", k4);
    			mapDotItem = new Sprite(streamLoader_2, "mapdots", 0);
    			mapDotNPC = new Sprite(streamLoader_2, "mapdots", 1);
    			mapDotPlayer = new Sprite(streamLoader_2, "mapdots", 2);
    			mapDotFriend = new Sprite(streamLoader_2, "mapdots", 3);
    			mapDotTeam = new Sprite(streamLoader_2, "mapdots", 4);
    			mapDotClan = new Sprite(streamLoader_2, "mapdots", 5);
    			for (int i4 = 0; i4 < 20; i4++)
    				hitMark[i4] = new Sprite("/Hits/hit " + i4);
    			for (int i4 = 0; i4 < 5; i4++)
    				hitIcon[i4] = new Sprite("/Hits/icon " + i4);
    			for (int l4 = 0; l4 < 10; l4++)
    				modIcons[l4] = new Sprite(streamLoader_2, "mod_icons", l4);
    			RSFont.unpackImages(modIcons, clanIcons);
    			infinity = new Sprite("/Shop/infinity");
    			backgroundFix = new Sprite("");
    			realBackground = new Sprite("Background");
    			Sprite sprite = new Sprite(streamLoader_2, "screenframe", 0);
    			leftFrame = new GraphicalComponent(sprite.myWidth, sprite.myHeight);
    			sprite.method346(0, 0);
    			sprite = new Sprite(streamLoader_2, "screenframe", 1);
    			topFrame = new GraphicalComponent(sprite.myWidth, sprite.myHeight);
    			sprite.method346(0, 0);
    			int i5 = (int) (Math.random() * 21D) - 10;
    			int j5 = (int) (Math.random() * 21D) - 10;
    			int k5 = (int) (Math.random() * 21D) - 10;
    			int l5 = (int) (Math.random() * 41D) - 20;
    			for (int i6 = 0; i6 < 100; i6++) {
    				if (mapFunctions[i6] != null)
    					mapFunctions[i6].method344(i5 + l5, j5 + l5, k5 + l5);
    				if (mapScenes[i6] != null)
    					mapScenes[i6].method360(i5 + l5, j5 + l5, k5 + l5);
    			}
                drawSmoothLoadingText(83, "Unpacking textures");
    			Rasterizer.unpackTextures(streamLoader_3);
    			Rasterizer.calculatePalette(0.80000000000000004D);
    			Rasterizer.resetTextures();
    			Animation.unpackConfig(jagexArchive);
    			ObjectDefinition.unpackConfig(jagexArchive);
    			OverlayFloor.unpackConfig(jagexArchive);
    			UnderlayFloor.unpackConfig(jagexArchive);
    			ItemDefinition.unpackConfig(jagexArchive);
    			EntityDefinition.unpackConfig(jagexArchive);
    			IdentityKitDefinition.unpackConfig(jagexArchive);
    			SpotAnimDefinition.unpackConfig(jagexArchive);
    			Varp.unpackConfig(jagexArchive);
    			VarBit.unpackConfig(jagexArchive);
    			ItemDefinition.isMembers = isMembers;
                drawSmoothLoadingText(95, "Unpacking interfaces");
    			TextDrawingArea aclass30_sub2_sub1_sub4s[] = { smallText, aTextDrawingArea_1271, chatTextDrawingArea, aTextDrawingArea_1273 };
    			RSInterface.unpack(imageLoader, streamLoader_1, aclass30_sub2_sub1_sub4s, streamLoader_2);
                drawSmoothLoadingText(100, "Preparing game engine");
    			for (int j6 = 0; j6 < 33; j6++) {
    				int k6 = 999;
    				int i7 = 0;
    				for (int k7 = 0; k7 < 34; k7++) {
    					if (mapBack.aByteArray1450[k7 + j6 * mapBack.anInt1452] == 0) {
    						if (k6 == 999)
    							k6 = k7;
    						continue;
    					}
    					if (k6 == 999)
    						continue;
    					i7 = k7;
    					break;
    				}
    				anIntArray968[j6] = k6;
    				anIntArray1057[j6] = i7 - k6;
    			}
    			for (int l6 = 1; l6 < 153; l6++) {
    				int j7 = 999;
    				int l7 = 0;
    				for (int j8 = 24; j8 < 177; j8++) {
    					if (mapBack.aByteArray1450[j8 + l6 * mapBack.anInt1452] == 0 && (j8 > 34 || l6 > 34)) {
    						if (j7 == 999) {
    							j7 = j8;
    						}
    						continue;
    					}
    					if (j7 == 999) {
    						continue;
    					}
    					l7 = j8;
    					break;
    				}
    				anIntArray1052[l6 - 1] = j7 - 24;
    				anIntArray1229[l6 - 1] = l7 - j7;
    			}
    			updateGameArea();
    			Censor.loadConfig(streamLoader_4);
    			mouseDetection = new MouseDetection(this);
    			startRunnable(mouseDetection, 10);
    			Animable_Sub5.clientInstance = this;
    			ObjectDefinition.clientInstance = this;
    			EntityDefinition.clientInstance = this;
    			return;
    		} catch (Exception exception) {
    			exception.printStackTrace();
    			Signlink.reporterror("loaderror " + lastMessage + " " + lastPercent);
    		}
    		loadingError = true;
    	}
    - Add
    Code:
    new CacheDownloader().downloadCache();
    right under
    Code:
    void startUp() {
    like this:
    Code:
    void startUp() {
    		new CacheDownloader().downloadCache();
    		drawSmoothLoadingText(20, "Starting up");
    		loginRenderer = new LoginRenderer(this);
    		Config.determineClient();
    		for (int index = 0; index < 25; index++) {
    			bubbles.add(new Bubble());
    		}
    
    
    		if (Signlink.sunjava)
    			super.minDelay = 5;
    		if (Signlink.cache_dat != null) {
    			for (int i = 0; i < 5; i++)
    				decompressors[i] = new Decompressor(Signlink.cache_dat, Signlink.cache_idx[i], i + 1);
    		}
    		try {
    			titleStreamLoader = streamLoaderForName(1, "title screen", "title", expectedCRCs[1], 25);
    			smallText = new TextDrawingArea(false, "p11_full", titleStreamLoader);
    			smallHit = new TextDrawingArea(false, "hit_full", titleStreamLoader);
    			bigHit = new TextDrawingArea(true, "critical_full", titleStreamLoader);
    			aTextDrawingArea_1271 = new TextDrawingArea(false, "p12_full", titleStreamLoader);
    			fancyFont = new TextDrawingArea(false, "q8_full", titleStreamLoader);
    			chatTextDrawingArea = new TextDrawingArea(false, "b12_full", titleStreamLoader);
    			newSmallFont = new RSFont(false, "p11_full", titleStreamLoader);
    			newRegularFont = new RSFont(false, "p12_full", titleStreamLoader);
    			newNormalFont = new RSFont(false, "p12_full", titleStreamLoader);
    			newBoldFont = new RSFont(false, "b12_full", titleStreamLoader);
    			newFancyFont = new RSFont(false, "q8_full", titleStreamLoader);
    			boldFont = new TextDrawingArea(false, "b12_full", titleStreamLoader);
    			normalFont = new TextDrawingArea(false, "p12_full", titleStreamLoader);
    			aTextDrawingArea_1273 = new TextDrawingArea(true, "q8_full", titleStreamLoader);
    			drawLogo();
    			loadTitleScreen();
    			Archive jagexArchive = streamLoaderForName(2, "config", "config", expectedCRCs[2], 30);
    			Archive streamLoader_1 = streamLoaderForName(3, "interface", "interface", expectedCRCs[3], 35);
    			Archive streamLoader_2 = streamLoaderForName(4, "2d graphics", "media", expectedCRCs[4], 40);
    			Archive streamLoader_3 = streamLoaderForName(6, "textures", "textures", expectedCRCs[6], 45);
    			Archive streamLoader_4 = streamLoaderForName(7, "chat system", "wordenc", expectedCRCs[7], 50);
    			streamLoaderForName(8, "sound effects", "sounds", expectedCRCs[8], 55);
    			byteGroundArray = new byte[4][104][104];
    			intGroundArray = new int[4][105][105];
    			worldController = new Scene(intGroundArray);
    			for (int j = 0; j < 4; j++)
    				aClass11Array1230[j] = new CollisionMap();
    
    			aClass30_Sub2_Sub1_Sub1_1263 = new Sprite(512, 512);
    			Archive streamLoader_6 = streamLoaderForName(5, "update list", "versionlist", expectedCRCs[5], 60);
                drawSmoothLoadingText(60, "Connecting to update server");
    			onDemandFetcher = new OnDemandFetcher();
    			onDemandFetcher.start(streamLoader_6, this);
    			Class36.method528(onDemandFetcher.getAnimCount());
    			Model.method459(onDemandFetcher.getModelCount(), onDemandFetcher);
                drawSmoothLoadingText(80, "Unpacking media");
    			ImageLoader.loadImageData(jagexArchive);
    			imageLoader = ImageLoader.image;
    			SkillOrbHandler.loadImages();
    			HPBarFull = new Sprite(Signlink.findcachedir() + "Interfaces/Player/HP0.png", 1);
    			HPBarEmpty = new Sprite(Signlink.findcachedir() + "Interfaces/Player/HP1.png", 1);
    			multiOverlay = new Sprite(streamLoader_2, "overlay_multiway", 0);
    			mapBack = new Background(streamLoader_2, "mapback", 0);
    			try {
    				SpriteLoader.loadSprites(streamLoader_2);
    				cacheSprite = SpriteLoader.sprites;
    			} catch (Exception e) {
    				System.out.println("Unable to load sprite cache.");
    			}
    			alertBack = new Sprite("Alert/alertback");
    			alertBorder = new Sprite("Alert/alertborder");
    			alertBorderH = new Sprite("Alert/alertborderh");
    			for (int index = 0; index < clanIcons.length; index++) {
    				clanIcons[index] = new Sprite("/Interfaces/Clan Chat/Icons/" + index);
    			}
    			for (int c1 = 0; c1 < 1; c1++)
    				newModIcons[c1] = new Sprite("Player/CROWN_" + c1);
    			for (int c1 = 0; c1 <= 3; c1++)
    				chatButtons[c1] = new Sprite(streamLoader_2, "chatbuttons", c1);
    			for (int j3 = 0; j3 <= 14; j3++)
    				sideIcons[j3] = new Sprite(streamLoader_2, "sideicons", j3);
    			for (int index = 0; index < 12; index++) {
    				scrollPart[index] = new Sprite("Scrollbar/b " + index);
    			}
    			for (int index = 0; index < 6; index++) {
    				scrollBar[index] = new Sprite("Scrollbar/s " + index);
    			}
    			compass = new Sprite(streamLoader_2, "compass", 0);
    			for (int s562 = 0; s562 < 4; s562++)
    				hitMarks562[s562] = new Sprite("Hitmarks/SPLAT_" + s562);
    			try {
    				for (int k3 = 0; k3 < 100; k3++)
    					mapScenes[k3] = new Background(streamLoader_2, "mapscene", k3);
    			} catch (Exception _ex) {
    			}
    			try {
    				for (int l3 = 0; l3 < 100; l3++)
    					mapFunctions[l3] = new Sprite(streamLoader_2, "mapfunction", l3);
    			} catch (Exception _ex) {
    			}
    			try {
    				for (int i4 = 0; i4 < 20; i4++)
    					hitMarks[i4] = new Sprite(streamLoader_2, "hitmarks", i4);
    			} catch (Exception _ex) {
    			}
    			try {
    				for (int h1 = 0; h1 < 6; h1++)
    					headIconsHint[h1] = new Sprite(streamLoader_2, "headicons_hint", h1);
    			} catch (Exception _ex) {
    			}
    			try {
    				for (int j4 = 0; j4 < 8; j4++)
    					headIcons[j4] = new Sprite(streamLoader_2, "headicons_prayer", j4);
    				for (int idx = 0; idx < 18; idx++)
    					headIcons[idx] = new Sprite("Player/Prayer/Prayer " + idx);
    				for (int j45 = 0; j45 < 3; j45++)
    					skullIcons[j45] = new Sprite(streamLoader_2, "headicons_pk", j45);
    			} catch (Exception _ex) {
    			}
    			try {
    				for (int i = 0; i < currencyImageAmount; i++) {
    					currencyImage[i] = new Sprite("/Shop/currency " + i);
    				}
    
    			} catch (Exception _ex) {
    			}
    			mapFlag = new Sprite(streamLoader_2, "mapmarker", 0);
    			mapMarker = new Sprite(streamLoader_2, "mapmarker", 1);
    			duelArena = new Sprite(streamLoader_2, "duel_arena", 0);
    			scrollBar1 = new Sprite(streamLoader_2, "scrollbar", 0);
    			scrollBar2 = new Sprite(streamLoader_2, "scrollbar", 1);
    			notInWild = new Sprite("/PvP/NOTINWILD1 0");
    			inWild = new Sprite("/PvP/INWILD1 0");
    			inTimer = new Sprite("/PvP/INCOUNT1 0");
    			for (int k4 = 0; k4 < 8; k4++)
    				crosses[k4] = new Sprite(streamLoader_2, "cross", k4);
    			mapDotItem = new Sprite(streamLoader_2, "mapdots", 0);
    			mapDotNPC = new Sprite(streamLoader_2, "mapdots", 1);
    			mapDotPlayer = new Sprite(streamLoader_2, "mapdots", 2);
    			mapDotFriend = new Sprite(streamLoader_2, "mapdots", 3);
    			mapDotTeam = new Sprite(streamLoader_2, "mapdots", 4);
    			mapDotClan = new Sprite(streamLoader_2, "mapdots", 5);
    			for (int i4 = 0; i4 < 20; i4++)
    				hitMark[i4] = new Sprite("/Hits/hit " + i4);
    			for (int i4 = 0; i4 < 5; i4++)
    				hitIcon[i4] = new Sprite("/Hits/icon " + i4);
    			for (int l4 = 0; l4 < 10; l4++)
    				modIcons[l4] = new Sprite(streamLoader_2, "mod_icons", l4);
    			RSFont.unpackImages(modIcons, clanIcons);
    			infinity = new Sprite("/Shop/infinity");
    			backgroundFix = new Sprite("");
    			realBackground = new Sprite("Background");
    			Sprite sprite = new Sprite(streamLoader_2, "screenframe", 0);
    			leftFrame = new GraphicalComponent(sprite.myWidth, sprite.myHeight);
    			sprite.method346(0, 0);
    			sprite = new Sprite(streamLoader_2, "screenframe", 1);
    			topFrame = new GraphicalComponent(sprite.myWidth, sprite.myHeight);
    			sprite.method346(0, 0);
    			int i5 = (int) (Math.random() * 21D) - 10;
    			int j5 = (int) (Math.random() * 21D) - 10;
    			int k5 = (int) (Math.random() * 21D) - 10;
    			int l5 = (int) (Math.random() * 41D) - 20;
    			for (int i6 = 0; i6 < 100; i6++) {
    				if (mapFunctions[i6] != null)
    					mapFunctions[i6].method344(i5 + l5, j5 + l5, k5 + l5);
    				if (mapScenes[i6] != null)
    					mapScenes[i6].method360(i5 + l5, j5 + l5, k5 + l5);
    			}
                drawSmoothLoadingText(83, "Unpacking textures");
    			Rasterizer.unpackTextures(streamLoader_3);
    			Rasterizer.calculatePalette(0.80000000000000004D);
    			Rasterizer.resetTextures();
    			Animation.unpackConfig(jagexArchive);
    			ObjectDefinition.unpackConfig(jagexArchive);
    			OverlayFloor.unpackConfig(jagexArchive);
    			UnderlayFloor.unpackConfig(jagexArchive);
    			ItemDefinition.unpackConfig(jagexArchive);
    			EntityDefinition.unpackConfig(jagexArchive);
    			IdentityKitDefinition.unpackConfig(jagexArchive);
    			SpotAnimDefinition.unpackConfig(jagexArchive);
    			Varp.unpackConfig(jagexArchive);
    			VarBit.unpackConfig(jagexArchive);
    			ItemDefinition.isMembers = isMembers;
                drawSmoothLoadingText(95, "Unpacking interfaces");
    			TextDrawingArea aclass30_sub2_sub1_sub4s[] = { smallText, aTextDrawingArea_1271, chatTextDrawingArea, aTextDrawingArea_1273 };
    			RSInterface.unpack(imageLoader, streamLoader_1, aclass30_sub2_sub1_sub4s, streamLoader_2);
                drawSmoothLoadingText(100, "Preparing game engine");
    			for (int j6 = 0; j6 < 33; j6++) {
    				int k6 = 999;
    				int i7 = 0;
    				for (int k7 = 0; k7 < 34; k7++) {
    					if (mapBack.aByteArray1450[k7 + j6 * mapBack.anInt1452] == 0) {
    						if (k6 == 999)
    							k6 = k7;
    						continue;
    					}
    					if (k6 == 999)
    						continue;
    					i7 = k7;
    					break;
    				}
    				anIntArray968[j6] = k6;
    				anIntArray1057[j6] = i7 - k6;
    			}
    			for (int l6 = 1; l6 < 153; l6++) {
    				int j7 = 999;
    				int l7 = 0;
    				for (int j8 = 24; j8 < 177; j8++) {
    					if (mapBack.aByteArray1450[j8 + l6 * mapBack.anInt1452] == 0 && (j8 > 34 || l6 > 34)) {
    						if (j7 == 999) {
    							j7 = j8;
    						}
    						continue;
    					}
    					if (j7 == 999) {
    						continue;
    					}
    					l7 = j8;
    					break;
    				}
    				anIntArray1052[l6 - 1] = j7 - 24;
    				anIntArray1229[l6 - 1] = l7 - j7;
    			}
    			updateGameArea();
    			Censor.loadConfig(streamLoader_4);
    			mouseDetection = new MouseDetection(this);
    			startRunnable(mouseDetection, 10);
    			Animable_Sub5.clientInstance = this;
    			ObjectDefinition.clientInstance = this;
    			EntityDefinition.clientInstance = this;
    			return;
    		} catch (Exception exception) {
    			exception.printStackTrace();
    			Signlink.reporterror("loaderror " + lastMessage + " " + lastPercent);
    		}
    		loadingError = true;
    	}
    You have to remove the old cache downloader and do the imports yourself.

    For the experienced coders:
    If you want to you can check the code and tell me in a nice constructive manner how I can improve it.
    This is just a learning project for me.
    Attached image
    Reply With Quote  
     

  2. #2  
    Registered Member
    Join Date
    Apr 2016
    Posts
    124
    Thanks given
    14
    Thanks received
    21
    Rep Power
    37
    Enums still follow class name conventions; cachePart should be CachePart

    What is the point of CachePart?

    This pretty much looks like the 'cache downloader' that most if not all clients come with now-a-days (excluding the checksum), except that it's split up into an unnecessary amount of classes.
    Reply With Quote  
     

  3. #3  
    Registered Member Rememberm3's Avatar
    Join Date
    Aug 2013
    Posts
    1,716
    Thanks given
    56
    Thanks received
    108
    Rep Power
    129
    Quote Originally Posted by NeedDump View Post
    Enums still follow class name conventions; cachePart should be CachePart

    What is the point of CachePart?

    This pretty much looks like the 'cache downloader' that most if not all clients come with now-a-days (excluding the checksum), except that it's split up into an unnecessary amount of classes.
    Okay, thank you for the conventions. I'm really bad with when I should split things up and when not. The point of CachePart? You can just have multiple parts of the cache so it checks for each part and if there is an update it only downloads that part, which means that it only downloads the updated parts, so it doesn't redownload the whole cache.
    Attached image
    Reply With Quote  
     

  4. #4  
    Registered Member
    Join Date
    Apr 2016
    Posts
    124
    Thanks given
    14
    Thanks received
    21
    Rep Power
    37
    Quote Originally Posted by RememberM3 View Post
    Okay, thank you for the conventions. I'm really bad with when I should split things up and when not. The point of CachePart? You can just have multiple parts of the cache so it checks for each part and if there is an update it only downloads that part, which means that it only downloads the updated parts, so it doesn't redownload the whole cache.
    If that's the case then upon downloading the "CachePart" required it should actually contain a list of all CacheParts required and download them, either synchronously or asynchronously.
    Reply With Quote  
     

  5. #5  
    Registered Member Rememberm3's Avatar
    Join Date
    Aug 2013
    Posts
    1,716
    Thanks given
    56
    Thanks received
    108
    Rep Power
    129
    Quote Originally Posted by NeedDump View Post
    If that's the case then upon downloading the "CachePart" required it should actually contain a list of all CacheParts required and download them, either synchronously or asynchronously.
    But that's the enum for, right?
    Attached image
    Reply With Quote  
     

  6. #6  
    Registered Member
    Join Date
    May 2016
    Posts
    90
    Thanks given
    3
    Thanks received
    21
    Rep Power
    0
    this is really ugly
    Reply With Quote  
     

  7. #7  
    Registered Member Rememberm3's Avatar
    Join Date
    Aug 2013
    Posts
    1,716
    Thanks given
    56
    Thanks received
    108
    Rep Power
    129
    Quote Originally Posted by LareBear96 View Post
    this is really ugly
    I know, this is one of my first things I really coded myself. Can you tell me what I should improve instead of only saying "this is really ugly".
    Attached image
    Reply With Quote  
     

  8. #8  
    Registered Member
    Join Date
    May 2016
    Posts
    90
    Thanks given
    3
    Thanks received
    21
    Rep Power
    0
    Quote Originally Posted by RememberM3 View Post
    I know, this is one of my first things I really coded myself. Can you tell me what I should improve instead of only saying "this is really ugly".
    Code:
    public class Data {
    	
    	public final static String cacheName = "MyCache";
    
    	public enum cachePart {
    		PART1("LINK TO CACHE"),
    		CAN_BE_ANY_NAME("LINK HAS TO BE DIRECT"),
    		LAST_PART("ENDS WITH ';'");
    
    		private String downloadURL;
    
    		private cachePart(String downloadURL) {
    			this.downloadURL = downloadURL;
    		}
    
    		public String getFile() {
    			if (downloadURL.endsWith("?dl=1")) {
    				return downloadURL.substring(downloadURL.lastIndexOf("/") + 1)
    						.replace("?dl=1", "");
    			} else {
    				return downloadURL.substring(downloadURL.lastIndexOf("/") + 1);
    			}
    		}
    
    		public String getFilePath() {
    			return SAVE_DIR() + getFile();
    		}
    
    		public int lengthOfEnum() {
    			return cachePart.values().length;
    		}
    
    		public boolean isZip() {
    			return getFile().endsWith(".zip");
    		}
    
    		public URL downloadURL() {
    			URL URL = null;
    			try {
    				URL = new URL(downloadURL);
    			} catch (MalformedURLException e) {
    				e.printStackTrace();
    			}
    			return URL;
    		}
    
    	}
    	
    	public static final String SAVE_DIR() {
    		File file = new File(System.getProperty("user.home") + "/" + cacheName + "/");
    		if (!file.exists()) {
    			if (!file.mkdir())
    				return "C:/MistextCache/";
    		}
    		return System.getProperty("user.home") + "/" + cacheName + "/";
    	}
    
    }
    this is not what enumerated types are meant for. also why do you have a class Data and have an enumerated class cachePart inside of it. you have no instanced information inside data so you don't need that class. also what is up with the name cachePart..... enum should be Data not cachePart. you can use static methods inside an enum.

    learn what object-orientated means, avoid getting into the bad habit of creating all of these static methods in every class... that's extremely bad to do because now they have a global state. when you develop larger programs its good practice not to make everything have a global state.

    Code:
    public class CacheDownloader {
    
    	public CacheDownloader downloadCache() {
    		for (Data.cachePart Files: Data.cachePart.values()) {
    			if (Update.updateExists(Files)) {
    				try {
    					Download.download(Files);
    				} catch (IOException e) {
    					e.printStackTrace();
    				}
    			} else {
    				Status.drawLoadingInfo(100, Files + " Doesn't have an update!");
    			}
    		}
    		return null;
    	}
    
    }
    try to think of better solutions to avoid returning null on a lot of your methods.
    Reply With Quote  
     

  9. #9  
    Registered Member Rememberm3's Avatar
    Join Date
    Aug 2013
    Posts
    1,716
    Thanks given
    56
    Thanks received
    108
    Rep Power
    129
    Quote Originally Posted by LareBear96 View Post
    Code:
    public class Data {
    
    public final static String cacheName = "MyCache";
    
    public enum cachePart {
    PART1("LINK TO CACHE"),
    CAN_BE_ANY_NAME("LINK HAS TO BE DIRECT"),
    LAST_PART("ENDS WITH ';'");
    
    private String downloadURL;
    
    private cachePart(String downloadURL) {
    this.downloadURL = downloadURL;
    }
    
    public String getFile() {
    if (downloadURL.endsWith("?dl=1")) {
    return downloadURL.substring(downloadURL.lastIndexOf("/") + 1)
    .replace("?dl=1", "");
    } else {
    return downloadURL.substring(downloadURL.lastIndexOf("/") + 1);
    }
    }
    
    public String getFilePath() {
    return SAVE_DIR() + getFile();
    }
    
    public int lengthOfEnum() {
    return cachePart.values().length;
    }
    
    public boolean isZip() {
    return getFile().endsWith(".zip");
    }
    
    public URL downloadURL() {
    URL URL = null;
    try {
    URL = new URL(downloadURL);
    } catch (MalformedURLException e) {
    e.printStackTrace();
    }
    return URL;
    }
    
    }
    
    public static final String SAVE_DIR() {
    File file = new File(System.getProperty("user.home") + "/" + cacheName + "/");
    if (!file.exists()) {
    if (!file.mkdir())
    return "C:/MistextCache/";
    }
    return System.getProperty("user.home") + "/" + cacheName + "/";
    }
    
    }
    this is not what enumerated types are meant for. also why do you have a class Data and have an enumerated class cachePart inside of it. you have no instanced information inside data so you don't need that class. also what is up with the name cachePart..... enum should be Data not cachePart. you can use static methods inside an enum.

    learn what object-orientated means, avoid getting into the bad habit of creating all of these static methods in every class... that's extremely bad to do because now they have a global state. when you develop larger programs its good practice not to make everything have a global state.

    Code:
    public class CacheDownloader {
    
    public CacheDownloader downloadCache() {
    for (Data.cachePart Files: Data.cachePart.values()) {
    if (Update.updateExists(Files)) {
    try {
    Download.download(Files);
    } catch (IOException e) {
    e.printStackTrace();
    }
    } else {
    Status.drawLoadingInfo(100, Files + " Doesn't have an update!");
    }
    }
    return null;
    }
    
    }
    try to think of better solutions to avoid returning null on a lot of your methods.
    Thank you, this is what I wanted. Now I can improve. How would you avoid returning null?
    Attached image
    Reply With Quote  
     

  10. #10  
    Banned
    Join Date
    Jan 2011
    Posts
    334
    Thanks given
    20
    Thanks received
    88
    Rep Power
    0
    Quote Originally Posted by RememberM3 View Post
    Thank you, this is what I wanted. Now I can improve. How would you avoid returning null?
    For one thing, you can utilize Java's Optional<T> class instead.
    Reply With Quote  
     

Page 1 of 2 12 LastLast

Thread Information
Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)


User Tag List

Similar Threads

  1. Auto Cache Downloading
    By James in forum Tutorials
    Replies: 113
    Last Post: 09-27-2008, 04:25 PM
  2. Auto Cache Downloading (Here's how!)
    By Ninja Cat in forum Tutorials
    Replies: 22
    Last Post: 03-11-2008, 02:50 PM
  3. 417 cache download!
    By Mr.Andrew Gover in forum RS2 Client
    Replies: 14
    Last Post: 12-15-2007, 07:25 PM
  4. Auto Cache download?
    By Eportal in forum Tutorials
    Replies: 4
    Last Post: 10-07-2007, 06:34 PM
  5. Buying Auto cache downloading webclient
    By wildy in forum RS2 Client
    Replies: 2
    Last Post: 08-24-2007, 03:40 AM
Posting Permissions
  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •