317 and 508 custom RSA keys

I’m implementing custom RSA key support in MoparScape 4, and for RSC it was pretty self explanatory, for 317 I never see an actual ‘Key’ object being made, so I don’t know where exactly to do this.

I know that to disable rsa, this comment was needed (this is how 317 currently runs):
in Stream.java

    public void doKeys() {
        int i = currentOffset;
        currentOffset = 0;
        byte abyte0[] = new byte[i];
        readBytes(i, 0, abyte0);
        BigInteger biginteger2 = new BigInteger(abyte0);
        BigInteger biginteger3 = biginteger2/*.modPow(biginteger, biginteger1)*/;
        byte abyte1[] = biginteger3.toByteArray();
        currentOffset = 0;
        writeWordBigEndian(abyte1.length);
        writeBytes(abyte1, abyte1.length, 0);
    }

Similar code exists in 508 Stream.java:

    public void doKeys(boolean bool, BigInteger biginteger, BigInteger biginteger_19_) {
        try {
            anInt2995++;
            int i = currentOffset;
            byte[] is = new byte[i];
            currentOffset = 0;
            method938(0, 0, i, is);
            BigInteger biginteger_20_ = new BigInteger(is);
            if (bool != false) {
                aClass68_Sub17_2994 = null;
            }
            BigInteger biginteger_21_ = biginteger_20_; //.modPow(biginteger, biginteger_19_);
            byte[] is_22_ = biginteger_21_.toByteArray();
            currentOffset = 0;
            writeByte(is_22_.length);
            writeBytes(is_22_.length, 0, is_22_);
        } catch (RuntimeException runtimeexception) {
            throw Class107.method1652(runtimeexception,
                    ("lh.UA(" + bool + ',' + (biginteger != null ? "{...}"
                            : "null") + ',' + (biginteger_19_ != null ? "{...}"
                            : "null") + ')'));
        }
    }

Say I have an RSA key byte array, the kind I would send into X509EncodedKeySpec() to create a public key, how do I translate that to the above?

Thanks for any help or pointers you can give.

I’ve been unable to properly implement the key using the available classes in Java. But basically the method is this

BigInteger message = new BigInteger(data);
BigInteger encodedData = message.modPow(publicKey, modulus);

Source: http://introcs.cs.princeton.edu/java/78crypto/RSA.java.html

        BigInteger biginteger2 = new BigInteger(abyte0);
        BigInteger biginteger3 = biginteger2/*.modPow(biginteger, biginteger1)*/;

ta da! (the correct instructions are commented out)

[quote=“t4, post:5, topic:431796”] BigInteger biginteger2 = new BigInteger(abyte0); BigInteger biginteger3 = biginteger2/*.modPow(biginteger, biginteger1)*/;
ta da! (the correct instructions are commented out)[/quote]
yeah thats all you need to do is uncomment the code and generate your public and private keys.

I generated the keys with something similar to this:

import java.security.KeyPair;
import java.security.KeyPairGenerator;

/**
 * Created by IntelliJ IDEA.
 * User: dloth
 * Date: 31/01/12
 * Time: 11:21 AM
 * To change this template use File | Settings | File Templates.
 */
public class KeyGenerator {
   
    public static void main(String[] args) throws Exception {
        KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");

        // Generate a key that is 2048 bits long
        RSAKeyGenParameterSpec spec = new RSAKeyGenParameterSpec(2048, RSAKeyGenParameterSpec.F4);
        keyGen.initialize(spec);
        KeyPair pair = keyGen.generateKeyPair();
        System.out.printf("Private key: %s\n\n", pair.getPrivate());
        System.out.printf("Public key: %s\n\n", pair.getPublic());
    }
}

And kept the byte array that key.getEncoded() returned. I knew the commented part did the actual encryption, but I wasn’t sure how to get from the byte array to what that particular bit of code needed.

[quote=“zyle1992, post:3, topic:431796”]I’ve been unable to properly implement the key using the available classes in Java. But basically the method is this

BigInteger message = new BigInteger(data);
BigInteger encodedData = message.modPow(publicKey, modulus);

Source: http://introcs.cs.princeton.edu/java/78crypto/RSA.java.html[/quote]

If that is correct, then all I need to do to get the publicKey and modulus BigInteger’s would be something like this:

