faulty script (Realm of the Mad God)

Ask gaming related questions
river3945
Posts: 5
Joined: 05 May 2017, 14:58

faulty script (Realm of the Mad God)

05 May 2017, 15:14

Hi,

i have a AHK Script for the Game Realm of the Mad God.
There are two Issues i can't solve.

1. The say function sometimes "leaks" my previous clipboard.
example: i have something in clipboard like a youtube link and despite the fact that i check the clipboard if it contains the message it posts the youtube link instead of the message.

2. at somepoint i get weird behaviour like i didn't use a return correctly. i can't use the F keys and when i press ctrl+c it actually paste some of the script.
i can't find the place where i did something wrong.

Any Tips are greaty appreciated.

here is the script on pastebin: https://pastebin.com/GdXjGkWi

and here in code tag:

Code: Select all

#SingleInstance Force
#Persistent
#NoEnv
SetWorkingDir %A_ScriptDir%
SendMode Input
SetKeyDelay 0
SetMouseDelay 0
SetTitleMatchMode 3


GroupAdd rotmg, % "Realm of the Mad God"
GroupAdd rotmg, % "Realm of the Mad God - Google Chrome"




Loop
{
	Process, Exist, Realm of the Mad God.exe
	{
		If errorLevel
		{
			WinSet, Style, -0x40000, ahk_class ApolloRuntimeContentWindow
			WinMove, ahk_class ApolloRuntimeContentWindow,,,, 806, 629
		}
	}
	Sleep, 5000
}




#IfWinActive ahk_class Chrome_WidgetWin_1

^+a::
{
	Run, "C:\Users\<<USERNAME>>\Documents\Rotmg\Notepad++ Portable\Notepad++Portable.exe"
	Return
}

#IfWinActive




#IfWinActive ahk_group rotmg

F1::
{
	takeScreenshot()
	Return
}	
	
F3::
{
	sendChat("Heal Please")
	Return
}

F4::
{
	sendChat("Thanks!")
	Return
}

F5::
{
	InputBox, tradingmsg, Trading message, Please enter a trading message:,,,,,,,,%tradingmsg%
	keep_x_running = y

	Loop, 
	{
		ifWinActive Realm of the Mad God
		{
			If keep_x_running = y
			{
				sendChat(tradingmsg)
			}
			Else
			{
				Return
			}
		}
		Sleep, 1500
	}
	Return
}

F6::
{
	keep_x_running = n
	Return
}

F7::
{
	sendChat("/nexustutorial")
	Return
}

F8::
{
	sendChat("/tell mreyeball password")
	Return
}

F9::
{
	sendChat("/tell mreyeball stats")
	Return
}

F10::
{
	sendChat("/tell mreyeball lefttomax")
	Return
}

F11::
{
	sendChat("/tell mreyeball mates")
	Return
}

F12::
{
	sendChat("/tell mreyeball server")
	Return
}

^+S::
{
	Run, %A_ScriptDir%\MoveScreenshots.ahk
	Return
}

X::
{
	;swapItem(640,420) Slot 1
	;swapItem(680,420) Slot 2
	;swapItem(720,420) Slot 3
	swapItem(760,420) Slot 4
	Return
}


LAlt::
{
	takeScreenshot()
	Return
}

Numpad1::
{
	sendChat("ready")
	Return
}

NumpadEnd::
{
	sendChat("ready")
	Return
}

Numpad2::
{
	sendChat("He lives and reigns and conquers the world")
	Return
}

NumpadDown::
{
	sendChat("He lives and reigns and conquers the world")
	Return
}

+WheelUp::
{
	Send {PgUp}
	Return
}

+WheelDown::
{
	Send {PgDn}
	Return
}

XButton2::
{
	SendInput I
	Return
}
	
XButton1::
{
	swapItem(640,420)
	Return
}

MButton::
{
	SendInput N
	Return
}

SC028::
{
	SendInput ae
	Return
}

SC027::
{
	SendInput oe
	Return
}

SC01A::
{
	SendInput ue
	Return
}

+SC028::
{
	SendInput AE
	Return
}

+SC027::
{
	SendInput OE
	Return
}

+SC01A::
{
	SendInput UE
	Return
}

