Results 1 to 13 of 13

Thread: [HELP] int array comparison

  1. #1
    Join Date
    Jan 2012
    Posts
    1,104
    Mentioned
    18 Post(s)
    Quoted
    211 Post(s)

    Default [HELP] int array comparison

    I am trying to make a game settings debug for my java client.

    I have a method called getSettingArray() which gets all the game setting values in an array. The method getSpecial() uses the prevous method and returns a number from that array.

    I have fields for storing the previous values and I compare them to the current values in the canvas paint loop (called very often). So basically when a game setting value changes it should write it out on the console.


    fields in the class
    Code:
    private int[] settings;
    private int spec;
    code in the canvas paint method
    Code:
    //FIRST PART: int comparison
    int currentSpec = Reflection.getSpecial();
    if (currentSpec != 0 && spec != 0) {
    	if (currentSpec != spec) {
    		System.out.println(String.format("Spec %d changed to %d", spec, currentSpec));
    }
    } 
    spec = currentSpec;
    
    
    
    //SECOND PART: array comparison
    int[] currentSettings = Reflection.getSettingArray();	
    if (currentSettings != null && settings != null) {
    	for (int i=0; i<currentSettings.length; i++) {
    		if (currentSettings[i] != settings[i]) {
    			System.out.println(String.format("Settings[%d] %d changed to %d", i, settings[i], currentSettings[i]));
    		}
    	}
    } 
    settings = currentSettings;
    The problem is when I use a weapon special (special attack value changes, game setting value changes), it writes it out with first syso, but not with the second one. The array comparison doesnt work.

    Any ideas?
    Last edited by Shatterhand; 10-22-2014 at 10:04 AM.

  2. #2
    Join Date
    Sep 2012
    Location
    Netherlands
    Posts
    2,752
    Mentioned
    193 Post(s)
    Quoted
    1468 Post(s)

    Default

    just debug it so you know whats going on
    Code:
    if (currentSettings[i] != settings[i])
           System.out.println(String.format("Settings[%d] %d changed to %d", i, settings[i], currentSettings[i]));
    else 
            System.out.println("settings[" + I + "]: " + Settings[I] + "     currentSettings[" + I + "]: " + currentSettings[I]);
    @Shatterhand;

    ps: new to java so idk if this is correct

  3. #3
    Join Date
    Jan 2012
    Posts
    1,104
    Mentioned
    18 Post(s)
    Quoted
    211 Post(s)

    Default

    Quote Originally Posted by hoodz View Post
    just debug it so you know whats going on
    Code:
    if (currentSettings[i] != settings[i])
           System.out.println(String.format("Settings[%d] %d changed to %d", i, settings[i], currentSettings[i]));
    else 
            System.out.println("settings[" + I + "]: " + Settings[I] + "     currentSettings[" + I + "]: " + currentSettings[I]);
    @Shatterhand;

    ps: new to java so idk if this is correct
    Tried that, changing the != to == in the condition, which does the same as yours, and it listed everything.

  4. #4
    Join Date
    Sep 2012
    Location
    Netherlands
    Posts
    2,752
    Mentioned
    193 Post(s)
    Quoted
    1468 Post(s)

    Default

    Quote Originally Posted by Shatterhand View Post
    Tried that, changing the != to == in the condition, which does the same as yours, and it listed everything.
    maybe try <> ? idk if it has any impact on in but you could try it

  5. #5
    Join Date
    Jan 2012
    Posts
    1,104
    Mentioned
    18 Post(s)
    Quoted
    211 Post(s)

    Default

    Quote Originally Posted by hoodz View Post
    maybe try <> ? idk if it has any impact on in but you could try it
    Nah thats correct in java, I am pretty sure the problem is somewhere else.

  6. #6
    Join Date
    Feb 2011
    Location
    The Future.
    Posts
    5,600
    Mentioned
    396 Post(s)
    Quoted
    1598 Post(s)

    Default

    Quote Originally Posted by Shatterhand View Post
    ...
    Are the two arrays guaranteed to be the same size? Are they always in the exact same order?

    If they any of the above cases are false then the correct way to compare them would be to use a nested loop.

    You need to define "doesn't work" and "doesn't write with the second".. explain what you mean by this. I don't understand what doesn't work here.
    I am Ggzz..
    Hackintosher

  7. #7
    Join Date
    Jan 2012
    Posts
    1,104
    Mentioned
    18 Post(s)
    Quoted
    211 Post(s)

    Default

    Quote Originally Posted by Brandon View Post
    Are the two arrays guaranteed to be the same size? Are they always in the exact same order?

    If they any of the above cases are false then the correct way to compare them would be to use a nested loop.

    You need to define "doesn't work" and "doesn't write with the second".. explain what you mean by this. I don't understand what doesn't work here.
    @Brandon
    Code:
    settings = currentSettings;
    Because of this, the array sizes are equal. The order is the same, I do not touch the field settings anywhere else.


    When a game setting (for example special attack) changes, the second part, the array comparison should write it out with the System.out.println(), but it doesnt do it. The first part, the int comparison is there just to show that it actually works.

    It writes out "Spec 100 changed to 75" but it doesnt write out "Settings[300] 1000 changed to 750"

    Note: special attack percent is settings[300]/10.

    I am thinking about some kind of timing problem here, it is currently in the canvas paint method, but I also tried out putting it in a separate thread and wait 1000ms between two loops.
    Last edited by Shatterhand; 10-22-2014 at 10:03 AM.

  8. #8
    Join Date
    Feb 2011
    Location
    The Future.
    Posts
    5,600
    Mentioned
    396 Post(s)
    Quoted
    1598 Post(s)

    Default

    Quote Originally Posted by Shatterhand View Post
    ...
    Replace it with this and tell us the output:

    Java Code:
    int[] currentSettings = Reflection.getSettingArray();
       
    if (currentSettings != null && settings != null) {
        for (int i = 0; i < settings.length; ++i) {
            if (currentSettings[i] != settings[i]) {
                System.out.println("Settings[" + i + "] " + settings[i] + " changed to " + currentSettings[i]));
            }
        }

        System.out.println("Canvas Report -- Settings Length: " + settings.length);
    }
    else {
        System.out.println("Settings or Current-Settings is NULL");
    }
     
    settings = currentSettings;


    Then after getting the output for that, do this one as well and paste the output here too:
    Java Code:
    int[] currentSettings = Reflection.getSettingArray();
       
    if (currentSettings != null && settings != null) {
        for (int i = 0; i < settings.length; ++i) {
            System.out.println("Settings[" + i + "] " + currentSettings[i]));
        }

        System.out.println("Canvas Report -- Settings Length: " + settings.length);
    }
    else {
        System.out.println("Settings or Current-Settings is NULL");
    }
     
    settings = currentSettings;
    Last edited by Brandon; 10-22-2014 at 02:15 PM.
    I am Ggzz..
    Hackintosher

  9. #9
    Join Date
    Jan 2012
    Posts
    1,104
    Mentioned
    18 Post(s)
    Quoted
    211 Post(s)

    Default

    Quote Originally Posted by Brandon View Post
    ...
    First one:
    Code:
    Canvas Report -- Settings Length: 2000
    Canvas Report -- Settings Length: 2000
    Canvas Report -- Settings Length: 2000
    Canvas Report -- Settings Length: 2000
    Canvas Report -- Settings Length: 2000
    Canvas Report -- Settings Length: 2000
    Canvas Report -- Settings Length: 2000
    Changed the special attack, then copied all the lines into notepad, didnt find a different line.

    Second one:
    http://pastebin.com/AmbDEa8L
    It generated 180k lines in a few second. I made sure to change my special attack value in this time. I searched for the part where it changed from 600 to 350, I only pasted that to pastebin. Its Settings[300].

    I counted all the Settings[300] occurrences, it was 409 total. 304 times with value 350 and 105 times with value 600, so everything looks fine.
    Last edited by Shatterhand; 10-22-2014 at 03:48 PM.

  10. #10
    Join Date
    Feb 2011
    Location
    The Future.
    Posts
    5,600
    Mentioned
    396 Post(s)
    Quoted
    1598 Post(s)

    Default

    Quote Originally Posted by Shatterhand View Post
    ...

    Weird.. -_-.. What does the output for this print:

    Java Code:
    int[] currentSettings = Reflection.getSettingArray();
       
    if (currentSettings != null && settings != null) {
        for (int i = 0; i < settings.length; ++i) {
            System.out.println("Settings[" + i + "] --> " + currentSettings[i] + "  " + settings[i]);
        }
    }
    settings = currentSettings;

    If it prints that they are equal then you might have a bug in your JVM.. I want to see the output of this. Perhaps even the settings array implementation. PM if it cannot be made public.

    What you could also try is to compare using subtraction or negation or even bit comparisons..

    Try something like:

    Java Code:
    int[] currentSettings = Reflection.getSettingArray();
       
    if (currentSettings != null && settings != null) {
        for (int i = 0; i < settings.length; ++i) {
            if ((currentSettings[i] - settings[i]) == 0) { //or  ((currentSettings[i] ^ settings[i]) == 0)
                System.out.println("Settings[" + i + "] changed from: " + currentSettings[i] + " to: " + settings[i]);
            }
        }
    }
    settings = currentSettings;
    Last edited by Brandon; 10-23-2014 at 02:44 AM.
    I am Ggzz..
    Hackintosher

  11. #11
    Join Date
    Jan 2012
    Posts
    1,104
    Mentioned
    18 Post(s)
    Quoted
    211 Post(s)

    Default

    Quote Originally Posted by Brandon View Post
    ...
    First one: http://pastebin.com/SP444gvP
    1000 1000
    750 750

    The second and third one does the same, it only writes out the equals, I even tried changing == to != but then nothing happened.

    Code:
    public static int[] getSettingArray() throws ClassCastException {
    	return (int[]) getClassFieldObject(Hooks.client_settings.split("\\.")[0], Hooks.client_settings.split("\\.")[1], null);
    }   
    
    public static Object getClassFieldObject(String className, String fieldName, Object object) {
    	if (!enabled) {
    		return null;
    	}
    	try {
    		ClassLoader cl = Main.frame.getClient().getApplet().getClass().getClassLoader();
    		Field field = cl.loadClass(className).getDeclaredField(fieldName);
    		field.setAccessible(true);
    		return field.get(object);
    	} catch (Exception ex) {
    		//ex.printStackTrace();
    	}
    	return null;
    }

  12. #12
    Join Date
    Feb 2011
    Location
    The Future.
    Posts
    5,600
    Mentioned
    396 Post(s)
    Quoted
    1598 Post(s)

    Default

    Quote Originally Posted by Shatterhand View Post
    First one: http://pastebin.com/SP444gvP
    1000 1000
    750 750
    Nice. That confirms it. Took this long to actually realise what was happening (wasn't sure if the client modified the existing array or not)..

    Problem: The assignment does not clone the array. Changes made to one is made to the other automatically. Basically, what you have is an atomic reference. Remember that even though it's an array of primitive, assignments are always referenced. As shown here..

    Java Code:
    package test;

    import java.lang.reflect.Field;

    public class Test {
        static int[] test = {1, 2, 3, 4};
       
        public static void main(String[] args) {
            int[] arr = (int[])getClassFieldObject("test.Test", "test", null);
           
            test[2] = 5; //change the value in one array, it changes in both..
           
            for (int i = 0; i < arr.length; ++i) {
                if (arr[i] != test[i]) //comparison fails because both arrays contain the same information.
                    System.out.println(arr[i]);
            }
        }
    }


    Now compare the above to:

    Java Code:
    static int[] test = {1, 2, 3, 4};
       
        public static void main(String[] args) {
            int[] arr = (int[])getClassFieldObject("test.Test", "test", null);
           
            test = new int[]{1, 2, 3, 5}; //still only one value change but it does not affect the other array.
           
            for (int i = 0; i < arr.length; ++i) {
                if (arr[i] != test[i]) //comparison succeeds because they are two different arrays now..
                    System.out.println(arr[i]);
            }
        }


    I know this is a reference problem because that's what your assignment operator does: settings = currentSettings; does not copy the array like you think it would. It simply takes the address of it, store it and increases the array's reference count.

    You can tell this is happening because no matter how many times you change your spec, the settings array always has the same value as the currentSettings array.. and so the comparison fails. Jagex does not create a new array.. rather they just modify the already existing static one and the changes are also done to your array as well..

    As to why it fails when you use "==", that I'm not sure of as it does not happen in the above example.. It should not fail with both "!=" and "==". That can't be. It's either one or the other. Could always be that the compiler optimised out the for-loop after realising you're doing self comparison but I highly doubt that..


    Try cloning/copying the array instead and see if it works. (Ex: settings = currentSettings.clone()).
    Last edited by Brandon; 10-23-2014 at 02:53 PM.
    I am Ggzz..
    Hackintosher

  13. #13
    Join Date
    Jan 2012
    Posts
    1,104
    Mentioned
    18 Post(s)
    Quoted
    211 Post(s)

    Default

    Quote Originally Posted by Brandon View Post
    ...
    @Brandon
    Code:
    settings = currentSettings.clone();
    Cloning actually worked. The reason I didnt think of this because I already though about this reference problem and I made a fast test with this code and it didtn work that time. But now it works too, weird.
    Code:
    for (int i=0; i<currentSettings.length; i++) {
    	    settings[i] = currentSettings[i];
    }
    Anyways thank you for your help, your time and patience. I can also thank you for having this client, without your tutorial I could not do it.

Thread Information

Users Browsing this Thread

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

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •