Configurable spam script

Post gaming related scripts
User avatar
evilC
Posts: 4823
Joined: 27 Feb 2014, 12:30

Configurable spam script

03 Feb 2015, 06:04

This script was borne from a discussion with Harry in IRC, but I quite liked the end solution, so I thought I would share.

What was required was a script that would spam the keys you were holding, with some conditions.

For example:
if you hold 1, it spams 1.
If you then hold a modifier without releasing 1, it spams <modifier>+1
if you release the modifier, it goes back to spamming 1.

He also wanted conditions, eg:
If I am holding Ctrl, and hit Q, I only want it to send Ctrl+Q once.
Releasing Q and re-hitting should allow another send of Ctrl+Q

How the code works:
At the start of the script is an array which configures the keys it watches for
key_list := ["1", "2", "3", "4", "5", "F1", "F2", "F3", "F4", "F5", "q", "g"]
Keys not in this list will not be spammed.

it then builds an "Associative Array" called keys, with one entry for each key, which is set to 0

so keys["q"] starts off as 0

It then declares some hotkeys for down and up events of each key, such that when a key is held, keys[<keyname>] is 1.

ie when Q is held, keys["q"] is 1, otherwise it is 0.

An endless loop is then kicked off, which constantly runs.
The endless loop cycles through all the keys like so: for key, value in keys

If keys[<key>] is 1, then that key is held.

A similar "Lookup array" is also present for the modifier keys, such that if CTRL is held, modifiers.Ctrl is 1. In this way, the code is able to build a list of modifiers for the send command - ie if modifiers.Ctrl is 1, but the rest are 0, the modifier string will be built as "^"


The "exceptions" system works thus:
If you wish to stop a key repeating, set keys_modifiers[<keyname>] to 1.
So to stop Ctrl+Q from repeating, if the code detects Q is hit with CTRL held, it sets keys_modifiers["q"] to 1

The keys_modifiers value for each key is set to 0 when that key is released.

Code: Select all

; To add a new key to the script, add it to this array:
key_list := ["1", "2", "3", "4", "5", "F1", "F2", "F3", "F4", "F5", "q", "g"]

; Init lookup array for modifiers
modifiers := {LAlt: 0, LShift: 0, LCtrl: 0}

; Build lookup array, declare hotkeys
keys := {}
keys_modded := {}
Loop % key_list.MaxIndex(){
	key := key_list[A_Index]
	; init array values
	keys[key] := 0
	keys_modded[key] := 0
	; Declare hotkeys for up and down events
	hotkey, $*%key%, keydown
	hotkey, $*%key% up, keyup
}

Loop {
	; Endless loop - always running
	for key, value in keys {
		; Loop through each of the keys
		if (value){
			; If the key is held...
			
			; Detect if any modifiers held
			if (modifiers.LAlt || modifiers.LCtrl || modifiers.LShift){
				modifier_held := 1
			} else {
				modifier_held := 0
			}
			
			if (key = "q" && modifiers.LCtrl){
				; Special case - CTRL + Q
				if (keys_modded[key]){
					; We already sent a modded version of this key, then ignore
					; keys_modded[key] will be set to 0 on up event of key
					continue
				} else {
					; We are going to send a modded version of this key, set keys_modded[key] to 1, so it ignores next time
					keys_modded[key] := 1
				}
			}
			
			if (key = "g" && modifier_held){
				; Special case - ANY modifier and g
				if (keys_modded[key]){
					continue
				} else {
					keys_modded[key] := 1
				}
			}

			; Build the list of modifiers to use for the send
			s := ""
			if (modifiers.LAlt){
				s .= "!"
			}
			if (modifiers.LShift){
				s .= "+"
			}
			if (modifiers.LCtrl){
				s .= "^"
			}
			
			; Send the key with the modifiers
			Send % s "{" key "}"
		}
	}
	Sleep 20
}

; Any of the "keys" (ie not modifiers) being pressed will call this
keydown:
	key := SubStr(A_ThisHotkey,3)
	keys[key] := 1
	return

; Any of the "keys" being released will call this
keyup:
	key := SubStr(A_ThisHotkey,3)
	; Remove " up" from end
	key := substr(key, 1, StrLen(key) - 3)
	keys[key] := 0
	keys_modded[key] := 0
	return

; Modifiers
$*LAlt::
$*LShift::
$*LCtrl::
	mod := substr(A_ThisHotkey, 3)
	modifiers[mod] := 1
	return

$*LAlt up::
$*LCtrl up::
$*LShift up::
	mod := substr(A_ThisHotkey, 3)
	; Remove " up" from end
	mod := substr(mod, 1, StrLen(mod) - 3)
	modifiers[mod] := 0
	return

; Quit script on Escape
Esc::
	ExitApp
