Results 1 to 3 of 3

Thread: Time Between Clicks for Alching. Script vs. Human

  1. #1
    Join Date
    Jun 2014
    Location
    Oklahoma
    Posts
    336
    Mentioned
    22 Post(s)
    Quoted
    231 Post(s)

    Default Time Between Clicks for Alching. Script vs. Human

    I was reminiscing about my time botting runescape the other day. It made me want to take a trip down memory lane. I was considering making a script, but I quickly remembered the effort involved and decided to not dedicate the time. My favorite part of making scripts was adding randomization to evade bans. After looking through some of my old scripts, I quickly realized how easy it to detect using simple statistics it would be. I did an experiment to show off how easy scripts could be to detect. I decided to focus on alching as it is very simple.

    Alching, you note the items and put them in that one inventory slot then you click in the same place over and over again. You know what I'm talking about. I bought 1000 nature runes, and 1000 maple long bows and I alched all of them by hand while I watched a movie. But I recorded all my mouse clicks using this python script.

    Code:
    from pynput.mouse import Listener
    import time
    import atexit
    
    
    file_name = f"click_data_{int(time.time())}.csv"
    output_file = open(file_name, mode="w")
    output_file.write("time,x,y\n")
    
    def exit_handler():
        output_file.close()
        print("Stopping. ")
    
    atexit.register(exit_handler)
    
    def on_click(x, y, button, pressed):
        if pressed:
            t = int(time.time() * 1000)
            print(t, x, y)
            output_file.write(f"{t},{x},{y}\n")
    
    
    with Listener(on_click=on_click) as listener:
        listener.join()
    This creates a .csv file with time in milliseconds, x coordinate, and y coordinate for each click you make. In total it took me 2411 clicks to finish. I did it in one sitting and I didn't take any breaks. Occasionally, I would click to fast and this would select the item I am alching (like when you are using an item on something). This would cause me to reopen the magic tab and start again. This caused extra clicks a few times. I attached the data if you want to look at it.

    When I scripted I would space out actions with random intervals of time using functions like randomRange(x,y) and gaussRangeInt(x, y) from SRL-6's math.simba. I did not entirely understand what these methods did at the time, but I do now. It's pulling a random number from a uniform and normal distribution respectively. But these distributions are far from human. They can also be picked up on quickly using statistical tests like this

    The basic idea is to compare the interval of time between my clicks with the interval of time between a script's clicks.

    Back when I would use bots, I commonly would use @fady's alching script to level up my magic. (I forget how to @mention). I simulated data from this script to compare to mine.

    Here is the basic components of his script, I removed most of it, but its enough to get the idea. Apparently I wrote the antiban function
    Code:
    procedure antiBan();             // Credit goes to Camel! Slight modification of the antiban in his Aircrafter.
    var
      i: integer;
    begin
      i := random(3000);
      if i < 70 then
      begin
        writeLn('Doing antiban');
        case i of
          1..4:  begin
                  writeLn('Taking Mini-break');
                  wait(gaussRangeInt(180000,300000));
                  if not isLoggedIn() then
                  begin
                    players[currentPlayer].login();
                    wait(gaussRangeInt(300,2000));
                    minimap.setAngle(MM_DIRECTION_NORTH);
                    mainscreen.setAngle(MS_ANGLE_HIGH);
                    closePollWindow();
                  end;
                 end;
          5..13: begin
                   hoverSkill(SKILL_MAGIC);
                   wait(gaussRangeInt(1500,5000));
                   gameTabs.openTab(TAB_BACKPACK);
                 end;
          14..16: mouseMovingObject();
          17..29: sleepAndMoveMouse(randomRange(3000,6000));
          30..40: begin
                    mouseOffClient(Random(4));
                    Wait(gaussRangeInt(10000,15000));
                  end;
          41..48: Wait(gaussRangeInt(2000,3000));
          49..70:begin
                   pickUpMouse();
                   wait(gaussRangeInt(1500,3000));
                 end;
        end;
        writeLn('Antiban Done, Resuming Alching');
        inc(a);
        initiate();
      end;
    end;
    
    procedure alch();
    begin
      tabBackPack.mouseSlot(slot, MOUSE_LEFT);
      wait(gaussRangeInt(100, 900));          //Waiting 0.1-0.9 seconds between clicks
      typeSend(players[currentPlayer].strings[0], false); 
      wait(gaussRangeInt(600, 1000));         // Waiting 0.6-1 second to repeat
    end;
    
    begin
        repeat
            antiBan();     
            alch();  
        until someCondition();
    end
    The typeSend uses a keybind that RS3 had to cast the spell I'm going to consider that a click. I recorded my data on OSRS. I don't think this really matters for what I'm trying to do. Here is some python code to generate data for the time between clicks similar to the script.

    Code:
    def gauss_range_int(min_i, max_i):
        mean = (max_i+min_i)/2.0;
        dev  = abs(max_i-min_i)/ 2.0 * 0.3 #* __gaussRange; # SRL-6 uses 0.3
        # didn't include hard bounding, doesn't matter much imo
        return round(random.gauss(mean, dev))
    
    
    # Simulate data for the time between clicks based on fady's script
    simulated_td = [] 
    for i in range(1200): 
        
        # Antiban
        r = random.randrange(0, 3000)
        wait_time = 0
        if r <= 4:
            pass # Remove the minibreak
        elif r <= 13:
            wait_time += gauss_range_int(1500, 5000) 
        elif r <= 16:
            pass # idk what to do here
        elif r <= 29:
            wait_time += random.randrange(3000, 6000)
        elif r <= 40:
            wait_time += gauss_range_int(10000, 15000) 
        elif r <= 48:
            wait_time += gauss_range_int(2000, 3000)
        elif r <= 70:
            wait_time += gauss_range_int(1500, 3000)
        
        wait_time += gauss_range_int(100, 900)
        simulated_td.append(wait_time)
        wait_time = gauss_range_int(600, 1000)
        simulated_td.append(wait_time)
    
    simulated_data = pd.Series(simulated_td)
    This simulation isn't perfect, but its close enough to what the script would have given you. Here is the histograms and plots of human data and the script's data.

    X Axis, is the click number. The human data is chronological. Y Axis is the milliseconds between each click.

    X Axis is the milliseconds between clicks, Y Axis is the count of observations. This approximates the distribution of the time between clicks.

    As you can see, they're quite different. Obivously the simulated data will be different each time as its generated randomly but the distribution will be roughly the same. The scripts distribution of time between clicks is much tighter. While mine is much wider, has a positive skew, and is borderline bimodal. It's certainly not normal or uniform. The antiban function appears to work well. It creates an occasional spike in time between clicks just like we see in my data. But these spikes make it hard to see the data, so I'm going to zoom in and crop them out. Here is the data zoomed in.



    The script data has a fairly consistent variance, while my data has a time varying variance. I had periods of time where I was clicking faster/slower, and being more/less consistent with my time between clicks.

    I also noticed that my time between clicks has dependency. Here is the ACF (auto correlation function) of the simulated data and my data. I increased the size of the simulated data to 100,000 for this.


    The Y axis is the autocorrelation. The X axis is the amount of lag in the series.

    My data had much more auto correlation than the scripts. This might just be a quirk of the way I click the mouse but quirks are human. There is quite a bit more stuff to look at. Perhaps I will edit this post with more content in the future there is a few ideas I'd like to try. But currently I'm tired of writing and I am going to go to bed. Hopefully someone finds this interesting.
    Attached Files Attached Files

  2. #2
    Join Date
    Feb 2012
    Location
    Norway
    Posts
    995
    Mentioned
    145 Post(s)
    Quoted
    596 Post(s)

    Default

    Thank you for taking the time to show people just how invariant these script usually, if not always are.

    All your plots lacks named axis'. This was mainly problematic when interpreting graph number 2.
    Last edited by slacky; 01-29-2023 at 12:28 PM.
    !No priv. messages please

  3. #3
    Join Date
    Dec 2011
    Location
    East Coast, USA
    Posts
    4,231
    Mentioned
    112 Post(s)
    Quoted
    1869 Post(s)

    Default

    Thanks for sharing! Mentions are like @username; with the semicolon required for the formatting to stick.
    GitLab projects | Simba 1.4 | Find me on IRC or Discord | ScapeRune scripts | Come play bot ScapeRune!

    <BenLand100> we're just in the transitional phase where society reclassifies guns as Badâ„¢ before everyone gets laser pistols

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
  •