Project1
标题:
后台运行脚本切屏后游戏会卡死,怎么解决
[打印本页]
作者:
hy2000
时间:
2020-8-30 11:11
标题:
后台运行脚本切屏后游戏会卡死,怎么解决
#------------------------------------------------------------------------
# -----SixRC 2017.11.02
# 后台运行脚本 含失去焦点时屏蔽键盘鼠标功能
#
# 使用前请务必阅读此 否则脚本会失败
# 使用为 BGR.bgr(bool) true为开启 false关闭 默认true
# BGR.update为在窗口失去或获得焦点时对于是否屏蔽键盘鼠标的刷新
# 下面的注释那里把它放进了Graphics.update 请自行选择要不要这样
# 然后
# 因为这个脚本涉及到对具体dll的修改 不同的dll情况不同
# 下面是不同dll对应的地址 请在 45 行开始自行修改DLL名和偏移地址及第二部分大小
# 除DLL外需要修改三处地方 见下面 47 48 行
# RGSS103J 0x2E48 \x46
# RGSS102J 100J 0x2E09 \x46
# RGSS104E 0x4FA4 \x5F
# RGSS200J 200E 202E 0x19AA \x35
# RGSS300 301 0x2712 \x5A
#------------------------------------------------------------------------
module BGR
module_function
GetActiveWindow=Win32API.new('user32','GetActiveWindow','v','l')
Hwnd=GetActiveWindow.call
User32=Win32API.new('kernel32','LoadLibraryA','p','l').call("user32")
GetAsyncKeyState=Win32API.new('kernel32','GetProcAddress','lp','l').call(User32,'GetAsyncKeyState')
GetKeyState=Win32API.new('kernel32','GetProcAddress','lp','l').call(User32,'GetKeyState')
WriteProcessMemory=Win32API.new('kernel32','WriteProcessMemory','llpll','l')
Original="\0"*5
OriginalVA="\0"*5
Mask="\x31\xC0\xC2\x04\x00"
Win32API.new('kernel32','ReadProcessMemory','llpll','l').call(-1,GetAsyncKeyState,Original,5,0)
Win32API.new('kernel32','ReadProcessMemory','llpll','l').call(-1,GetKeyState,OriginalVA,5,0)
@state=0
def update
if @state==0 && Hwnd != GetActiveWindow.call
WriteProcessMemory.call(-1,GetAsyncKeyState,Mask,5,0) if $game_variables!=nil
WriteProcessMemory.call(-1,GetKeyState,Mask,5,0) if $game_variables!=nil
return @state=1
end
if @state==1 && Hwnd == GetActiveWindow.call
WriteProcessMemory.call(-1,GetAsyncKeyState,Original,5,0) #if $game_variables!=nil
WriteProcessMemory.call(-1,GetKeyState,OriginalVA,5,0) #if $game_variables!=nil
return @state=0
end
end
DLL=Win32API.new('kernel32','LoadLibrary','p','l').call('RGSS103J')
def bgr(x=true)
WriteProcessMemory.call(-1,DLL+0x2E48,"\0",1,0) if x
WriteProcessMemory.call(-1,DLL+0x2E48,"\x46",1,0) unless x
end
end
#整合进 Graphics.update 请选择性使用
class << Graphics
alias update_BGR update
def update
BGR.update #if $scene.is_a?(Scene_Map)
update_BGR
end
end
#使用
复制代码
这是SixRC大大写的后台运行脚本,但如果运行的话在游戏开始前切到别的窗口(如qq),回来后就会卡死无法行动。
我理解这是屏蔽了键盘后没有触发恢复导致的,尝试在上面加入一些条件;可以看到我加入了if $game_variables!=nil的条件,这样就不会在标题画面屏蔽,避免进游戏卡死。
但之后我又发现这么做后有时候在游戏内的下级窗口(比如开了一个合成窗口)后切屏截个图之类的又会卡死
感觉玩家游戏时还是有可能会切出去qq或者截屏的吧?这样直接卡死似乎对体验感很不好,感觉我这么堵不是个头,有没有什么更好的解决办法?
作者:
SixRC
时间:
2020-8-30 11:44
原因是用 GetActiveWindow 获取游戏句柄
假如游戏未打卡时切到别的窗口
读到的句柄就是错的 导致后续判断全错
这是偷懒时候的写法 确实有bug
[pre lang="ruby"]dll_name="RGSS103J"
DLL=Win32API.new('kernel32','GetModuleHandle','p','l').call(dll_name)
code = [139,68,36,4,139,128,196,182,18,0,139,64,8,194,16,0].pack('C*')
Hwnd = Win32API.new('user32.dll','CallWindowProc','pllll','l').call(code,DLL,0,0,0)[/pre]
你把取句柄的代码改成这段再测试一下
应该没问题了 别的你改的改回去吧..
现在不在家 这是猜的 有问题再说
欢迎光临 Project1 (https://rpg.blue/)
Powered by Discuz! X5.0