找回密码
 注册/Sign up
搜索
查看: 5762|回复: 8

[LUA]稍微降低CPU使用率的LUA

[复制链接]
发表于 2021-8-11 18:49:15 | 显示全部楼层 |阅读模式
本帖最后由 muscipular 于 2021-8-11 18:50 编辑

单机发现cgmsv占cpu挺多的。写了个脚本降低cpu使用率, 基本约等于0, 只支持cgmsv_21.2a windows版
  1. local ffi = require "ffi";
  2. local hook = { hooks = {} }
  3. ffi.cdef [[
  4.     void Sleep(int ms);
  5.     int VirtualProtect(void* lpAddress, unsigned long dwSize, unsigned long flNewProtect, unsigned long* lpflOldProtect);
  6. ]]
  7. function hook.inlineHook(cast, callback, hookAddr, size, prefixCode, postCode)
  8.   local callbackAddr = type(callback) == 'function' and tonumber(ffi.cast('intptr_t', ffi.cast('void*', ffi.cast(cast, callback)))) or 0;
  9.   if type(callback) ~= 'function' and callback then
  10.     callbackAddr = callback;
  11.   end
  12.   local hookFnPtr = ffi.cast('void*', hookAddr)
  13.   local oldProtectFlag = ffi.new('unsigned long[1]')
  14.   local tmpProtectFlag = ffi.new('unsigned long[1]')
  15.   local detourBytes = ffi.new('uint8_t[?]', 2048)
  16.   local backup = ffi.new('uint8_t[?]', size)
  17.   -- make backup
  18.   ffi.copy(backup, hookFnPtr, size);
  19.   -- prefixCode
  20.   for i, v in ipairs(prefixCode) do
  21.     detourBytes[i - 1] = v;
  22.   end
  23.   --call callback
  24.   if callback then
  25.     detourBytes[#prefixCode] = 0xE8;
  26.     ffi.cast('uint32_t*', detourBytes + #prefixCode + 1)[0] = callbackAddr - (ffi.cast('uint32_t', detourBytes) + #prefixCode + 5);
  27.   else
  28.     detourBytes[#prefixCode] = 0x90;
  29.     detourBytes[#prefixCode + 1] = 0x90;
  30.     detourBytes[#prefixCode + 2] = 0x90;
  31.     detourBytes[#prefixCode + 3] = 0x90;
  32.     detourBytes[#prefixCode + 4] = 0x90;
  33.   end
  34.   -- prefixCode
  35.   for i, v in ipairs(postCode) do
  36.     detourBytes[i - 1 + 5 + #prefixCode] = v;
  37.   end
  38.   --origin code
  39.   ffi.copy(detourBytes + #prefixCode + 5 + #postCode, hookFnPtr, size);
  40.   --jmp to origin code
  41.   detourBytes[#prefixCode + 5 + size + #postCode] = 0xE9;
  42.   ffi.cast('int32_t*', detourBytes + #prefixCode + 5 + size + #postCode + 1)[0] = ffi.cast('int32_t', (hookAddr + size) - (ffi.cast('int32_t', detourBytes) + size + #postCode + #prefixCode + 10));
  43.   --mark memory executable
  44.   ffi.C.VirtualProtect(detourBytes, 2048, 0x40, tmpProtectFlag);
  45.   --mark memory writable
  46.   ffi.C.VirtualProtect(hookFnPtr, size, 0x40, oldProtectFlag)
  47.   --jmp to hook code
  48.   ffi.cast('uint8_t*', hookAddr)[0] = 0xE9;
  49.   ffi.cast('uint32_t*', hookAddr + 1)[0] = ffi.cast('uint32_t', detourBytes) - (hookAddr + 5);
  50.   for i = 5, size - 1 do
  51.     ffi.cast('uint8_t*', hookAddr + i)[0] = 0x90;
  52.   end
  53.   --restore memory protect
  54.   ffi.C.VirtualProtect(hookFnPtr, size, oldProtectFlag[0], tmpProtectFlag)
  55.   local new_hook = {}
  56.   new_hook.uninstall = function()
  57.     ffi.C.VirtualProtect(hookFnPtr, size, 0x40, oldProtectFlag)
  58.     ffi.copy(hookFnPtr, backup, size)
  59.     ffi.C.VirtualProtect(hookFnPtr, size, oldProtectFlag[0], tmpProtectFlag)
  60.     hook.hooks[tostring(hookAddr)] = nil;
  61.   end
  62.   new_hook.detourBytes = detourBytes;
  63.   new_hook.backup = backup;
  64.   new_hook.callback = callback;
  65.   hook.hooks[tostring(hookAddr)] = new_hook;
  66.   return new_hook;
  67. end
  68. ffi.hook = hook;
  69. local val = 100; --延迟时间,单位毫秒,最大127,不能少于0
  70. ffi.hook.inlineHook('nil', ffi.cast('uint32_t', ffi.cast('void*', ffi.C.Sleep)), 0x004013DD, 5, { 0x6A, val }, { })
  71. ffi.hook.inlineHook('nil', ffi.cast('uint32_t', ffi.cast('void*', ffi.C.Sleep)), 0x00420C5F, 7, { 0x6A, val }, { })
  72. ffi.hook.inlineHook('nil', ffi.cast('uint32_t', ffi.cast('void*', ffi.C.Sleep)), 0x00425337, 7, { 0x6A, val }, { })
  73. ffi.hook.inlineHook('nil', ffi.cast('uint32_t', ffi.cast('void*', ffi.C.Sleep)), 0x004EB3EA, 5, { 0x6A, val }, { })
复制代码




补充内容 (2021-8-11 18:56):
PS:不要重复加载,不然可能崩端
PS2:不建议用在多人服务器上,否则可能延迟比较大,或者手动修改延迟降低一下

补充内容 (2021-9-27 11:49):
已整合至 http://bbs.cgmsv.com/thread-1036-1-1.html

评分

参与人数 1金币 +2 收起 理由
Zack + 2 原创技术贴

查看全部评分

发表于 2021-8-13 00:44:51 | 显示全部楼层
感谢分享.正常情况下,启动时会生成随机迷宫导致负载过高,10分钟后一般都会回复正常.

发表于 2021-8-14 19:50:27 | 显示全部楼层
如果只是單機測試其他功能屏蔽迷宮也是一解決方案

发表于 2021-8-27 19:16:59 | 显示全部楼层
小白问下楼主这个要怎么使用,复制代码到某个文件里还是新建一个文档粘贴进去?
 楼主| 发表于 2021-8-28 09:44:45 | 显示全部楼层
寂静之岚 发表于 2021-8-27 19:16
小白问下楼主这个要怎么使用,复制代码到某个文件里还是新建一个文档粘贴进去? ...

可以直接加载,参考其他lua模块

发表于 2021-8-29 23:47:06 | 显示全部楼层
本帖最后由 maixu0 于 2021-8-29 23:49 编辑

不建议用在多人服务器上,否则可能延迟比较大,或者手动修改延迟降低一下


这里的“多人服务器”指的是什么意思?只有一个人玩才可以吗?
 楼主| 发表于 2021-8-30 00:13:36 | 显示全部楼层
maixu0 发表于 2021-8-29 23:47
不建议用在多人服务器上,否则可能延迟比较大,或者手动修改延迟降低一下

少于10人估计没问题,专业开服的用不上这个

发表于 2021-9-1 16:26:16 | 显示全部楼层
我愣是没看懂你写的是啥

发表于 2021-9-1 17:00:29 | 显示全部楼层
放在这个路径里gmsv\lua\Module,亲测有效
您需要登录后才可以回帖 登录 | 注册/Sign up

本版积分规则

手机版|cgmsv引擎论坛

GMT+8, 2026-6-5 09:08 , Processed in 0.032514 second(s), 5 queries , Gzip On, Redis On.

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表