SC00C::
{
	SendInput ss
	Return
}




sendChat(Message)
{
	ClipSaved = %ClipboardAll%
	ClipWait
	Clipboard = %Message%
	ClipWait
	
	Loop,
		If Clipboard = %Message%
		{
			Blockinput, on
			Send {Enter}
			Send ^v
			Send {Enter}
			Blockinput, off
			Break
		}
		Sleep, 100
	
	Clipboard = %ClipSaved%	
	Return
}


takeScreenshot()
{
	IniRead, OutputVar, %A_ScriptDir%\<<ININAME>>.ini, <<INIVAR>>, Switch
	
	If (%OutputVar% == 0)
	{
		Run, "%A_ScriptDir%\Ifran View\i_view64.exe" /capture=2 /convert=C:\Users\<<USERNAME>>\Documents\Rotmg\Screenshots\Rotmg_$U(`%Y-`%m-`%d_`%H`%M`%S) %A_TickCount%.png
		Return
	}
	Else
	{
		Run, "%A_ScriptDir%\Ifran View\i_view64.exe" /capture=2 /convert=<<PATH>><<USERNAME>>\Screenshots\Rotmg_$U(`%Y-`%m-`%d_`%H`%M`%S) %A_TickCount%.png
		Return
	}
}


swapItem(xPos,yPos)
{
	MouseGetPos, mousePosX, mousePosY ; mousePosX/Y have old mouse position
	WinGetPos, , , winSizeX, winSizeY, Realm of the Mad God ; winSizeX/Y have window size
	BlockInput, on
	CoordMode, Mouse, Relative
	MouseMove, %xPos%, %yPos%
	SendEvent {Control Up}
	SendEvent {LButton Down}
	SendEvent {LButton Up}
	SendEvent {LButton Down}
	SendEvent {LButton Up}
	CoordMode, Mouse, Window
	MouseMove, mousePosX, mousePosY
	If (LB == "D") {
		Send {LButton down}
	}
	BlockInput, off
	Return
}

#IfWinActive
User avatar
Almost_there
Posts: 404
Joined: 30 Sep 2014, 10:32

Re: faulty script (Realm of the Mad God)

05 May 2017, 18:31

Well, the logic about your script I cannot say anything about because I doesn't know the game.

Here is my comments, hopefully some may help to identify the problem source.

Loop / Process
In my opinion it's bad practice to make an eternal loop like this because it will interact on other sub routines that takes some time to perform. I would rather have put that into a timer, and established a global variable so that the timer code won't run if a time consuming routine already runs.
tip: You don't have to use a block after Process.

F5
Could there be a case where the loop just runs forever? If it did, you probably wouldn't notice because most other hotkeys would seems to work as the code would be executed, but also goes back to that loop.
I haven't read your code that well, but it can be worth checking out. You may insert an message that pops up when A_index is getting large.

If keep_x_running = y
I have had experiences in the past where ahk have failed to executed the code properly unless I put parentheses around the comparison statement.

swapItem(760,420) Slot 4
Looks like you've missed the comment character here.

If (%OutputVar% == 0)
no need for percent enclosure here.

Your script last line is "#IfWinActive", not sure that will cause any differences in behavior of the script.
river3945
Posts: 5
Joined: 05 May 2017, 14:58

Re: faulty script (Realm of the Mad God)

06 May 2017, 07:20

Thanks for looking over my script.

- i changed the eternal loop to:

Code: Select all

SetTimer, WindowBorders, 5000
Return


WindowBorders:
	Process, Exist, Realm of the Mad God.exe
	If errorLevel
	{
		WinSet, Style, -0x40000, ahk_class ApolloRuntimeContentWindow
		WinMove, ahk_class ApolloRuntimeContentWindow,,,, 806, 629
	}
Return
the problem is that i have to close and then start game sometimes. i want to bordersizing option removed on the new instance aswell so i have to look periodically, i think. if settimer is better at this than loop then i will use this now.


- the f5 loop needs to run endlessly, iam not doing anything else at that point since iam trading items and just standing around. f6 will break the loop.
should i always use settimer over loop?

- i've added parentheses

- thank you very much for finding that error, i hope that this was the thing that made the script weird after a while.

- i removed the percent enclosure