KeyFactory keyFactory = KeyFactory.getInstance("RSA");
RSAPublicKey pubKey = keyFactory.generatePublic(new X509EncodedKeySpec(myByteArray));
BigInteger publicKey = pubKey.getPublicExponent();
BigInteger modulus = pubKey.getModulus();

and that is it? If so, thanks, easy enough. :slight_smile:

[quote=“Moparisthebest, post:7, topic:431796”]I generated the keys with something similar to this:

import java.security.KeyPair;
import java.security.KeyPairGenerator;

/**
 * Created by IntelliJ IDEA.
 * User: dloth
 * Date: 31/01/12
 * Time: 11:21 AM
 * To change this template use File | Settings | File Templates.
 */
public class KeyGenerator {
   
    public static void main(String[] args) throws Exception {
        KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");

        // Generate a key that is 2048 bits long
        RSAKeyGenParameterSpec spec = new RSAKeyGenParameterSpec(2048, RSAKeyGenParameterSpec.F4);
        keyGen.initialize(spec);
        KeyPair pair = keyGen.generateKeyPair();
        System.out.printf("Private key: %s\n\n", pair.getPrivate());
        System.out.printf("Public key: %s\n\n", pair.getPublic());
    }
}

And kept the byte array that key.getEncoded() returned. I knew the commented part did the actual encryption, but I wasn’t sure how to get from the byte array to what that particular bit of code needed.

If that is correct, then all I need to do to get the publicKey and modulus BigInteger’s would be something like this:

KeyFactory keyFactory = KeyFactory.getInstance("RSA");
RSAPublicKey pubKey = keyFactory.generatePublic(new X509EncodedKeySpec(myByteArray));
BigInteger publicKey = pubKey.getPublicExponent();
BigInteger modulus = pubKey.getModulus();

and that is it? If so, thanks, easy enough. :)[/quote]

the public keys are static biginteger variables in the client, why do you need to go from a bytearray? :s

To allow people to specify their own public keys, I’m currently planning to accept either base64 url-friendly encoding of the key pasted directly into the program, or a file with a base64 encoding of the key with any supported download method (either http(s) or bittorrent)

317 doesn’t store any “key” object, it simply stores the public exponent and modulus as BigInteger instances.
You use BigInteger.modPow(exp, mod) to both encode and decode the block.

If you want to use the abstracted Java API version for it, this may help you:
https://github.com/vexsoftware/votifier/blob/master/java/com/vexsoftware/votifier/crypto/RSAIO.java
https://github.com/vexsoftware/votifier/blob/master/java/com/vexsoftware/votifier/crypto/RSA.java

I’ve already implemented this into the current version of MoparScape 4, you can check it out now. :slight_smile:

you should really put your mscp v* on git or something