[Update] 8th Feb - extra "z" at end of mod := substr(A_ThisHotkey, 3) removed, dunno how it got there :(
Last edited by evilC on 08 Feb 2015, 12:59, edited 3 times in total.
geek
Posts: 1052
Joined: 02 Oct 2013, 22:13
Location: GeekDude
Contact:

Re: Configurable spam script

03 Feb 2015, 09:25

I think the (more accurate) term is "Auto-Fire", not spam. Spam would imply the use is for flooding the in-game chat. Additionally, there is quite a bit of stigma around the word spam.
Last edited by geek on 04 Feb 2015, 12:05, edited 1 time in total.
Guest

Re: Configurable spam script

03 Feb 2015, 10:32

How could I add something with this effect http://ahk.us.to/?p=7cd39a to this http://ahk.uk.to/?p=80b113 without stopping it from working? Wherever I put it the whole thing stops working xD
User avatar
evilC
Posts: 4823
Joined: 27 Feb 2014, 12:30

Re: Configurable spam script

03 Feb 2015, 10:35

as soon as the code encounters a hotkey, it stops the "auto-execute" section.

so after a=0, no code will execute when the script starts

take a := 0 and put it at start of your script.
Put the rest at the end
Guest

Re: Configurable spam script

06 Feb 2015, 09:49

how do you add a special case of a key without modifiers? i tried this but it didn't work

if (key = "s" && !modifier_held){ ;
if (keys_modded[key]){
continue
} else {
keys_modded[key] := 1
}
}
Guest

Re: Configurable spam script

06 Feb 2015, 09:52

so like, if I'm holding shift-S it'll spam shift-S, but if i'm just holding S, it won't spam it, it'll just leave it down.
User avatar
evilC
Posts: 4823
Joined: 27 Feb 2014, 12:30

Re: Configurable spam script

06 Feb 2015, 10:05

Currently the script does not support "held", all key presses are "sends" (ie a down event immediately followed by an up event).

If you want it to only send s (down then up) once - it would cater for that, but holding s while you hold the key, and releasing it when you release the key is beyond the scope of the script as it stands.
Guest

Re: Configurable spam script

06 Feb 2015, 10:14

what if the key wasn't included in key_list, but mod+key were added as exceptions? is that possible?
User avatar
evilC
Posts: 4823
Joined: 27 Feb 2014, 12:30

Re: Configurable spam script

06 Feb 2015, 13:35

ff a key is not in key_list, the script will not interfere with it.

Certainly, if you hit a spam key or modifier while a key not in key_list is held, it will not spam it.

However, how that then affects the other keys is another matter - I do not know how a game might interpret that.

How does the game behave now in those various situation with the script as it stands?
Guest

Re: Configurable spam script

08 Feb 2015, 01:47

The game needs a key held down to walk backwards. If one key down is sent or spammed, the player just jerks on the spot. But if I exclude that key from key list, I can't have modifier+that key spammed.

I guess I could just run this in a separate script http://ahk.us.to/?p=fa3e72
Guest

Re: Configurable spam script

08 Feb 2015, 01:55

ok that doesn't work, the big script stops the little script
Guest

Re: Configurable spam script

08 Feb 2015, 04:09

another problem with this script is, it stops me using mod-key of keys that aren't in key list

for example alt-tab gets reduced to tab and alt-s gets reduced to s even tho neither tab nor s are in key list
User avatar
evilC
Posts: 4823
Joined: 27 Feb 2014, 12:30

Re: Configurable spam script

08 Feb 2015, 12:57

Guest wrote:another problem with this script is, it stops me using mod-key of keys that aren't in key list

for example alt-tab gets reduced to tab and alt-s gets reduced to s even tho neither tab nor s are in key list
change

Code: Select all

; Modifiers
$*LAlt::
$*LShift::
$*LCtrl::
    mod := substr(A_ThisHotkey, 3)
    modifiers[mod] := 1
    return

$*LAlt up::
$*LCtrl up::
$*LShift up::
    mod := substr(A_ThisHotkey, 3)
    ; Remove " up" from end
    mod := substr(mod, 1, StrLen(mod) - 3)
    modifiers[mod] := 0
    return
To

Code: Select all

; Modifiers
$~*LAlt::
$~*LShift::
$~*LCtrl::
    mod := substr(A_ThisHotkey, 4)
    modifiers[mod] := 1
    return

$~*LAlt up::
$~*LCtrl up::
$~*LShift up::
    mod := substr(A_ThisHotkey, 4)
    ; Remove " up" from end
    mod := substr(mod, 1, StrLen(mod) - 3)
    modifiers[mod] := 0
    return
Lemme know if it works, I will update the OP.
I also noticed that this line mod := substr(A_ThisHotkey, 3)had an extra "z" at the end, which was a typo.

Return to “Gaming Scripts (v1)”

Who is online

Users browsing this forum: No registered users and 25 guests