- i always thought that you had to end #IfWinActive ... with #IfWinActive but you're right
pravdaglagol
Posts: 4
Joined: 05 May 2017, 12:22

Re: faulty script (Realm of the Mad God)

06 May 2017, 09:34

Would you try redefining your sendChat() function as follows?:

Code: Select all

sendChat(Message)
{
	Blockinput, on
	Send {Enter}%Message%{Enter}
	Sleep, 100
	Blockinput, off
	Return
}
Your function as it stands contains the ClipWait command which may explain why it malfunctions when you copy something to the clipboard manually.
The first ClipWait is waiting indefinitely for there to be something on the clipboard before moving to the next line.
river3945
Posts: 5
Joined: 05 May 2017, 14:58

Re: faulty script (Realm of the Mad God)

06 May 2017, 11:27

iam sorry but a solution with send is not working for me because its to slow.
in the game it takes like a second for longer strings to post which interferes with moving around.

i will try removing the clipwait command.
river3945
Posts: 5
Joined: 05 May 2017, 14:58

Re: faulty script (Realm of the Mad God)

06 May 2017, 12:15

so this is the current sendChat function:

Code: Select all

sendChat(Message)
{
	ClipSaved = %ClipboardAll%
	Clipboard = %Message%
	
	Loop,
		if (Clipboard == Message)
		{
			Blockinput, on
			Send {Enter}
			Send ^v
			Send {Enter}
			Blockinput, off
			Break
		}
		Sleep, 100
	
	Clipboard = %ClipSaved%	
	Return
}
what i still dont get is that it when the game is having a high cpu load the previous clipboard is sometimes pasted.
but i check with if (Clipboard == Message) the content of the clipboard before so how is that possible?
pravdaglagol
Posts: 4
Joined: 05 May 2017, 12:22

Re: faulty script (Realm of the Mad God)

06 May 2017, 13:42

Man, that's a good question.

Here's what I've been playing with:

Code: Select all

#Persistent
#NoEnv  ; Recommended for performance and compatibility with future AutoHotkey releases.
#SingleInstance force
SendMode Input  ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir%  ; Ensures a consistent starting directory.

chatmsg = Four score and seven years ago.

f1::
sendChat(chatmsg)
return

f2::
sendChat2(chatmsg)
return

sendChat(Message)
{
	ClipSaved := Clipboard
	Clipboard := Message
	Sleep 20
	Send {Enter}^v{Enter}
	Sleep 20
	Clipboard := ClipSaved
Return
}

sendChat2(Message)
{
	ClipSaved := Clipboard
	Clipboard := Message
	Send {Enter}^v{Enter}
	Clipboard := ClipSaved
Return
}
Now take what I have there, open a notepad and hold down F1. Then try F2.

I think that's indeed your problem in a nutshell.

The only related commentary I find in the help file is on the OnClipboardChange page under Remarks where it says:
If the clipboard changes while an OnClipboardChange label or function is already running, that notification event is lost. If this is undesirable, specify Critical as the label's first line. However, this will also buffer/defer other threads (such as the press of a hotkey) that occur while the OnClipboardChange thread is running.

If the script itself changes the clipboard, its OnClipboardChange label or functions are typically not executed immediately; that is, commands immediately below the command that changed the clipboard are likely to execute beforehand. To force the label or functions to execute immediately, use a short delay such as Sleep 20 after changing the clipboard.
Perhaps storing the clipboard before the function call would force it to process in the correct order.
river3945
Posts: 5
Joined: 05 May 2017, 14:58

Re: faulty script (Realm of the Mad God)

06 May 2017, 14:29

thank you pravdaglagol and Almost_there for taking the time! :thumbup: <3

iam using this now as the sayscript:

Code: Select all

sendChat(Message)
{
	ClipSaved := Clipboard
	Clipboard := Message
	Sleep 150
	Send {Enter}^v{Enter}
	Sleep 150
	Clipboard := ClipSaved
	Return
}
and it works great. i spammed say binds and no leaking so far. it did still sometimes leak at Sleep 20 so i upped it to a point where it is still ok for me. i've made an extra sendChat for trading with Sleep 250.

Return to “Gaming”

Who is online

Users browsing this forum: No registered users and 18 guests