[quote=“t4, post:12, topic:431796”][quote author=Moparisthebest link=topic=534500.msg3927062#msg3927062 date=1330316424]
I’ve already implemented this into the current version of MoparScape 4, you can check it out now. :slight_smile:
[/quote]
you should really put your mscp v* on git or something[/quote]

I share all of the interesting code in MoparscapeSources.jar, but I’ve been meaning to change the distribution to something better like git, I just have to write all new automation code to push it out there for me, so I’m not as motivated to change it. :slight_smile:

What does ‘v*’ mean though? :confused:

version#

i remember along time ago there was a moparscape client that wasn’t loaded into a custom UI, i think it was moparscape 2 or something? what were the differences between that and 3? what was moparscape 1?

Oh, gotcha.

Let me see if I remember. MoparScape ‘1’ was just called MoparScape, and it was a cheat client for regular runescape, before private servers existed. It had things that gave PVPers an advantage, like HP over heads, and color-coding of people (by level) on the mini-map in the wilderness so you knew who you could beat and who could beat you before you got close enough to see them the legit way. It also had things for SCAR scripters, such as locking the map true north (or any other way), and colors that didn’t change like the normal client. It also had some strings changed (hold onto your butts…), and disabled the chat censor which people liked. I wrote a truly awful automatic updater for it, that used waffendennis’s deobs, read the .java files I was interested in into a giant String[] line-by-line and proceeded to edit the source code based on a lot of .substring()'s and .indexOf()'s (no regular expressions!), then recompiled it so I could upload it to kaitneiks.com. I probably still have that stuff someplace, no idea where though.

MoparScape 2 was the same thing I believe, except a private server client for 317.

MoparScape 3 had all the above features, as well as Aryan (the bot) built into it.

MoparScape 4 is just a fancy loader with a bunch of features, so anyone can write any client for it. Because it seems people insist on creating their own client now to add an item or two.

That’s what I remember so far, if I track down my updater I’ll post it and many laughs will be had. I think it was the first thing I wrote in Java outside of my entry-level Java class, my only other experience programming at the time was writing and/or modifying other’s SCAR scripts. :slight_smile:

edit:
I forgot about ‘MoparScape Revolution’, which was basically an improved version of MoparScape (1). I just found the source code, I’m not sure if it was the latest, but you’ll get an idea of how bad it was anyhow. Hell, I used windows at the time. :slight_smile:

From scanning over the updater, the features at the time were:

  1. World Switcher
  2. Maplock
  3. Zoom in/out and camera movement (move camera away from player)
  4. HP over heads
  5. Removed logo, changed strings
  6. mapdots, the PVP color-coding I mentioned earlier.

here is the original .rar archive I found dated April, 2006:
http://uppit.com/ini5jxjbwqzc/moparsfullupdate.rar

Haha, this was my ‘improved’ version of the updater, it was actually much cleaner than the original, if you can believe it. It almost makes me want to puke looking at this:

import java.io.*;
import java.util.regex.*;

public class ClientUpdater
{

	public static String fileprefix = "output/";
	public static String[] clientline = new String[20000];
	
	private static String getRegexString(String regex,String searchstring){
		String[] result = searchstring.split(regex);
		if(result.length==2)
   	  return (searchstring.substring(result[0].length(),searchstring.length()-result[1].length()));
   	else
     return (searchstring.substring(result[0].length()));
 	}

	 	private static void renamePrivVar(String regex, String newName){
 		  for (int x=0;x<clientline.length&&clientline[x]!=null; x++)
 		    clientline[x] = clientline[x].replaceAll(regex,newName);
		}
		
		private static void renamePrivVar(String[] regex, String[] newName){
			if(regex.length!=newName.length)
				return;
 		  for (int x=0;x<clientline.length&&clientline[x]!=null; x++)
 		    for(int i = 0; i < regex.length;i++)
 		      clientline[x] = clientline[x].replaceAll(regex[i],newName[i]);
		}
		
		public static void renameClassVar(String className, String regex, String newName){
			   try{
    	      File file2 = new File(fileprefix+className);
            FileInputStream fi = new FileInputStream(file2);
            byte[] bytes = new byte[(int) file2.length()];
            fi.read(bytes);
            fi.close();
            String content = new String(bytes);
            content = content.replaceAll(regex, newName);
            FileOutputStream fos = new FileOutputStream(file2);
            fos.write(content.getBytes());
            fos.close();
         }
        catch(Exception e){
            e.printStackTrace();
        }
    }
    
    public static void renameClassVar(String className, String[] regex, String[] newName){
			   try{
    	      File file2 = new File(fileprefix+className);
            FileInputStream fi = new FileInputStream(file2);
            byte[] bytes = new byte[(int) file2.length()];
            fi.read(bytes);
            fi.close();
            String content = new String(bytes);
            for(int i = 0; i < regex.length;i++)
              content = content.replaceAll(regex[i], newName[i]);
            FileOutputStream fos = new FileOutputStream(file2);
            fos.write(content.getBytes());
            fos.close();
         }
        catch(Exception e){
            e.printStackTrace();
        }
    }
		
		public static void renamePubVar(String regex, String newName){
			renamePrivVar(regex, newName);
			File index = new File("./"+fileprefix);
		  String[] filet = index.list();
	  	for(int i = 0; i < filet.length;i++)
		    if(filet[i].trim().endsWith(".java") && (((filet[i].trim().indexOf("Class")>-1)||(filet[i].trim().indexOf("Sub")>-1))))
          renameClassVar(filet[i], regex, newName);
    }
    
    public static void renamePubVar(String[] regex, String[] newName){
    	if(regex.length!=newName.length)
				return;
			renamePrivVar(regex, newName);
			File index = new File("./"+fileprefix);
		  String[] filet = index.list();
	  	for(int i = 0; i < filet.length;i++)
		    if(filet[i].trim().endsWith(".java") && (((filet[i].trim().indexOf("Class")>-1)||(filet[i].trim().indexOf("Sub")>-1))))
          renameClassVar(filet[i], regex, newName);
    }
    
    public static void declareMethod(String nameParams){
    	for (int x=0;x<clientline.length&&clientline[x]!=null; x++)
    	  if ((clientline[x].indexOf("public client()")>-1))
				  clientline[x] = "public "+nameParams+"{ }\n"+clientline[x];
    }
  
	
	public static void main(String[] args)
	{
		String writetoscreen = "";
		try
		{
			File file = new File(fileprefix+"client.java");
			FileInputStream fistream = new FileInputStream(file);
			BufferedReader reader = new BufferedReader(new InputStreamReader(fistream));
		  int linenumber = 0;
			while ((clientline[linenumber] = reader.readLine()) != null)
			  linenumber++;
			fistream.close();
			
			for (int x=0;x<clientline.length&&clientline[x]!=null; x++)
			  if (clientline[x].indexOf("mapdots")>-1){
			//    System.out.println(clientline[x]);
			    String[] classnames = clientline[x].trim().split("\\s");
		//	    System.out.println(classnames[0]);
			    int aclassnum = Integer.parseInt(getRegexString("_\\d{1,4}",classnames[0]).substring(1));
			    String aclassname = classnames[0].substring(0,classnames[0].indexOf("_"+aclassnum)+1);
			    String[] dotNames = {"itemDot", "npcDot", "playerDot", "friendDot", "unknownDot"};
			    for (int t=0;t<5; t++)
			      renamePrivVar(aclassname+(aclassnum+t), dotNames[t]);
			    declareMethod("void ChangeColors()");
			    declareMethod("void ChangeBack()");
			    declareMethod("void updateColors()");
			    declareMethod("void updatePlayers(int otherPlyrLvl)");
			    aclassname = "dot";  
			    aclassnum = 0;
			    String intarraystring = "";
			    String wildyposclass = "";
//			    System.out.println(aclassnum);
//			    System.out.println(aclassname);
			//    System.out.println(getRegexString("_\\d{1,4}",classnames[0]).substring(1));
			 //   System.out.println(classnames[3].substring(0,classnames[3].indexOf("(")));
			    try{
			      File pkclass = new File(fileprefix+classnames[3].substring(0,classnames[3].indexOf("("))+".java");
			      FileInputStream fistreampkclass = new FileInputStream(pkclass);
		      	BufferedReader pkreader = new BufferedReader(new InputStreamReader(fistreampkclass));
		        String tempstring = "";
		       	while ((tempstring = pkreader.readLine()) != null){
		      	  if ((tempstring.indexOf("public int anIntArray")>-1)){
		      	  	String[] result = tempstring.trim().split("\\s");
		      	  	intarraystring = result[2].substring(0,result[2].indexOf("["));
		      	  	renamePubVar(intarraystring, "mapDotArray");
		      	  	intarraystring = "mapDotArray";
//		      	    System.out.println(intarraystring);
		      	  }
		        }
		      } catch(IOException e) { e.printStackTrace(); }
		      for (int i=0;i<clientline.length&&clientline[i]!=null; i++)
					  if ((clientline[i].indexOf(" (level-")>-1)&&(clientline[i].indexOf("aString")==-1)){
					  	      wildyposclass = getRegexString("aClass.{1,40}anInt\\d{1,4}",clientline[i]);
//                   System.out.println(wildyposclass.substring(0,wildyposclass.indexOf(".anInt")));
//                   System.out.println(wildyposclass.substring(wildyposclass.indexOf("anInt"),wildyposclass.length()));
// 	                  System.out.println(wildyposclass.substring(1).toLowerCase().replaceAll("_\\d{1,4}\\.anint\\d{1,4}",""));
 	                  renamePubVar(wildyposclass.substring(0,wildyposclass.indexOf(".anInt")),"myPlayer");
 	                  renamePrivVar(wildyposclass.substring(1).toLowerCase().replaceAll("_\\d{1,4}\\.anint\\d{1,4}",""),"otherPlayer");
 	                  renamePubVar(wildyposclass.substring(wildyposclass.indexOf("anInt"),wildyposclass.length()),"cmbtLvl");
 	                  i = clientline.length;
			    	}
		      for (int z=0;z<clientline.length&&clientline[z]!=null; z++)
		        if (clientline[z].indexOf("* 4 + 2) -")>-1){
		          for (int a=z;a>0;a--)
		            if (clientline[a].indexOf("public void method")>-1){
                  clientline[a+1] = clientline[a+1]+"\n    	  updateColors();";
		            	a = 0;
		            }
		          for (int a=z;a<clientline.length&&clientline[a]!=null; a++)
		            if(clientline[a].indexOf("otherPlayer")>-1){
		            	clientline[a]=clientline[a]+"\n    	  updatePlayers(otherPlayer.cmbtLvl);"; 
                a = clientline.length;
		            }
  z = clientline.length; 
	}
		      x = clientline.length;
		  }
			
for (int x=0;x<clientline.length&&clientline[x]!=null; x++)
  if (clientline[x].indexOf("\"%5\"")>-1){
  	clientline[x+4] = clientline[x+4]+"\n                            if(s.startsWith(\"Level:\"))\n"+
"                              wildypos = Integer.parseInt(s.substring(7));\n";
    x = clientline.length;
  }

	                for (int x=0;x<clientline.length&&clientline[x]!=null; x++)
				if(clientline[x].indexOf("getParameter(\"nodeid\")")>-1)
				{
					String[] result = clientline[x].trim().split("\\s");
					renamePrivVar(result[0],"nodeId");
				}

	                for (int x=0;x<clientline.length&&clientline[x]!=null; x++)
				if(clientline[x].indexOf("public Socket method")>-1)
				{
				//	String[] result = clientline[x].trim().split("\\s");
                       //       String methodname = result[2].substring(0,result[2].indexOf("int")-1);
				//	renamePrivVar(methodname,"socketMethod");
                              clientline[x+3] = "//"+clientline[x+3];
                              clientline[x+4] = "//"+clientline[x+4];
                              clientline[x+5] = "//"+clientline[x+5];                               
				}

Pattern pattern3 = Pattern.compile("if\\(super\\.anInt\\d{1,4} == 1 && super\\.anInt\\d{1,4} >= \\w{1,2} - 15 && super\\.anInt\\d{1,4} < \\w\\d?\\)");   	
for (int x=0;x<clientline.length&&clientline[x]!=null; x++){//adds world switcher
Matcher match2 = pattern3.matcher(clientline[x]);	
    if(match2.find()){
				clientline[x+5] = clientline[x+5]+"\n"+clientline[x]+"\n"+clientline[x+1].replace("0;","2;")+"\n"+clientline[x+2];
				String[] result = clientline[x+1].trim().split("\\s");
				for (int i=0;i<clientline.length&&clientline[i]!=null; i++)
				  if(clientline[i].indexOf("if("+result[0]+" == 1)")>-1){
					  String[] password = clientline[i+3].trim().split("\\s");
					  clientline[i+10] = clientline[i+10]+"else\nif("+result[0]+" == 2)\n";
					  for (int z=1;z<10;z++)
					    clientline[i+10] = ((clientline[i+10]+clientline[i+z]+"\n").replaceAll(password[0],"worldnum")).replaceAll("20\\)","3)");	
					    clientline[i+10] = clientline[i+10]+"}";
					  clientline[i+5] = clientline[i+5].replace("0;","2;");	
					  i = clientline.length;			    
			for (int y=0;y<clientline.length&&clientline[y]!=null; y++)
			  if(clientline[y].indexOf("Username: ")>-1){
			    clientline[y+3] = clientline[y+3]+"\n"+
			    clientline[y].replaceAll("aString\\d{1,4}","worldnum").replaceAll("Username","World #").replaceAll("== 0\\)","== 2\\)")+
			    "\n"+clientline[y+3];
			    y = clientline.length;
			  }	
			}
		  x = clientline.length;			
	  }
}
	
for (int x=0;x<clientline.length&&clientline[x]!=null; x++)//adds maplock
	if ((clientline[x].indexOf("/ 2 & 0x7ff;")>-1))
				{
				 String[] result = clientline[x].trim().split("\\s");
         int firstvariable = Integer.parseInt(result[0].replace("anInt",""));
				 clientline[x] = "if(maplock){\n"+
         "   anInt"+firstvariable+" = mapface;\n"+
         "   anInt"+(firstvariable-1)+" = 383;\n"+
         "   }else{\n"+clientline[x];
         clientline[x+1] = clientline[x+1]+"\n}";
				}
				
	try{			
		Pattern pattern = Pattern.compile("int \\w{1,2} = 2048 - \\w{1,2} & 0x7ff;"); //adds zoom and camera movement
    for (int x=0;x<clientline.length&&clientline[x]!=null; x++){	
     Matcher match = pattern.matcher(clientline[x]);
     if (match.find())
				{
					  String[] zoomvars = new String[3];
					  String[] result = clientline[x+2].trim().split("\\s");
				  	zoomvars[0]=result[1];	
			  		result = clientline[x+3].trim().split("\\s");
				  	zoomvars[1]=result[1];		
		  			result = clientline[x+4].trim().split("\\s");
				  	zoomvars[2]=result[1];			
						//insertzoomcrap
						clientline[x+14] = clientline[x+14]+"if(cameratoggle){\n"+  
            "	if(lftrit == 0)\n"+    
            "    lftrit = "+zoomvars[0]+";\n"+
            "	if(zoom == 0)\n"+      
            "    zoom = "+zoomvars[1]+";\n"+
            "  if(fwdbwd == 0)\n"+  
            "    fwdbwd = "+zoomvars[2]+";\n"+
            "  "+zoomvars[0]+" = lftrit;\n"+
            "  "+zoomvars[1]+" = zoom;\n"+
            "  "+zoomvars[2]+" = fwdbwd;\n"+
            "}";
            x = clientline.length; 
				}
}
			} catch(Exception e) { e.printStackTrace(); }
				
// 0x3f008edd disables frame check 
				
for (int x=0;x<clientline.length&&clientline[x]!=null; x++)	//fixes hp over heads
      if ((clientline[x].indexOf("* 30) /")>-1))
				{
					int anintnumber = 0;
					String currenthp = clientline[x].substring(clientline[x].indexOf("=")+1,clientline[x].indexOf("*")).trim()+")";
					String totalhp = clientline[x].substring(clientline[x].indexOf("/")+1,clientline[x].indexOf(";")).trim();
					Pattern pattern2 = Pattern.compile("anInt\\d+ - 3");
					Matcher match2 = pattern2.matcher(clientline[x+3]);	
					if (match2.find()){
					  String tempstring =(clientline[x+3].substring(match2.start(),match2.end()));
					  anintnumber = Integer.parseInt(tempstring.substring(tempstring.indexOf("anInt")+5,tempstring.indexOf(" - 3")));
					}
					for (int i=0;i<clientline.length&&clientline[i]!=null; i++){
					  if ((clientline[i].indexOf("Welcome to RuneScape")>-1))
			    	{
			    		Pattern xcoord = Pattern.compile("[a-z] / 2");
			    		Pattern ycoord1 = Pattern.compile(", [a-z],");
			    		Pattern ycoord2 = Pattern.compile(", [a-z]\\)");
			    		Pattern ycoord3 = Pattern.compile("\\([a-z],");
			    		Matcher ymatch1 = ycoord1.matcher(clientline[i]);
			    		Matcher ymatch2 = ycoord2.matcher(clientline[i]);
			    		Matcher ymatch3 = ycoord3.matcher(clientline[i]);
			    		String[]  aroundx = xcoord.split(clientline[i]);
				    	writetoscreen = aroundx[0]+"anInt"+(anintnumber-1)+aroundx[1];
				    	if (ymatch1.find()){
				    	aroundx = ycoord1.split(writetoscreen);
				    	writetoscreen = aroundx[0]+", "+"anInt"+anintnumber+"-9, "+aroundx[1];
				      }
				      if (ymatch2.find()){
				    	aroundx = ycoord2.split(writetoscreen);
				    	writetoscreen = aroundx[0]+", "+"anInt"+anintnumber+"-9)"+aroundx[1];
				      }
				      if (ymatch3.find()){
				    	aroundx = ycoord3.split(writetoscreen);
				    	writetoscreen = aroundx[0]+"("+"anInt"+anintnumber+"-9, "+aroundx[1];
				      }
				     writetoscreen = writetoscreen.replace("\"Welcome to RuneScape\"",currenthp+"+\"/\"+"+totalhp);
				     writetoscreen = writetoscreen.replace("0xffff00","0xFF0000");
			    	}
				  }
				  clientline[x] = "if(showhp)\n"+writetoscreen+"\n"+clientline[x];
				 x = clientline.length;
				}
		
for (int x=0;x<clientline.length&&clientline[x]!=null; x++){//changes names
			if ((clientline[x].indexOf("Welcome to RuneScape")>-1))
					clientline[x]= clientline[x].replace("RuneScape","MoparScape");
			if ((clientline[x].indexOf("New User")>-1))
					clientline[x]= clientline[x].replace("New User","Info");
		  if ((clientline[x].indexOf("Existing User")>-1)){
					clientline[x]= clientline[x].replace("Existing User","Play");
					clientline[x]= clientline[x].replace("0xffffff","0xFF0000");
				}
		  if ((clientline[x].indexOf("Login")>-1)){
					clientline[x]= clientline[x].replace("Login","Enter");
					clientline[x]= clientline[x].replace("0xffffff","0xFF0000");
				}
		 if ((clientline[x].indexOf("Cancel")>-1))
					clientline[x]= clientline[x].replace("Cancel","Quit");
		 if ((clientline[x].indexOf("Create a free account")>-1))
					clientline[x]= clientline[x].replace("Create a free account","This is MoparScape");
	 	 if ((clientline[x].indexOf("To create a new account you need to")>-1))
					clientline[x]= clientline[x].replace("To create a new account you need to","For help, more info, suggestions,");
		 if ((clientline[x].indexOf("go back to the main RuneScape webpage")>-1))
					clientline[x]= clientline[x].replace("go back to the main RuneScape webpage","or new versions, visit www.moparisthebest.com");
		 if ((clientline[x].indexOf("and choose the 'create account'")>-1))
					clientline[x]= clientline[x].replace("and choose the 'create account'","and my thread ask anything you want");
		 if ((clientline[x].indexOf("button near the top of that page.")>-1))
					clientline[x]= clientline[x].replace("button near the top of that page.","Have Fun. ~Moparisthebest");
		 if ((clientline[x].indexOf("RuneScape is loading - please wait...")>-1))
					clientline[x]= clientline[x].replace("RuneScape is loading - please wait...","MoparScape is loading - Hold onto your Butts...");
		 clientline[x] = clientline[x].replaceAll("if\\(aBoolean\\d{1,4} \\|\\| aBoolean\\d{1,4} \\|\\| aBoolean\\d{1,4}\\)","if\\(false\\)");
		 if(clientline[x].indexOf("/ 2 - 128")>-1)//removes logo
        clientline[x] = "//"+clientline[x];
     if(clientline[x].indexOf("extends Applet_Sub1")>-1)//adds variables
        clientline[x+1] = clientline[x+1]+"public static boolean showhp,cameratoggle,maplock;\n"+
	                     "public static int zoom,lftrit,fwdbwd,mapface,wildypos;\n";
	   if ((clientline[x].indexOf("jagex.com")>-1))
				clientline[x] = "flag = true;\n"+clientline[x];
     if ((clientline[x].indexOf("public client()")>-1))
				clientline[x] = "public static String worldnum = \"10\";\n"+clientline[x];
}
			FileOutputStream fos = new FileOutputStream(file);
			for (int x=0;x<clientline.length&&clientline[x]!=null; x++)
        fos.write((clientline[x]+"\n").getBytes());
      fos.close();
			
		} catch(IOException e) { e.printStackTrace(); }
	}
}

[code=java5]import java.lang.reflect.;
import java.io.
;

//getBadClass() by moparisthebest
//getVersion() by newbiehacker
public class getBCVer
{
public static String fileprefix = “output/”;

public static void main(String args[])
{
	if(args.length != 1){
	  System.out.println("args: .bat_file_name");
	  return;
	}
	
	writeToBat(args[0],getBadClass(),getVersion());

}

public static void writeToBat(String batFileName, String badClass, int version){
	   System.out.println("bad class: " + badClass + "\nclient version: " + version);
	   try{   
	      File file2 = new File(batFileName);
        FileInputStream fi = new FileInputStream(file2);
        byte[] bytes = new byte[(int) file2.length()];
        fi.read(bytes);
        fi.close();
        String content = new String(bytes);
        content = content.replaceAll("badclass=.*", "badclass=" + badClass);
        content = content.replaceAll("version=\\d*", "version=" + version);
        FileOutputStream fos = new FileOutputStream(file2);
        fos.write(content.getBytes());
        fos.close();
     } catch(Exception e){
        e.printStackTrace();
    }
}

public static String getBadClass(){
   String badclassname = "NotFound";
   int filecount = 0;
   try{
   	    String filename = "";
        File index = new File("./"+fileprefix);
        String[] files = index.list();
        for(int i = 0; i < files.length; i++){
            if(files[i].trim().endsWith(".java")){
                filename = files[i];
                    File file = new File(fileprefix+filename);
                    FileInputStream fistream2 = new FileInputStream(file);
                    byte[] bytes = new byte[(int) file.length()];
                    fistream2.read(bytes);
                    fistream2.close();
                    String content = new String(bytes);
                    if(content.contains("goto")){
                        badclassname = filename.substring(0, filename.length() - 5);
                        return badclassname;
                    }
                    filecount++;
            }
        }
    }
    catch(Exception e){
        e.printStackTrace();
    }
    return badclassname;
}

public static int getVersion(){
	 int clientversion = 0;
	 try{   
        Class signlink = Class.forName("sign.signlink");
        Field clientVersion = signlink.getDeclaredField("clientversion");
        clientVersion.setAccessible(true);
        clientversion = clientVersion.getInt(clientversion);
      } catch(Exception e){
        e.printStackTrace();
      }
    return clientversion;
}

}
[/code]

[code=java5]import java.io.*;
public class RandomRemover
{
static String tamafile = “”;
static int filecount;
public static String fileprefix = “output/”;
public static void main(String[] args)
{
//replacing Math.random() ----> /Math.randm()/0.5
System.out.println(“Replacing Math.random() with /Math.randm()/0.5”);
File index = new File("./"+fileprefix);
String[] filet = index.list();
boolean imagereplaced = false,chatremoved = false;
for(int i = 0; i < filet.length;i++)
{
//file alotetaan
if(filet[i].trim().endsWith(".java") && (((filet[i].trim().indexOf(“Class”)>-1)||(filet[i].trim().indexOf(“Sub”)>-1)) || (filet[i].trim().indexOf(“client.java”)>-1)) )
{
tamafile = filet[i];
try
{
File file = new File(fileprefix+tamafile);
FileInputStream fistream = new FileInputStream(file);
BufferedReader reader = new BufferedReader(new InputStreamReader(fistream));
File file2 = new File(fileprefix+tamafile+“a”);
FileOutputStream fos = new FileOutputStream(file2);
int replacecount = 0;
String fileline = “”;
String line = “”;
// FileOutputStream fos = new FileOutputStream(file);
while ((line = reader.readLine()) != null)
{
// System.out.println(line);
if (line.indexOf(“Math.random()”)>-1)
{
replacecount++;
line = line.replaceAll(“Math.random\(\)”,"/Math.randm()/0.5");
}

			if (line.indexOf("Image image =")>-1)
			{
				imagereplaced = true;
				line = "Image image = Toolkit.getDefaultToolkit().getImage(\"mopar.jpg\");";
			}
			
			if (line.indexOf("return (new String(ac)).trim();")>-1)
			{
				chatremoved = true;
				line = "return s;";
			}
			
			if (line.indexOf("\"Jagex\"")>-1)
			{
				line = line.replaceAll("\"Jagex\"","\"MoparScape\"");
			}
		//	fileline = fileline + "\n" + line;
			fos.write((line+"\n").getBytes());
		}
		System.out.println("Replaced "+replacecount+" times in "+tamafile);
//		FileOutputStream fos = new FileOutputStream(file);

// fos.write(contentout.getBytes());
fistream.close();
fos.close();
file.delete();
file2.renameTo(new File(fileprefix+tamafile));
// String line = “”;
// fos.write(fileline.getBytes());
filecount++;
} catch(IOException e) { e.printStackTrace(); }

	//file hoidettu
	}
	}
	System.out.println("Replace done in "+filecount+" files");
	if(imagereplaced)
		  System.out.println("Succesfuly replaced image");
		else
		  System.out.println("failed replacing image");
  if(chatremoved)
		  System.out.println("Succesfuly removed chat filter");
		else
		  System.out.println("failed removing chat filter");
}

}
[/code]

so what revision was mscp 2? was it still the whole 317 client loading a 349(?) cache deal?

Up until 4 they were all 317, probably loading the newest cache available at the time. (up to 377)