开服主机32/月起点击投放广告百度网盘18/月
服务器88元/月起点击投放广告点击投放广告
123下一页
返回列表 发布新帖
查看: 593|回复: 44

[教程] DOF攻城镶嵌教程

739

主题

31

回帖

2万

积分

管理员

黄金
22
银两
1038699
金币
21570 个

耳熟能详TGL尊享TGL亲王TGL龙年限定

发表于 2022-9-9 08:03:09 | 显示全部楼层 |阅读模式
  1. LD_PRELOAD=/bin/unvtce.so ./df_game_r siroco11 start &
复制代码
上面加入到RUN里面即可。但是要搭配DP使用。


然后bin目录自创文件。代码我按照顺序去写直接复制就好。
fuccaic.c

unvtce.config

unvtce.so

  1. /*
  2. 读写任意内存: js通过NativePointer类可以操作内存, 除了读写内存该类提供了很多实用的接口, 包括修改内存保护属性, 特征码搜索, 从内存中读取字符串等.

  3. hook任意函数: js通过Interceptor.attach接口可以实现对汇编的hook. 使用该接口时不必考虑32位或者64位程序, 也不必考虑被hook函数的调用约定, 甚至可以在函数内部进行hook.

  4. 通过Interceptor.attach可以拿到函数的入参和返回值, 并可以对函数返回值进行修改.

  5. 此外还可以使用更高级的Interceptor.replace接口, 该接口可以重写被hook的函数, 彻底改变程序执行流程.

  6. 执行任意函数: js通过NativeFunction类, 可以在js脚本内执行游戏进程内的所有C函数.

  7. 整数用readInt()读  utf8字符串用readUtf8String(-1)读 utf16用readUtf16String(-1)读

  8. linux平台: 修改run脚本, 添加LD_PRELOAD启动df_game_r, 即:
  9. LD_PRELOAD=./frida-gadget-12.11.13-linux-x86.so ./df_game_r siroco11 start &

  10. windows平台, 将frida-gadget-15.1.27-windows-x86.dll放到游戏目录下, 使用补丁大合集自带的注入dll功能在游戏进程启动时注入

  11. frida 官网地址: https://frida.re

  12. frida提供的js api接口文档地址: https://frida.re/docs/javascript-api/

  13. linux平台下载地址:https://github.com/frida/frida/releases/download/12.11.13/frida-gadget-12.11.13-linux-x86.so.xz

  14. windows平台下载地址:https://github.com/frida/frida/releases/download/15.1.27/frida-gadget-15.1.27-windows-x86.dll.xz

  15. 作者:初级程序员_ https://www.bilibili.com/read/cv17379503?spm_id_from=333.999.list.card_article.click

  16. 出处:bilibili

  17. 看雪: https://bbs.pediy.com/user-905049.htm
  18. */

  19. //本地时间戳
  20. function get_timestamp()
  21. {
  22.     var date = new Date();
  23.     date = new Date(date.setHours(date.getHours() + 10));     //转换到本地时间
  24.     var year = date.getFullYear().toString();
  25.     var month = (date.getMonth() + 1).toString();
  26.     var day = date.getDate().toString();
  27.     var hour = date.getHours().toString();
  28.     var minute = date.getMinutes().toString();
  29.     var second = date.getSeconds().toString();
  30.     var ms = date.getMilliseconds().toString();


  31.     return year + '-' + month + '-' + day + ' ' + hour + ':' + minute + ':' + second;
  32. }


  33. //linux创建文件夹
  34. function api_mkdir(path)
  35. {
  36.     var opendir = new NativeFunction(Module.getExportByName(null, 'opendir'), 'int', ['pointer'], {"abi":"sysv"});
  37.     var mkdir = new NativeFunction(Module.getExportByName(null, 'mkdir'), 'int', ['pointer', 'int'], {"abi":"sysv"});
  38.     var path_ptr = Memory.allocUtf8String(path);
  39.     if(opendir(path_ptr))
  40.         return true;
  41.     return mkdir(path_ptr, 0x1FF);
  42. }

  43. //服务器环境
  44. var G_CEnvironment = new NativeFunction(ptr(0x080CC181), 'pointer', [], {"abi":"sysv"});
  45. //获取当前服务器配置文件名
  46. var CEnvironment_get_file_name = new NativeFunction(ptr(0x80DA39A), 'pointer', ['pointer'], {"abi":"sysv"});

  47. //获取当前频道名
  48. function api_CEnvironment_get_file_name()
  49. {
  50.     var filename = CEnvironment_get_file_name(G_CEnvironment());
  51.     return filename.readUtf8String(-1);
  52. }

  53. //文件记录日志
  54. var frida_log_dir_path = './frida_log/'
  55. var f_log = null;
  56. var log_day = null;
  57. function log(msg)
  58. {
  59.     var date = new Date();
  60.     date = new Date(date.setHours(date.getHours() + 10));     //转换到本地时间
  61.     var year = date.getFullYear().toString();
  62.     var month = (date.getMonth() + 1).toString();
  63.     var day = date.getDate().toString();
  64.     var hour = date.getHours().toString();
  65.     var minute = date.getMinutes().toString();
  66.     var second = date.getSeconds().toString();
  67.     var ms = date.getMilliseconds().toString();

  68.     //日志按日期记录
  69.     if((f_log == null) || (log_day != day))
  70.     {
  71.         api_mkdir(frida_log_dir_path);
  72.         f_log = new File(frida_log_dir_path + 'frida_' + api_CEnvironment_get_file_name() + '_' + year + '_' + month + '_' + day + '.log', 'a+');
  73.         log_day = day;
  74.     }

  75.     //时间戳
  76.     var timestamp = year + '-' + month + '-' + day + ' ' + hour + ':' + minute + ':' + second + '.' + ms;

  77.     //控制台日志
  78.     console.log('[' + timestamp + ']' + msg + '\n');

  79.     //文件日志
  80.     f_log.write('[' + timestamp + ']' + msg + '\n');
  81.     //立即写日志到文件中
  82.     f_log.flush();
  83. }

  84. //生成随机整数(不包含max)
  85. function get_random_int(min, max)
  86. {
  87.     return Math.floor(Math.random() * (max - min)) + min;
  88. }

  89. //内存十六进制打印
  90. function bin2hex(p, len)
  91. {
  92.     var hex = '';
  93.     for(var i = 0; i < len; i++)
  94.     {
  95.         var s = p.add(i).readU8().toString(16);
  96.         if(s.length == 1)
  97.             s = '0' + s;
  98.         hex += s;
  99.         if (i != len - 1)
  100.             hex += ' ';
  101.     }
  102.     return hex;
  103. }


  104. //延迟加载插件
  105. function awake()
  106. {
  107.     //Hook check_argv
  108.     Interceptor.attach(ptr(0x829EA5A), {

  109.         onEnter: function (args) {
  110.         },
  111.         onLeave: function (retval) {
  112.             //等待check_argv函数执行结束 再加载插件
  113.             start();
  114.         }
  115.     });
  116. }

  117. //所有账号角色开启GM权限
  118. function hook_check_gm()
  119. {
  120.     //GM账户
  121.     //WongWork::CGMAccounts::isGM
  122.     Interceptor.attach(ptr(0x8109346), {

  123.         onEnter: function (args) {
  124.         },
  125.         onLeave: function (retval) {
  126.             //强制返回true
  127.             retval.replace(1);
  128.         }
  129.     });

  130.     //GM角色
  131.     //CUser::isGMUser
  132.     Interceptor.attach(ptr(0x814589C), {

  133.         onEnter: function (args) {
  134.         },
  135.         onLeave: function (retval) {
  136.             //强制返回true
  137.             retval.replace(1);
  138.         }
  139.     });
  140. }

  141. //解除每日创建角色数量限制
  142. function disable_check_create_character_limit()
  143. {
  144.     //DB_CreateCharac::CheckLimitCreateNewCharac
  145.     Interceptor.attach(ptr(0x8401922), {
  146.         onEnter: function (args) {
  147.         },
  148.         onLeave: function (retval) {
  149.             //强制返回允许创建
  150.             retval.replace(1);
  151.         }
  152.     });
  153. }

  154. //获取副本id
  155. var CDungeon_get_index = new NativeFunction(ptr(0x080FDCF0),  'int', ['pointer'], {"abi":"sysv"});

  156. //修复绝望之塔
  157. //skip_user_apc: 为true时, 跳过每10层的UserAPC
  158. function fix_TOD(skip_user_apc)
  159. {
  160.     //每日进入次数限制
  161.     //TOD_UserState::getEnterCount
  162.     Interceptor.attach(ptr(0x08643872), {

  163.         onEnter: function (args) {
  164.             //今日已进入次数强制清零
  165.             args[0].add(0x10).writeInt(0);
  166.         },
  167.         onLeave: function (retval) {
  168.         }
  169.     });

  170.     //每10层挑战玩家APC 服务器内角色不足10个无法进入
  171.     if(skip_user_apc)
  172.     {
  173.         //跳过10/20/.../90层
  174.         //TOD_UserState::getTodayEnterLayer
  175.         Interceptor.attach(ptr(0x0864383E), {

  176.             onEnter: function (args) {
  177.                 //绝望之塔当前层数
  178.                 var today_enter_layer = args[1].add(0x14).readShort();

  179.                 if(((today_enter_layer%10) == 9) && (today_enter_layer > 0) && (today_enter_layer < 100))
  180.                 {
  181.                     //当前层数为10的倍数时  直接进入下一层
  182.                     args[1].add(0x14).writeShort(today_enter_layer + 1);
  183.                 }
  184.             },
  185.             onLeave: function (retval) {
  186.             }
  187.         });
  188.     }



  189.     //修复金币异常
  190.     //CParty::UseAncientDungeonItems
  191.     var CParty_UseAncientDungeonItems_ptr = ptr(0x859EAC2);
  192.     var CParty_UseAncientDungeonItems = new NativeFunction(CParty_UseAncientDungeonItems_ptr,  'int', ['pointer', 'pointer', 'pointer', 'pointer'], {"abi":"sysv"});
  193.     Interceptor.replace(CParty_UseAncientDungeonItems_ptr, new NativeCallback(function (party, dungeon, inven_item, a4) {

  194.         //当前进入的地下城id
  195.         var dungeon_index = CDungeon_get_index(dungeon);

  196.         //根据地下城id判断是否为绝望之塔
  197.         if((dungeon_index >= 11008) && (dungeon_index <= 11107))
  198.         {
  199.             //绝望之塔 不再扣除金币
  200.             return 1;
  201.         }

  202.         //其他副本执行原始扣除道具逻辑
  203.         return CParty_UseAncientDungeonItems(party, dungeon, inven_item, a4);
  204.      }, 'int', ['pointer', 'pointer', 'pointer', 'pointer']));

  205. }

  206. //根据账号查找已登录角色
  207. var GameWorld_find_user_from_world_byaccid = new NativeFunction(ptr(0x86C4D40), 'pointer', ['pointer', 'int'], {"abi":"sysv"});
  208. //获取玩家任务信息
  209. var CUser_getCurCharacQuestW = new NativeFunction(ptr(0x814AA5E),  'pointer', ['pointer'], {"abi":"sysv"});
  210. //任务相关操作(第二个参数为协议编号: 33=接受任务, 34=放弃任务, 35=任务完成条件已满足, 36=提交任务领取奖励)
  211. var CUser_quest_action = new NativeFunction(ptr(0x0866DA8A),  'int', ['pointer', 'int', 'int', 'int', 'int'], {"abi":"sysv"});
  212. //发包给客户端
  213. var CUser_Send = new NativeFunction(ptr(0x86485BA), 'int', ['pointer', 'pointer'], {"abi":"sysv"});
  214. //设置GM完成任务模式(无条件完成任务)
  215. var CUser_setGmQuestFlag = new NativeFunction(ptr(0x822FC8E),  'int', ['pointer', 'int'], {"abi":"sysv"});
  216. //是否GM任务模式
  217. var CUser_getGmQuestFlag = new NativeFunction(ptr(0x822FC8E),  'int', ['pointer'], {"abi":"sysv"});
  218. //通知客户端更新已完成任务列表
  219. var CUser_send_clear_quest_list = new NativeFunction(ptr(0x868B044),  'int', ['pointer'], {"abi":"sysv"});
  220. //计算任务基础奖励(不包含道具奖励)
  221. var CUser_quest_basic_reward = new NativeFunction(ptr(0x866E7A8),  'int', ['pointer', 'pointer', 'pointer', 'pointer', 'pointer', 'pointer', 'int'], {"abi":"sysv"});
  222. //通知客户端QP更新
  223. var CUser_sendCharacQp = new NativeFunction(ptr(0x868AC24),  'int', ['pointer'], {"abi":"sysv"});
  224. //通知客户端QuestPiece更新
  225. var CUser_sendCharacQuestPiece = new NativeFunction(ptr(0x868AF2C),  'int', ['pointer'], {"abi":"sysv"});
  226. //获取角色状态
  227. var CUser_get_state = new NativeFunction(ptr(0x80DA38C), 'int', ['pointer'], {"abi":"sysv"});
  228. //通知客户端角色属性更新
  229. var CUser_SendNotiPacket = new NativeFunction(ptr(0x867BA5C), 'int', ['pointer', 'int', 'int', 'int'], {"abi":"sysv"});

  230. //获取DataManager实例
  231. var G_CDataManager = new NativeFunction(ptr(0x80CC19B), 'pointer', [], {"abi":"sysv"});
  232. //从pvf中获取任务数据
  233. var CDataManager_find_quest = new NativeFunction(ptr(0x835FDC6), 'pointer', ['pointer', 'int'], {"abi":"sysv"});

  234. var UserQuest_finish_quest = new NativeFunction(ptr(0x86AC854), 'int', ['pointer', 'int'], {"abi":"sysv"});
  235. //通知客户端更新角色任务列表
  236. var UserQuest_get_quest_info = new NativeFunction(ptr(0x86ABBA8), 'int', ['pointer', 'pointer'], {"abi":"sysv"});
  237. //重置所有任务为未完成状态
  238. var UserQuest_reset = new NativeFunction(ptr(0x86AB894), 'int', ['pointer'], {"abi":"sysv"});

  239. //设置任务为已完成状态
  240. var WongWork_CQuestClear_setClearedQuest = new NativeFunction(ptr(0x808BA78), 'int', ['pointer', 'int'], {"abi":"sysv"});
  241. //重置任务为未完成状态
  242. var WongWork_CQuestClear_resetClearedQuests = new NativeFunction(ptr(0x808BAAC), 'int', ['pointer', 'int'], {"abi":"sysv"});
  243. //任务是否已完成
  244. var WongWork_CQuestClear_isClearedQuest = new NativeFunction(ptr(0x808BAE0), 'int', ['pointer', 'int'], {"abi":"sysv"});

  245. //检测当前角色是否可接该任务
  246. var stSelectQuestParam_stSelectQuestParam = new NativeFunction(ptr(0x83480B4), 'pointer', ['pointer', 'pointer'], {"abi":"sysv"});
  247. var Quest_check_possible = new NativeFunction(ptr(0x8352D86), 'int', ['pointer', 'pointer'], {"abi":"sysv"});

  248. //服务器组包
  249. var PacketGuard_PacketGuard = new NativeFunction(ptr(0x858DD4C), 'int', ['pointer'], {"abi":"sysv"});
  250. var InterfacePacketBuf_put_header = new NativeFunction(ptr(0x80CB8FC), 'int', ['pointer', 'int', 'int'], {"abi":"sysv"});
  251. var InterfacePacketBuf_put_byte = new NativeFunction(ptr(0x80CB920), 'int', ['pointer', 'uint8'], {"abi":"sysv"});
  252. var InterfacePacketBuf_put_short = new NativeFunction(ptr(0x80D9EA4), 'int', ['pointer', 'uint16'], {"abi":"sysv"});
  253. var InterfacePacketBuf_put_int = new NativeFunction(ptr(0x80CB93C), 'int', ['pointer', 'int'], {"abi":"sysv"});
  254. var InterfacePacketBuf_put_binary = new NativeFunction(ptr(0x811DF08), 'int', ['pointer', 'pointer', 'int'], {"abi":"sysv"});
  255. var InterfacePacketBuf_finalize = new NativeFunction(ptr(0x80CB958), 'int', ['pointer', 'int'], {"abi":"sysv"});
  256. var Destroy_PacketGuard_PacketGuard = new NativeFunction(ptr(0x858DE80), 'int', ['pointer'], {"abi":"sysv"});

  257. //服务器组包
  258. function api_PacketGuard_PacketGuard()
  259. {
  260.     var packet_guard = Memory.alloc(0x20000);
  261.     PacketGuard_PacketGuard(packet_guard);

  262.     return packet_guard;
  263. }

  264. //无条件完成指定任务并领取奖励
  265. function api_force_clear_quest(user, quest_id)
  266. {
  267.     //设置GM完成任务模式(无条件完成任务)
  268.     CUser_setGmQuestFlag(user, 1);

  269.     //接受任务
  270.     CUser_quest_action(user, 33, quest_id, 0, 0);

  271.     //完成任务
  272.     CUser_quest_action(user, 35, quest_id, 0, 0);

  273.     //领取任务奖励(倒数第二个参数表示领取奖励的编号, -1=领取不需要选择的奖励; 0=领取可选奖励中的第1个奖励; 1=领取可选奖励中的第二个奖励)
  274.     CUser_quest_action(user, 36, quest_id, -1, 1);

  275.     //服务端有反作弊机制: 任务完成时间间隔不能小于1秒.  这里将上次任务完成时间清零 可以连续提交任务
  276.     user.add(0x79644).writeInt(0);

  277.     //关闭GM完成任务模式(不需要材料直接完成)
  278.     CUser_setGmQuestFlag(user, 0);

  279.     return;
  280. }

  281. //重置所有任务(需要小退重新选择角色刷新)
  282. function api_reset_all_quest(user)
  283. {
  284.     var user_quest = CUser_getCurCharacQuestW(user);
  285.     //清空已接任务列表
  286.     for(var i=0; i<20; i++)
  287.     {
  288.         user_quest.add(4 * (i + 7500 + 2)).writeInt(0);
  289.     }
  290.     //所有任务设置未完成状态
  291.     for(var i=0; i<29999; i++)
  292.     {
  293.         WongWork_CQuestClear_resetClearedQuests(user_quest.add(4), i);
  294.     }

  295.     api_CUser_SendNotiPacketMessage(user, '所有任务已重置, 请重新选择角色刷新任务列表!', 14);
  296. }

  297. //完成当前已接任务并领取奖励
  298. function clear_doing_quest(user)
  299. {
  300.     //玩家任务信息
  301.     var user_quest = CUser_getCurCharacQuestW(user);

  302.     //遍历20个已接任务
  303.     //任务列表(保存任务id): user_quest.add(4 * (i + 7500 + 2))
  304.     //任务完成状态(0=已满足任务条件): user_quest.add(4 * (i + 7520 + 2))
  305.     for(var i=0; i<20; i++)
  306.     {
  307.         //任务id
  308.         var quest_id = user_quest.add(4 * (i + 7500 + 2)).readInt();

  309.         if(quest_id > 0)
  310.         {
  311.             //无条件完成任务并领取奖励
  312.             api_force_clear_quest(user, quest_id);
  313.         }
  314.     }

  315.     //通知客户端更新已完成任务列表
  316.     CUser_send_clear_quest_list(user);

  317.     //通知客户端更新任务列表
  318.     var packet_guard = api_PacketGuard_PacketGuard();
  319.     UserQuest_get_quest_info(user_quest, packet_guard);
  320.     CUser_Send(user, packet_guard);
  321.     Destroy_PacketGuard_PacketGuard(packet_guard);
  322. }

  323. //完成角色当前可接的所有任务(仅发送金币/经验/QP等基础奖励 无道具奖励)
  324. var QUEST_GRADE_COMMON_UNIQUE = 5;                  //任务脚本中[grade]字段对应的常量定义 可以在importQuestScript函数中找到
  325. var QUEST_GRADE_NORMALY_REPEAT = 4;                 //可重复提交的重复任务
  326. var QUEST_GRADE_DAILY = 3;                          //每日任务
  327. var QUEST_GRADE_EPIC = 0;                           //史诗任务
  328. function clear_all_quest_by_character_level(user)
  329. {
  330.     //log('clear_all_quest_by_character_level start!');

  331.     //玩家任务信息
  332.     var user_quest = CUser_getCurCharacQuestW(user);
  333.     //玩家已完成任务信息
  334.     var WongWork_CQuestClear = user_quest.add(4);
  335.     //玩家当前等级
  336.     var charac_lv = CUserCharacInfo_get_charac_level(user);

  337.     //本次完成任务数量
  338.     var clear_quest_cnt = 0;

  339.     //pvf数据
  340.     var data_manager = G_CDataManager();

  341.     //首先完成当前已接任务
  342.     clear_doing_quest(user);

  343.     //完成当前等级所有任务总经验奖励
  344.     var total_exp_bonus = 0;
  345.     //完成当前等级所有任务总金币奖励
  346.     var total_gold_bonus = 0;
  347.     //任务点奖励
  348.     var total_quest_point_bonus = 0;
  349.     var total_quest_piece_bonus = 0;

  350.     //任务最大编号: 29999
  351.     for(var quest_id=1; quest_id<30000; quest_id++)
  352.     {
  353.         //跳过已完成的任务
  354.         if(WongWork_CQuestClear_isClearedQuest(WongWork_CQuestClear, quest_id))
  355.             continue;

  356.         //获取任务数据
  357.         var quest = CDataManager_find_quest(data_manager, quest_id);
  358.         if(!quest.isNull())
  359.         {
  360.             //任务类型
  361.             var quest_grade = quest.add(8).readInt();

  362.             //跳过grade为[common unique]类型的任务(转职等任务)
  363.             //跳过可重复提交的任务
  364.             //跳过每日任务
  365.             if((quest_grade != QUEST_GRADE_COMMON_UNIQUE) && (quest_grade != QUEST_GRADE_NORMALY_REPEAT) && (quest_grade != QUEST_GRADE_DAILY))
  366.             {
  367.                 //判断任务当前是否可接
  368.                 //var stSelectQuestParam = Memory.alloc(100);
  369.                 //stSelectQuestParam_stSelectQuestParam(stSelectQuestParam, user);
  370.                 //if(Quest_check_possible(quest, stSelectQuestParam))

  371.                 //只判断任务最低等级要求 忽略 职业/前置 等任务要求 可一次性完成当前等级所有任务
  372.                 var quest_min_lv = quest.add(0x20).readInt();
  373.                 if(quest_min_lv <= charac_lv)
  374.                 {
  375.                     //获取该任务的基础奖励
  376.                     var exp_bonus = Memory.alloc(4);
  377.                     var gold_bonus = Memory.alloc(4);
  378.                     var quest_point_bonus = Memory.alloc(4);
  379.                     var quest_piece_bonus = Memory.alloc(4);
  380.                     //QP奖励已直接发送到角色 经验/金币只返回结果  需要手动发送
  381.                     CUser_quest_basic_reward(user,quest, exp_bonus, gold_bonus, quest_point_bonus, quest_piece_bonus, 1);

  382.                     //统计本次自动完成任务的基础奖励
  383.                     var exp = exp_bonus.readInt();
  384.                     var gold = gold_bonus.readInt();
  385.                     var quest_point = quest_point_bonus.readInt();
  386.                     var quest_piece = quest_piece_bonus.readInt();
  387.                     if(exp > 0)
  388.                         total_exp_bonus += exp;
  389.                     if(gold > 0)
  390.                         total_gold_bonus += gold;
  391.                     if(quest_point > 0)
  392.                         total_quest_point_bonus += quest_point;     //没有[quest point]字段的任务quest_point=10000
  393.                     if(quest_piece > 0)
  394.                         total_quest_piece_bonus += quest_piece;

  395.                     //将该任务设置为已完成状态
  396.                     WongWork_CQuestClear_setClearedQuest(user_quest.add(4), quest_id);

  397.                     //本次自动完成任务计数
  398.                     clear_quest_cnt++;
  399.                 }
  400.             }
  401.         }
  402.     }

  403.     //通知客户端更新
  404.     if(clear_quest_cnt > 0)
  405.     {
  406.         //发送任务经验奖励
  407.         if(total_exp_bonus > 0)
  408.             api_CUser_gain_exp_sp(user, total_exp_bonus);
  409.         //发送任务金币奖励
  410.         if(total_gold_bonus > 0)
  411.             CInventory_gain_money(CUserCharacInfo_getCurCharacInvenW(user), total_gold_bonus, 0, 0, 0);

  412.         //通知客户端更新奖励数据
  413.         if ( CUser_get_state(user) == 3 )
  414.         {
  415.             CUser_SendNotiPacket(user, 0, 2, 0);
  416.             CUser_SendNotiPacket(user, 1, 2, 1);

  417.             CUser_SendUpdateItemList(user, 1, 0, 0);
  418.             CUser_sendCharacQp(user);
  419.             CUser_sendCharacQuestPiece(user);
  420.         }

  421.         //通知客户端更新已完成任务列表
  422.         CUser_send_clear_quest_list(user);

  423.         //通知客户端更新任务列表
  424.         var packet_guard = api_PacketGuard_PacketGuard();
  425.         UserQuest_get_quest_info(user_quest, packet_guard);
  426.         CUser_Send(user, packet_guard);
  427.         Destroy_PacketGuard_PacketGuard(packet_guard);

  428.         //公告通知客户端本次自动完成任务数据
  429.         api_CUser_SendNotiPacketMessage(user, '已自动完成当前等级任务数量: ' + clear_quest_cnt, 14);
  430.         api_CUser_SendNotiPacketMessage(user, '任务经验奖励: ' + total_exp_bonus, 14);
  431.         api_CUser_SendNotiPacketMessage(user, '任务金币奖励: ' + total_gold_bonus, 14);
  432.         api_CUser_SendNotiPacketMessage(user, '任务QuestPoint奖励: ' + total_quest_point_bonus, 14);
  433.         api_CUser_SendNotiPacketMessage(user, '任务QuestPiece奖励: ' + total_quest_piece_bonus, 14);
  434.     }


  435.     //log('clear_all_quest_by_character_level end!');

  436.     return;
  437. }

  438. //捕获玩家游戏事件
  439. function hook_history_log()
  440. {
  441.     //cHistoryTrace::operator()
  442.     Interceptor.attach(ptr(0x854F990), {

  443.         onEnter: function (args) {

  444.             //解析日志内容: "18000008",18000008,D,145636,"nickname",1,72,8,0,192.168.200.1,192.168.200.1,50963,11, DungeonLeave,"龍人之塔",0,0,"aabb","aabb","N/A","N/A","N/A"
  445.             var history_log = args[1].readUtf8String(-1);
  446.             var group = history_log.split(',');

  447.             //角色信息
  448.             var account_id = parseInt(group[1]);
  449.             var time_hh_mm_ss = group[3];
  450.             var charac_name = group[4];
  451.             var charac_no = group[5];
  452.             var charac_level = group[6];
  453.             var charac_job = group[7];
  454.             var charac_growtype = group[8];
  455.             var user_web_address = group[9];
  456.             var user_peer_ip2 = group[10];
  457.             var user_port = group[11];
  458.             var channel_index = group[12];              //当前频道id

  459.             //玩家游戏事件
  460.             var game_event = group[13].slice(1);        //删除多余空格

  461.             //触发游戏事件的角色
  462.             var user = GameWorld_find_user_from_world_byaccid(G_GameWorld(), account_id);

  463.             if(user.isNull())
  464.                 return;

  465.             //道具减少:  Item-,1,10000113,63,1,3,63,0,0,0,0,0,0000000000000000000000000000,0,0,00000000000000000000
  466.             if(game_event == 'Item-')
  467.             {
  468.                 var item_id = parseInt(group[15]);                //本次操作道具id
  469.                 var item_cnt = parseInt(group[17]);               //本次操作道具数量
  470.                 var reason = parseInt(group[18]);                 //本次操作原因


  471.                 //log('玩家[' + charac_name + ']道具减少, 原因:' + reason + '(道具id=' + item_id + ', 使用数量=' + item_cnt);

  472.                 if(5 == reason)
  473.                 {
  474.                     //丢弃道具
  475.                 }
  476.                 else if(3 == reason)
  477.                 {
  478.                     //
  479.                     //使用道具
  480.                     //

  481.                     //这里并未改变道具原始效果 原始效果成功执行后触发下面的代码
  482.                     if(10000113 == item_id)
  483.                     {
  484.                         //任务完成券
  485.                         clear_doing_quest(user);
  486.                     }
  487.                 }
  488.                 else if(9 == reason)
  489.                 {
  490.                     //分解道具
  491.                 }
  492.                 else if(10 == reason)
  493.                 {
  494.                     //使用属性石头
  495.                 }
  496.             }
  497.             else if(game_event == 'KillMob')
  498.             {
  499.                 //杀死怪物
  500.                //魔法封印装备词条升级
  501.                  boost_random_option_equ(user);
  502.             }
  503.             else if(game_event == 'Money+')
  504.             {
  505.                 var cur_money = parseInt(group[14]);                //当前持有的金币数量
  506.                 var add_money = parseInt(group[15]);                //本次获得金币数量
  507.                 var reason = parseInt(group[16]);                   //本次获得金币原因

  508.                 //log('玩家[' + charac_name + ']获取金币, 原因:' + reason + '(当前持有金币=' + cur_money + ', 本次获得金币数量=' + add_money);

  509.                 if(4 == reason)
  510.                 {
  511.                     //副本拾取
  512.                 }
  513.                 else if(5 == reason)
  514.                 {
  515.                     //副本通关翻牌获取金币
  516.                 }
  517.             }
  518.             else if(game_event == 'DungeonLeave')
  519.             {
  520.                 //离开副本
  521.                 //刷完副本后, 重置异界+极限祭坛次数
  522.   CUser_DimensionInoutUpdate(user, 1, 1);
  523.             }
  524.         },
  525.         onLeave: function (retval) {

  526.         }
  527.     });
  528. }


  529. //重置异界/极限祭坛次数
  530. var CUser_DimensionInoutUpdate = new NativeFunction(ptr(0x8656C12),  'int', ['pointer', 'int', 'int'], {"abi":"sysv"});


  531. //设置幸运点数
  532. var CUserCharacInfo_SetCurCharacLuckPoint = new NativeFunction(ptr(0x0864670A), 'int', ['pointer', 'int'], {"abi":"sysv"});
  533. //获取角色当前幸运点
  534. var CUserCharacInfo_GetCurCharacLuckPoint = new NativeFunction(ptr(0x822F828), 'int', ['pointer'], {"abi":"sysv"});
  535. //设置角色属性改变脏标记(角色上线时把所有属性从数据库缓存到内存中, 只有设置了脏标记, 角色下线时才能正确存档到数据库, 否则变动的属性下线后可能会回档)
  536. var CUserCharacInfo_enableSaveCharacStat = new NativeFunction(ptr(0x819A870), 'int', ['pointer'], {"abi":"sysv"});


  537. //幸运点上下限
  538. var MAX_LUCK_POINT = 99999;
  539. var MIN_LUCK_POINT = 1;

  540. //设置角色幸运点
  541. function api_CUserCharacInfo_SetCurCharacLuckPoint(user, new_luck_point)
  542. {
  543.     if(new_luck_point > MAX_LUCK_POINT)
  544.         new_luck_point = MAX_LUCK_POINT;
  545.     else if(new_luck_point < MIN_LUCK_POINT)
  546.         new_luck_point = MIN_LUCK_POINT;

  547.     CUserCharacInfo_enableSaveCharacStat(user);
  548.     CUserCharacInfo_SetCurCharacLuckPoint(user, new_luck_point);

  549.     return new_luck_point;
  550. }

  551. //使用命运硬币后, 可以改变自身幸运点
  552. //查询角色当前幸运点GM命令: //show lp
  553. //当前角色幸运点拉满GM命令: //max lp
  554. function use_ftcoin_change_luck_point(user)
  555. {
  556.     //抛命运硬币
  557.     var rand = get_random_int(0, 100);

  558.     //当前幸运点数
  559.     var new_luck_point = null;

  560.     if(rand == 0)
  561.     {
  562.         //1%几率将玩家幸运点充满(最大值10W)
  563.         new_luck_point = MAX_LUCK_POINT;
  564.     }
  565.     else if(rand == 1)
  566.     {
  567.         //1%几率将玩家幸运点耗尽
  568.         new_luck_point = MIN_LUCK_POINT;
  569.     }
  570.     else if(rand < 51)
  571.     {
  572.         //49%几率当前幸运点增加20%
  573.         new_luck_point = Math.floor(CUserCharacInfo_GetCurCharacLuckPoint(user) * 1.2);
  574.     }
  575.     else
  576.     {
  577.         //49%几率当前幸运点降低20%
  578.         new_luck_point = Math.floor(CUserCharacInfo_GetCurCharacLuckPoint(user) * 0.8);
  579.     }

  580.     //修改角色幸运点
  581.     new_luck_point = api_CUserCharacInfo_SetCurCharacLuckPoint(user, new_luck_point);

  582.     //通知客户端当前角色幸运点已改变
  583.     api_CUser_SendNotiPacketMessage(user, '命运已被改变, 当前幸运点数: ' + new_luck_point, 0);
  584. }



  585. //使用角色幸运值加成装备爆率
  586. function enable_drop_use_luck_piont()
  587. {
  588.     //由于roll点爆装函数拿不到user, 在杀怪和翻牌函数入口保存当前正在处理的user
  589.     var cur_luck_user = null;

  590.     //DisPatcher_DieMob::dispatch_sig
  591.     Interceptor.attach(ptr(0x81EB0C4), {
  592.         onEnter: function (args) {
  593.             cur_luck_user = args[1];
  594.         },
  595.         onLeave: function (retval) {
  596.             cur_luck_user = null;
  597.         }
  598.     });

  599.     //CParty::SetPlayResult
  600.     Interceptor.attach(ptr(0x85B2412), {
  601.         onEnter: function (args) {
  602.             cur_luck_user = args[1];
  603.         },
  604.         onLeave: function (retval) {
  605.             cur_luck_user = null;
  606.         }
  607.     });


  608.     //修改决定出货品质(rarity)的函数 使出货率享受角色幸运值加成
  609.     //CLuckPoint::GetItemRarity
  610.     var CLuckPoint_GetItemRarity_ptr = ptr(0x8550BE4);
  611.     var CLuckPoint_GetItemRarity = new NativeFunction(CLuckPoint_GetItemRarity_ptr,  'int', ['pointer', 'pointer', 'int', 'int'], {"abi":"sysv"});
  612.     Interceptor.replace(CLuckPoint_GetItemRarity_ptr, new NativeCallback(function (a1, a2, roll, a4) {

  613.         //使用角色幸运值roll点代替纯随机roll点
  614.         if(cur_luck_user)
  615.         {
  616.             //获取当前角色幸运值
  617.             var luck_point = CUserCharacInfo_GetCurCharacLuckPoint(cur_luck_user);

  618.             //roll点范围1-100W, roll点越大, 出货率越高
  619.             //角色幸运值范围1-10W
  620.             //使用角色 [当前幸运值*10] 作为roll点下限, 幸运值越高, roll点越大
  621.             roll = get_random_int(luck_point*10, 1000000);
  622.         }

  623.         //执行原始计算爆装品质函数
  624.         var rarity = CLuckPoint_GetItemRarity(a1, a2, roll, a4);

  625.         //调整角色幸运值
  626.         if(cur_luck_user)
  627.         {
  628.             var rate = 1.0;

  629.             //出货粉装以上, 降低角色幸运值
  630.             if(rarity >= 3)
  631.             {
  632.                 //出货品质越高, 幸运值下降约快
  633.                 rate = 1 - (rarity*0.01);
  634.             }
  635.             else
  636.             {
  637.                 //未出货时, 提升幸运值
  638.                 rate = 1.01;
  639.             }

  640.             //设置新的幸运值
  641.             var new_luck_point = Math.floor(CUserCharacInfo_GetCurCharacLuckPoint(cur_luck_user) * rate);
  642.             api_CUserCharacInfo_SetCurCharacLuckPoint(cur_luck_user, new_luck_point);
  643.         }

  644.         return rarity;
  645.      }, 'int', ['pointer', 'pointer', 'int', 'int']));
  646. }

  647. //获取背包槽中的道具
  648. var INVENTORY_TYPE_BODY = 0;            //身上穿的装备
  649. var INVENTORY_TYPE_ITEM = 1;            //物品栏
  650. var INVENTORY_TYPE_AVARTAR = 2;         //时装栏
  651. var CInventory_GetInvenRef = new NativeFunction(ptr(0x84FC1DE), 'pointer', ['pointer', 'int', 'int'], {"abi":"sysv"});

  652. //检查背包中道具是否为空
  653. var Inven_Item_isEmpty = new NativeFunction(ptr(0x811ED66), 'int', ['pointer'], {"abi":"sysv"});
  654. //获取背包中道具item_id
  655. var Inven_Item_getKey = new NativeFunction(ptr(0x850D14E), 'int', ['pointer'], {"abi":"sysv"});
  656. //道具是否是装备
  657. var Inven_Item_isEquipableItemType = new NativeFunction(ptr(0x08150812), 'int', ['pointer'], {"abi":"sysv"});
  658. //获取装备pvf数据
  659. var CDataManager_find_item = new NativeFunction(ptr(0x835FA32), 'pointer', ['pointer', 'int'], {"abi":"sysv"});
  660. //是否魔法封印装备
  661. var CEquipItem_IsRandomOption = new NativeFunction(ptr(0x8514E5E), 'int', ['pointer'], {"abi":"sysv"});
  662. //解封魔法封印
  663. var random_option_CRandomOptionItemHandle_give_option = new NativeFunction(ptr(0x85F2CC6),  'int', ['pointer', 'int', 'int', 'int', 'int', 'int', 'pointer'], {"abi":"sysv"});
  664. //获取装备品级
  665. var CItem_get_rarity = new NativeFunction(ptr(0x080F12D6), 'int', ['pointer'], {"abi":"sysv"});
  666. //获取装备可穿戴等级
  667. var CItem_getUsableLevel = new NativeFunction(ptr(0x80F12EE), 'int', ['pointer'], {"abi":"sysv"});
  668. //获取装备[item group name]
  669. var CItem_getItemGroupName = new NativeFunction(ptr(0x80F1312), 'int', ['pointer'], {"abi":"sysv"});
  670. //获取装备魔法封印等级?
  671. var CEquipItem_GetRandomOptionGrade = new NativeFunction(ptr(0x8514E6E), 'int', ['pointer'], {"abi":"sysv"});




  672. //增加魔法封印装备的魔法封印等级
  673. function _boost_random_option_equ(inven_item)
  674. {
  675.     //空装备
  676.     if(Inven_Item_isEmpty(inven_item))
  677.         return false;

  678.     //获取装备当前魔法封印属性
  679.     var random_option = inven_item.add(37);

  680.     //随机选取一个词条槽
  681.     var random_option_slot = get_random_int(0, 3);

  682.     //若词条槽已有魔法封印
  683.     if(random_option.add(3*random_option_slot).readU8())
  684.     {
  685.         //每个词条有2个属性值
  686.         var value_slot = get_random_int(1, 3);

  687.         //当前词条等级
  688.         var random_option_level = random_option.add(3*random_option_slot + value_slot).readU8();
  689.         if(random_option_level < 0xFF)
  690.         {
  691.             //1%概率词条等级+1
  692.             if(get_random_int(random_option_level, 100000) < 1000)
  693.             {
  694.                 random_option.add(3*random_option_slot + value_slot).writeU8(random_option_level + 1);
  695.                 return true;
  696.             }
  697.         }
  698.     }

  699.     return false;
  700. }

  701. //穿戴中的魔法封印装备词条升级
  702. function boost_random_option_equ(user)
  703. {
  704.     //遍历身上的装备 为拥有魔法封印属性的装备提升魔法封印等级
  705.     var inven = CUserCharacInfo_getCurCharacInvenW(user);
  706.     for(var slot=10; slot<=21; slot++)
  707.     {
  708.         var inven_item = CInventory_GetInvenRef(inven, INVENTORY_TYPE_BODY, slot);
  709.         if(_boost_random_option_equ(inven_item))
  710.         {
  711.             //通知客户端更新
  712.             CUser_SendUpdateItemList(user, 1, 3, slot);
  713.         }
  714.     }
  715. }


  716. //魔法封印属性转换时可以继承
  717. function change_random_option_inherit()
  718. {
  719.     //random_option::CRandomOptionItemHandle::change_option
  720.     Interceptor.attach(ptr(0x85F3340), {
  721.         onEnter: function (args) {
  722.             //保存原始魔法封印属性
  723.             this.random_option = args[7];
  724.             //本次变换的属性编号
  725.             this.change_random_option_index = args[6].toInt32();

  726.             //记录原始属性
  727.             this.random_optio_type = this.random_option.add(3*this.change_random_option_index).readU8();
  728.             this.random_optio_value_1 = this.random_option.add(3*this.change_random_option_index + 1).readU8();
  729.             this.random_optio_value_2 = this.random_option.add(3*this.change_random_option_index + 2).readU8();
  730.         },
  731.         onLeave: function (retval) {
  732.             //魔法封印转换成功
  733.             if(retval == 1)
  734.             {
  735.                 //获取未被附魔的魔法封印槽
  736.                 var index = -1;
  737.                 if(this.random_option.add(0).readU8() == 0)
  738.                     index = 0;
  739.                 else if(this.random_option.add(3).readU8() == 0)
  740.                     index = 1;
  741.                 else if(this.random_option.add(6).readU8() == 0)
  742.                     index = 2;

  743.                 //当魔法封印词条不足3个时, 若变换出等级极低的属性, 可直接附魔到装备空的魔法封印槽内
  744.                 if(index >= 0)
  745.                 {
  746.                     if((this.random_option.add(11).readU8() <= 5) && (this.random_option.add(12).readU8() <= 5))
  747.                     {
  748.                         //魔法封印附魔
  749.                         this.random_option.add(3*index).writeU8(this.random_option.add(10).readU8());
  750.                         this.random_option.add(3*index + 1).writeU8(this.random_option.add(11).readU8());
  751.                         this.random_option.add(3*index + 2).writeU8(this.random_option.add(12).readU8());

  752.                         //清空本次变换的属性(可以继续选择其他词条变换)
  753.                         this.random_option.add(10).writeInt(0);

  754.                         return;
  755.                     }
  756.                 }

  757.                 //用变换后的词条覆盖原始魔法封印词条
  758.                 this.random_option.add(3*this.change_random_option_index).writeU8(this.random_option.add(10).readU8());

  759.                 //若变换后的属性低于原来的值 则继承原有属性值 否则使用变换后的属性
  760.                 if(this.random_option.add(11).readU8() > this.random_optio_value_1)
  761.                     this.random_option.add(3*this.change_random_option_index + 1).writeU8(this.random_option.add(11).readU8());

  762.                 if(this.random_option.add(12).readU8() > this.random_optio_value_2)
  763.                     this.random_option.add(3*this.change_random_option_index + 2).writeU8(this.random_option.add(12).readU8());

  764.                 //清空本次变换的属性(可以继续选择其他词条变换)
  765.                 this.random_option.add(10).writeInt(0);
  766.             }
  767.         }
  768.     });
  769. }

  770. //魔法封印自动解封
  771. function auto_unseal_random_option_equipment(user)
  772. {
  773.     //CInventory::insertItemIntoInventory
  774.     Interceptor.attach(ptr(0x8502D86), {
  775.         onEnter: function (args) {
  776.             this.user = args[0].readPointer();
  777.         },
  778.         onLeave: function (retval) {

  779.             //物品栏新增物品的位置
  780.             var slot = retval.toInt32();
  781.             if(slot > 0 )
  782.             {
  783.                 //获取道具的角色
  784.                 var user = this.user;

  785.                 //角色背包
  786.                 var inven = CUserCharacInfo_getCurCharacInvenW(user);

  787.                 //背包中新增的道具
  788.                 var inven_item = CInventory_GetInvenRef(inven, INVENTORY_TYPE_ITEM, slot);

  789.                 //过滤道具类型
  790.                 if(!Inven_Item_isEquipableItemType(inven_item))
  791.                     return;

  792.                 //装备id
  793.                 var item_id = Inven_Item_getKey(inven_item);

  794.                 //pvf中获取装备数据
  795.                 var citem = CDataManager_find_item(G_CDataManager(), item_id);

  796.                 //检查装备是否为魔法封印类型
  797.                 if(!CEquipItem_IsRandomOption(citem))
  798.                     return;

  799.                 //是否已被解除魔法封印(魔法封印前10个字节是否为0)
  800.                 var random_option = inven_item.add(37);
  801.                 if(random_option.readU32() || random_option.add(4).readU32() || random_option.add(8).readShort())
  802.                 {
  803.                     return;
  804.                 }

  805.                 //尝试解除魔法封印
  806.                 var ret = random_option_CRandomOptionItemHandle_give_option(ptr(0x941F820).readPointer(), item_id, CItem_get_rarity(citem), CItem_getUsableLevel(citem), CItem_getItemGroupName(citem), CEquipItem_GetRandomOptionGrade(citem), inven_item.add(37));
  807.                 if(ret)
  808.                 {
  809.                     //通知客户端有装备更新
  810.                     CUser_SendUpdateItemList(user, 1, 0, slot);
  811.                 }
  812.             }
  813.         }
  814.     });
  815. }


  816. //本次登录时间
  817. var CUserCharacInfo_GetLoginTick = new NativeFunction(ptr(0x822F692),  'int', ['pointer'], {"abi":"sysv"});
  818. //点券充值
  819. var WongWork_IPG_CIPGHelper_IPGInput = new NativeFunction(ptr(0x80FFCA4),  'int', ['pointer', 'pointer', 'int', 'int', 'pointer', 'pointer', 'pointer', 'pointer', 'pointer', 'pointer'], {"abi":"sysv"});

  820. //代币充值
  821. var WongWork_IPG_CIPGHelper_IPGInputPoint = new NativeFunction(ptr(0x80FFFC0),  'int', ['pointer', 'pointer','int', 'int', 'pointer', 'pointer'], {"abi":"sysv"});

  822. //同步点券数据库
  823. var WongWork_IPG_CIPGHelper_IPGQuery = new NativeFunction(ptr(0x8100790),  'int', ['pointer', 'pointer'], {"abi":"sysv"});

  824. //点券充值 (禁止直接修改billing库所有表字段, 点券相关操作务必调用数据库存储过程!)
  825. function api_recharge_cash_cera(user, amount)
  826. {
  827.     //充值
  828.     WongWork_IPG_CIPGHelper_IPGInput(ptr(0x941F734).readPointer(), user, 5, amount, ptr(0x8C7FA20), ptr(0x8C7FA20),
  829.         Memory.allocUtf8String('GM'), ptr(0), ptr(0), ptr(0));

  830.     //通知客户端充值结果
  831.     WongWork_IPG_CIPGHelper_IPGQuery(ptr(0x941F734).readPointer(), user);
  832. }

  833. //代币充值 (禁止直接修改billing库所有表字段, 点券相关操作务必调用数据库存储过程!)
  834. function api_recharge_cash_cera_point(user, amount)
  835. {
  836.     //充值
  837.     WongWork_IPG_CIPGHelper_IPGInputPoint(ptr(0x941F734).readPointer(), user, amount, 4, ptr(0), ptr(0));

  838.     //通知客户端充值结果
  839.     WongWork_IPG_CIPGHelper_IPGQuery(ptr(0x941F734).readPointer(), user);
  840. }



  841. //在线奖励
  842. function enable_online_reward()
  843. {
  844.     //在线每5min发一次奖, 在线时间越长, 奖励越高
  845.     //CUser::WorkPerFiveMin
  846.     Interceptor.attach(ptr(0x8652F0C), {
  847.         onEnter: function (args) {
  848.             var user = args[0];

  849.             //当前系统时间
  850.             var cur_time = api_CSystemTime_getCurSec();

  851.             //本次登录时间
  852.             var login_tick = CUserCharacInfo_GetLoginTick(user);


  853.             if(login_tick > 0)
  854.             {
  855.                 //在线时长(分钟)
  856.                 var diff_time = Math.floor((cur_time - login_tick) / 60);

  857.                 //在线10min后开始计算
  858.                 if(diff_time < 10)
  859.                     return;

  860.                 //在线奖励最多发送1天
  861.                 if(diff_time > 1*24*60)
  862.                     return;

  863.                 //奖励: 每分钟0.1点券
  864.                 var REWARD_CASH_CERA_PER_MIN = 0.1;

  865.                 //计算奖励
  866.                 var reward_cash_cera = Math.floor(diff_time*REWARD_CASH_CERA_PER_MIN);

  867.                 //发点券
  868.                 api_recharge_cash_cera(user, reward_cash_cera);

  869.                 //发消息通知客户端奖励已发送
  870.                 //api_CUser_SendNotiPacketMessage(user, '[' + get_timestamp() + '] 在线奖励已发送(当前阶段点券奖励:' + reward_cash_cera + ')', 6);
  871.             }
  872.         },
  873.         onLeave: function (retval) {
  874.         }
  875.     });
  876. }

  877. //获取当前角色id
  878. var CUserCharacInfo_getCurCharacNo = new NativeFunction(ptr(0x80CBC4E), 'int', ['pointer'], {"abi":"sysv"});
  879. //道具是否被锁
  880. var CUser_CheckItemLock = new NativeFunction(ptr(0x8646942), 'int', ['pointer', 'int', 'int'], {"abi":"sysv"});
  881. //道具是否为消耗品
  882. var CItem_is_stackable = new NativeFunction(ptr(0x80F12FA), 'int', ['pointer'], {"abi":"sysv"});
  883. //获取消耗品类型
  884. var CStackableItem_GetItemType = new NativeFunction(ptr(0x8514A84),  'int', ['pointer'], {"abi":"sysv"});
  885. //获取徽章支持的镶嵌槽类型
  886. var CStackableItem_getJewelTargetSocket = new NativeFunction(ptr(0x0822CA28),  'int', ['pointer'], {"abi":"sysv"});
  887. //获取时装管理器
  888. var CInventory_GetAvatarItemMgrR = new NativeFunction(ptr(0x80DD576), 'pointer', ['pointer'], {"abi":"sysv"});
  889. //获取道具附加信息
  890. var Inven_Item_get_add_info = new NativeFunction(ptr(0x80F783A), 'int', ['pointer'], {"abi":"sysv"});
  891. //获取时装插槽数据
  892. var WongWork_CAvatarItemMgr_getJewelSocketData = new NativeFunction(ptr(0x82F98F8), 'pointer', ['pointer', 'int'], {"abi":"sysv"});
  893. //背包中删除道具(背包指针, 背包类型, 槽, 数量, 删除原因, 记录删除日志)
  894. var CInventory_delete_item = new NativeFunction(ptr(0x850400C), 'int', ['pointer', 'int', 'int', 'int', 'int', 'int'], {"abi":"sysv"});
  895. //时装镶嵌数据存盘
  896. var DB_UpdateAvatarJewelSlot_makeRequest = new NativeFunction(ptr(0x843081C), 'pointer', ['int', 'int', 'pointer'], {"abi":"sysv"});



  897. //获取时装在数据库中的uid
  898. function api_get_avartar_ui_id(avartar)
  899. {
  900.     return avartar.add(7).readInt();
  901. }

  902. //设置时装插槽数据(时装插槽数据指针, 插槽, 徽章id)
  903. //jewel_type: 红=0x1, 黄=0x2, 绿=0x4, 蓝=0x8, 白金=0x10
  904. function api_set_JewelSocketData(jewelSocketData, slot, emblem_item_id)
  905. {
  906.     if(!jewelSocketData.isNull())
  907.     {
  908.         //每个槽数据长6个字节: 2字节槽类型+4字节徽章item_id
  909.         //镶嵌不改变槽类型, 这里只修改徽章id
  910.         jewelSocketData.add(slot*6+2).writeInt(emblem_item_id);
  911.     }

  912.     return;
  913. }

  914. //修复时装镶嵌
  915. function fix_use_emblem()
  916. {
  917.     //Dispatcher_UseJewel::dispatch_sig
  918.     Interceptor.attach(ptr(0x8217BD6), {

  919.         onEnter: function (args) {

  920.             try {
  921.                 var user = args[1];
  922.                 var packet_buf = args[2];

  923.                 console.log('收到角色[' + api_CUserCharacInfo_getCurCharacName(user) + ']的镶嵌请求');
  924.                 console.log('Ptext packet: '+bin2hex(packet_buf.add(20).readPointer(),40));
  925.                 //校验角色状态是否允许镶嵌
  926.                 var state = CUser_get_state(user);
  927.                 if(state != 3)
  928.                 {
  929.                     return;
  930.                 }

  931.                 //解析packet_buf

  932.                 //时装所在的背包槽
  933.                 var avartar_inven_slot = api_PacketBuf_get_short(packet_buf);
  934.                 console.log(avartar_inven_slot+'---------------------OK');
  935.                 //时装item_id
  936.                 var avartar_item_id = api_PacketBuf_get_int(packet_buf);
  937.                 console.log(avartar_item_id+'---------------------OK');
  938.                 //本次镶嵌徽章数量
  939.                 var emblem_cnt = api_PacketBuf_get_byte(packet_buf);
  940.                 console.log(emblem_cnt+'---------------------OK');

  941.                 log('avartar_inven_slot=' + avartar_inven_slot + ', avartar_item_id=' + avartar_item_id + ', emblem_cnt=' + emblem_cnt);

  942.                 //获取时装道具
  943.                 var inven = CUserCharacInfo_getCurCharacInvenW(user);
  944.                 var avartar = CInventory_GetInvenRef(inven, INVENTORY_TYPE_AVARTAR, avartar_inven_slot);

  945.                 //校验时装 数据是否合法
  946.                 if(Inven_Item_isEmpty(avartar) || (Inven_Item_getKey(avartar) != avartar_item_id) || CUser_CheckItemLock(user, 2, avartar_inven_slot))
  947.                 {
  948.                     return;
  949.                 }

  950.                 //获取时装插槽数据
  951.                 var avartar_add_info = Inven_Item_get_add_info(avartar);
  952.                 var inven_avartar_mgr = CInventory_GetAvatarItemMgrR(inven);
  953.                 var jewel_socket_data = WongWork_CAvatarItemMgr_getJewelSocketData(inven_avartar_mgr, avartar_add_info);
  954.                 log('jewel_socket_data=' + jewel_socket_data + ':' + bin2hex(jewel_socket_data, 30));

  955.                 if(jewel_socket_data.isNull())
  956.                 {
  957.                     return;
  958.                 }

  959.                 //最多只支持3个插槽
  960.                 if(emblem_cnt <= 3)
  961.                 {
  962.                     var emblems = {};

  963.                     for(var i=0; i<emblem_cnt; i++)
  964.                     {
  965.                         //徽章所在的背包槽
  966.                         var emblem_inven_slot = api_PacketBuf_get_short(packet_buf);
  967.                         //徽章item_id
  968.                         var emblem_item_id = api_PacketBuf_get_int(packet_buf);
  969.                         //该徽章镶嵌的时装插槽id
  970.                         var avartar_socket_slot = api_PacketBuf_get_byte(packet_buf);

  971.                         //log('emblem_inven_slot=' + emblem_inven_slot + ', emblem_item_id=' + emblem_item_id + ', avartar_socket_slot=' + avartar_socket_slot);

  972.                         //获取徽章道具
  973.                         var emblem = CInventory_GetInvenRef(inven, INVENTORY_TYPE_ITEM, emblem_inven_slot);

  974.                         //校验徽章及插槽数据是否合法
  975.                         if(Inven_Item_isEmpty(emblem) || (Inven_Item_getKey(emblem) != emblem_item_id) || (avartar_socket_slot >= 3))
  976.                         {
  977.                             return;
  978.                         }

  979.                         //校验徽章是否满足时装插槽颜色要求

  980.                         //获取徽章pvf数据
  981.                         var citem = CDataManager_find_item(G_CDataManager(), emblem_item_id);
  982.                         if(citem.isNull())
  983.                         {
  984.                             return;
  985.                         }

  986.                         //校验徽章类型
  987.                         if(!CItem_is_stackable(citem) ||  (CStackableItem_GetItemType(citem) != 20))
  988.                         {
  989.                             return;
  990.                         }

  991.                         //获取徽章支持的插槽
  992.                         var emblem_socket_type = CStackableItem_getJewelTargetSocket(citem);

  993.                         //获取要镶嵌的时装插槽类型
  994.                         var avartar_socket_type = jewel_socket_data.add(avartar_socket_slot*6).readShort();

  995.                         if(!(emblem_socket_type & avartar_socket_type))
  996.                         {
  997.                             //插槽类型不匹配
  998.                             //log('socket type not match!');
  999.                             return;
  1000.                         }

  1001.                         emblems[avartar_socket_slot] = [emblem_inven_slot, emblem_item_id];
  1002.                     }



  1003.                     //开始镶嵌
  1004.                     for (var avartar_socket_slot in emblems) {
  1005.                         //删除徽章
  1006.                         var emblem_inven_slot = emblems[avartar_socket_slot][0];
  1007.                         CInventory_delete_item(inven, 1, emblem_inven_slot, 1, 8, 1);

  1008.                         //设置时装插槽数据
  1009.                         var emblem_item_id = emblems[avartar_socket_slot][1];
  1010.                         api_set_JewelSocketData(jewel_socket_data, avartar_socket_slot, emblem_item_id);

  1011.                         //log('徽章item_id=' + emblem_item_id + '已成功镶嵌进avartar_socket_slot=' + avartar_socket_slot + '的槽内!');
  1012.                     }

  1013.                     //时装插槽数据存档
  1014.                     DB_UpdateAvatarJewelSlot_makeRequest(CUserCharacInfo_getCurCharacNo(user), api_get_avartar_ui_id(avartar), jewel_socket_data);

  1015.                     //通知客户端时装数据已更新
  1016.                     CUser_SendUpdateItemList(user, 1, 1, avartar_inven_slot);

  1017.                     //回包给客户端
  1018.                     var packet_guard = api_PacketGuard_PacketGuard();
  1019.                     InterfacePacketBuf_put_header(packet_guard, 1, 204);
  1020.                     InterfacePacketBuf_put_int(packet_guard, 1);
  1021.                     InterfacePacketBuf_finalize(packet_guard, 1);
  1022.                     CUser_Send(user, packet_guard);
  1023.                     Destroy_PacketGuard_PacketGuard(packet_guard);

  1024.                     //log('镶嵌请求已处理完成!');
  1025.                 }


  1026.             } catch (error) {
  1027.                 console.log('fix_use_emblem throw Exception:' + error);
  1028.             }


  1029.         },
  1030.         onLeave: function (retval) {
  1031.             //返回值改为0  不再踢线
  1032.             retval.replace(0);
  1033.         }
  1034.     });
  1035. }

  1036. //获取角色名字
  1037. var CUserCharacInfo_getCurCharacName = new NativeFunction(ptr(0x8101028), 'pointer', ['pointer'], {"abi":"sysv"});
  1038. //给角色发消息
  1039. var CUser_SendNotiPacketMessage = new NativeFunction(ptr(0x86886CE), 'int', ['pointer', 'pointer', 'int'], {"abi":"sysv"});
  1040. //获取角色上次退出游戏时间
  1041. var CUserCharacInfo_getCurCharacLastPlayTick = new NativeFunction(ptr(0x82A66AA), 'int', ['pointer'], {"abi":"sysv"});
  1042. //获取角色等级
  1043. var CUserCharacInfo_get_charac_level = new NativeFunction(ptr(0x80DA2B8), 'int', ['pointer'], {"abi":"sysv"});
  1044. //获取角色当前等级升级所需经验
  1045. var CUserCharacInfo_get_level_up_exp = new NativeFunction(ptr(0x0864E3BA), 'int', ['pointer', 'int'], {"abi":"sysv"});
  1046. //角色增加经验
  1047. var CUser_gain_exp_sp = new NativeFunction(ptr(0x866A3FE), 'int', ['pointer', 'int', 'pointer', 'pointer', 'int', 'int', 'int'], {"abi":"sysv"});
  1048. //发送道具
  1049. var CUser_AddItem = new NativeFunction(ptr(0x867B6D4), 'int', ['pointer', 'int', 'int', 'int', 'pointer', 'int'], {"abi":"sysv"});
  1050. //获取角色背包
  1051. var CUserCharacInfo_getCurCharacInvenW = new NativeFunction(ptr(0x80DA28E), 'pointer', ['pointer'], {"abi":"sysv"});
  1052. //减少金币
  1053. var CInventory_use_money = new NativeFunction(ptr(0x84FF54C), 'int', ['pointer', 'int', 'int', 'int'], {"abi":"sysv"});
  1054. //增加金币
  1055. var CInventory_gain_money = new NativeFunction(ptr(0x84FF29C), 'int', ['pointer', 'int', 'int', 'int', 'int'], {"abi":"sysv"});
  1056. //通知客户端道具更新(客户端指针, 通知方式[仅客户端=1, 世界广播=0, 小队=2, war room=3], itemSpace[装备=0, 时装=1], 道具所在的背包槽)
  1057. var CUser_SendUpdateItemList = new NativeFunction(ptr(0x867C65A), 'int', ['pointer', 'int', 'int', 'int'], {"abi":"sysv"});

  1058. //获取系统时间
  1059. var CSystemTime_getCurSec = new NativeFunction(ptr(0x80CBC9E), 'int', ['pointer'], {"abi":"sysv"});
  1060. var GlobalData_s_systemTime_ = ptr(0x941F714);

  1061. //怪物攻城
  1062. function VillageAttackedStart(user)
  1063. {
  1064.         var Inter_VillageAttackedCountdown = new NativeFunction(ptr(0x84DFAE0), 'pointer', ['pointer' ,'pointer' ,'pointer'], {"abi":"sysv"});
  1065.         var Inter_VillageAttackedStart_dispatch_sig = new NativeFunction(ptr(0x84DF47A), 'pointer', ['pointer' ,'pointer' ,'pointer'], {"abi":"sysv"});

  1066.         var a3 =Memory.alloc(100);
  1067.         a3.add(10).writeInt(1200);//持续时间按秒计算
  1068.         a3.add(14).writeInt(100);//防御点数
  1069.         a3.add(18).writeInt(100);//成功防守所需点数
  1070.         //Inter_VillageAttackedCountdown(ptr(0),ptr(0),a3);//通知什么时候开始攻城
  1071.         Inter_VillageAttackedStart_dispatch_sig(ptr(0),user,a3);//怪物开始攻城
  1072.         console.log('VillageAttack----------------------------Start');
  1073. }

  1074. //结束怪物攻城
  1075. function VillageAttackedEnd()
  1076. {
  1077.         var Inter_VillageAttackedEnd_dispatch_sig = new NativeFunction(ptr(0x84DF6A4), 'pointer', ['pointer' ,'pointer' ,'pointer'], {"abi":"sysv"});
  1078.         var Inter_VillageAttackedCountdown = new NativeFunction(ptr(0x84DFAE0), 'pointer', ['pointer' ,'pointer' ,'pointer'], {"abi":"sysv"});
  1079.         var Inter_VillageAttackedUpdate = new NativeFunction(ptr(0x84DFBE6), 'pointer', ['pointer' ,'pointer' ,'pointer'], {"abi":"sysv"});
  1080.         var Inter_VillageAttackedScore = new NativeFunction(ptr(0x84DFD16), 'pointer', ['pointer' ,'pointer' ,'pointer'], {"abi":"sysv"});
  1081.         var Inter_VillageAttackedReward = new NativeFunction(ptr(0x84DFEA6), 'pointer', ['pointer' ,'pointer' ,'pointer'], {"abi":"sysv"});
  1082.         var Inter_VillageAttackedReward_send_reward_item =  new NativeFunction(ptr(0x84E0390), 'pointer', ['pointer' ,'pointer' ,'pointer' ,'int'], {"abi":"sysv"});
  1083.         var Inter_VillageAttackedRewardServer = new NativeFunction(ptr(0x84E05C2), 'pointer', [], {"abi":"sysv"});


  1084.         var a3 =Memory.alloc(100);
  1085.         a3.add(10).writeInt(1200);//持续时间按秒计算
  1086.         a3.add(14).writeInt(100);//防御点数
  1087.         a3.add(18).writeInt(100);//成功防御所需点数
  1088.         Inter_VillageAttackedEnd_dispatch_sig(ptr(0),ptr(0),a3);//结束怪物攻城
  1089.         //Inter_VillageAttackedCountdown(ptr(0),ptr(0),a3);
  1090.         //Inter_VillageAttackedUpdate(ptr(0),ptr(0),a3);
  1091.         //Inter_VillageAttackedScore(ptr(0),ptr(0),a3);
  1092.         //Inter_VillageAttackedReward(ptr(0),ptr(0),a3);
  1093.         //Inter_VillageAttackedReward_send_reward_item(ptr(0),ptr(0),a3,ptr(199));
  1094.         Inter_VillageAttackedRewardServer();//关闭逆袭之谷.限时任务
  1095.         console.log('VillageAttack-------------------------End');
  1096. }

  1097. //怪物攻城发送奖励
  1098. function VillageAttackedReward_send_reward_item(user)
  1099. {
  1100.         var Inter_VillageAttackedReward = new NativeFunction(ptr(0x84DFEA6), 'pointer', ['pointer' ,'pointer' ,'pointer'], {"abi":"sysv"});
  1101.         var Inter_VillageAttackedReward_send_reward_item =  new NativeFunction(ptr(0x84E0390), 'pointer', ['pointer' ,'pointer' ,'int' ,'int'], {"abi":"sysv"});
  1102.         var a3 =Memory.alloc(100);
  1103.         a3.add(18).writeInt(100);//成功防御所需点数
  1104.         Inter_VillageAttackedReward(ptr(0),user,a3);
  1105.         //Inter_VillageAttackedReward_send_reward_item(ptr(0),ptr(0),ptr(0),a3);
  1106.         //Inter_VillageAttackedReward *this, CUser *a2, unsigned int a3, int a4
  1107.         console.log('VillageAttackedReward_send_reward_item-------------------------OK');
  1108. }

  1109. //
  1110. function PcroomResponse_IsShutdonTimeOverLogin()
  1111. {
  1112.         Inter_PcroomResponse_IsShutdonTimeOverLogin = new NativeFunction(ptr(0x84DB40E), 'pointer', [], {"abi":"sysv"});
  1113.         Inter_PcroomResponse_IsShutdonTimeOverLogin();
  1114.         console.log('Inter_PcroomResponse_IsShutdonTimeOverLogin');
  1115. }

  1116. //warstart
  1117. function WarRoom_Start()
  1118. {
  1119.         var Inter_WarRoom_Start = new NativeFunction(ptr(0x86BD6D4),'pointer',['pointer'], {"abi":"sysv"});
  1120.         Inter_WarRoom_Start(ptr(0));
  1121. }

  1122. //Warjoin
  1123. function Warroom_join()
  1124. {
  1125.         var Inte_WarRoom_Join = new NativeFunction(ptr(0x86BAE9A),'pointer',['pointer','pointer','int'], {"abi":"sysv"});
  1126.         Inter_WarRoom_Join(ptr(0),user,0);
  1127. }

  1128. //PCroom
  1129. function Pcroom(user)
  1130. {
  1131.         var Inter_PcroomResponse_dispatch_sig =  new NativeFunction(ptr(0x84DB452), 'pointer', ['pointer' ,'pointer' ,'pointer'], {"abi":"sysv"});
  1132.         var a3 =Memory.alloc(100);
  1133.         a3.add(18).writeInt(7);//
  1134.         a3.add(22).writeInt(0);//
  1135.         Inter_PcroomResponse(ptr(0),user,a3);
  1136.         //Inter_PcroomResponse *this, CUser *a2, char *a3
  1137. }

  1138. //CUser::setPcRoomAuth
  1139. function CUser_setPcRoomAuth(user)
  1140. {
  1141.         Inter_CUser_setPcRoomAuth = new NativeFunction(ptr(0x84EC834),'pointer',['pointer' ,'pointer'], {"abi":"sysv"});
  1142.         Inter_CUser_setPcRoomAuth(user,1)
  1143.         console.log('====================================ok')
  1144. }

  1145. //Inter_OnTimeEventRewardStart::dispatch_sig
  1146. function Inter_OnTimeEventRewardStart(user)
  1147. {
  1148.         var Inter_OnTimeEventRewardStart_dispatch_sig = new NativeFunction(ptr(0x84E0DC6), 'pointer', ['pointer' ,'pointer' ,'pointer'], {"abi":"sysv"});
  1149.         var a3 =Memory.alloc(100);
  1150.         a3.add(10).writeInt(0);//
  1151.         a3.add(18).writeInt(100);//
  1152.         a3.add(22).writeInt(100);//
  1153.         a3.add(14).writeInt(100);//
  1154.         Inter_OnTimeEventRewardStart_dispatch_sig(ptr(0),user,a3);
  1155.         console.log('Inter_OnTimeEventRewardStart-------------------------OK');
  1156. }

  1157. //发送邮件
  1158. function SYSTEMMAil()
  1159. {
  1160.         var ReqDBSendNewSystemMail = new NativeFunction(ptr(0x85555E8),'pointer' [''], {"abi":"sysv"});
  1161. /*      char *src,
  1162.            (Inven_Item *)v21,
  1163.            0,
  1164.            CurCharacNo,
  1165.            strlen(&s),
  1166.            strlen,
  1167.            12,
  1168.            ServerGroup,
  1169.            0,
  1170.            0;
  1171. */
  1172. }

  1173. //组队改街头PK

  1174. //var raw_packet_buf = api_PacketBuf_get_byte();


  1175. //获取系统UTC时间(秒)
  1176. function api_CSystemTime_getCurSec()
  1177. {
  1178.         return GlobalData_s_systemTime_.readInt();
  1179. }

  1180. //给角色发经验
  1181. function api_CUser_gain_exp_sp(user, exp)
  1182. {
  1183.         var a2 = Memory.alloc(4);
  1184.         var a3 = Memory.alloc(4);
  1185.         CUser_gain_exp_sp(user, exp, a2, a3, 0, 0, 0);
  1186. }

  1187. //给角色发道具
  1188. function api_CUser_AddItem(user, item_id, item_cnt)
  1189. {
  1190.         var item_space = Memory.alloc(4);
  1191.         var slot = CUser_AddItem(user, item_id, item_cnt, 6, item_space, 0);

  1192.         if(slot >= 0)
  1193.         {
  1194.                 //通知客户端有游戏道具更新
  1195.                 CUser_SendUpdateItemList(user, 1, item_space.readInt(), slot);
  1196.         }

  1197.         return;
  1198. }

  1199. //获取角色名字
  1200. function api_CUserCharacInfo_getCurCharacName(user)
  1201. {
  1202.         var p = CUserCharacInfo_getCurCharacName(user);
  1203.         if(p.isNull())
  1204.         {
  1205.                 return '';
  1206.         }

  1207.         return p.readUtf8String(-1);
  1208. }

  1209. //给角色发消息
  1210. function api_CUser_SendNotiPacketMessage(user, msg, msg_type)
  1211. {
  1212.         var p = Memory.allocUtf8String(msg);
  1213.         CUser_SendNotiPacketMessage(user, p, msg_type);

  1214.         return;
  1215. }

  1216. //发送离线奖励
  1217. function send_offline_reward(user)
  1218. {
  1219.         //当前系统时间
  1220.         var cur_time = api_CSystemTime_getCurSec();

  1221.         //用户上次退出游戏时间
  1222.         var user_last_play_time = CUserCharacInfo_getCurCharacLastPlayTick(user);

  1223.         //新创建的角色首次登陆user_last_play_time为0
  1224.         if(user_last_play_time > 0)
  1225.         {
  1226.                 //离线时长(分钟)
  1227.                 var diff_time = (cur_time - user_last_play_time) / 60;

  1228.                 //离线10min后开始计算
  1229.                 if(diff_time < 10)
  1230.                         return;

  1231.                 //离线奖励最多发送3天
  1232.                 if(diff_time > 3*24*60)
  1233.                         diff_time = 3*24*60;

  1234.                 //经验奖励: 每分钟当前等级经验的0.2%
  1235.                 var REWARD_EXP_PER_MIN = 0.002;
  1236.                 //金币奖励: 每分钟当前等级*100
  1237.                 var REWARD_GOLD_PER_MIN = 100;

  1238.                 //计算奖励
  1239.                 var cur_level = CUserCharacInfo_get_charac_level(user);
  1240.                 var reward_exp = Math.floor(CUserCharacInfo_get_level_up_exp(user, cur_level) * REWARD_EXP_PER_MIN * diff_time);
  1241.                 var reward_gold = Math.floor(cur_level * REWARD_GOLD_PER_MIN * diff_time);

  1242.                 //发经验
  1243.                 api_CUser_gain_exp_sp(user, reward_exp);
  1244.                 //发金币
  1245.                 CInventory_gain_money(CUserCharacInfo_getCurCharacInvenW(user), reward_gold, 0, 0, 0);
  1246.                 //通知客户端有游戏道具更新
  1247.                 CUser_SendUpdateItemList(user, 1, 0, 0);

  1248.                 //发消息通知客户端奖励已发送
  1249.                 //api_CUser_SendNotiPacketMessage(user, '离线奖励已发送(经验奖励:' + reward_exp + ', 金币奖励:' + reward_gold + ')', 6);
  1250.         }
  1251. }

  1252. //发送每日首次登陆奖励
  1253. function send_first_login_reward(user)
  1254. {
  1255.         //奖励道具列表(道具id, 每级奖励数量)
  1256.         var REWARD_LIST = [[8, 0.1], [3037, 10]];

  1257.         //获取玩家登录
  1258.         var cur_level = CUserCharacInfo_get_charac_level(user);
  1259.         for(var i=0; i<REWARD_LIST.length; i++)
  1260.         {
  1261.                 //道具id
  1262.                 var reward_item_id = REWARD_LIST[i][0];
  1263.                 //道具数量
  1264.                 var reward_item_cnt = 1 + Math.floor((cur_level * REWARD_LIST[i][1]));

  1265.                 //发送道具到玩家背包
  1266.                 api_CUser_AddItem(user, reward_item_id, reward_item_cnt);
  1267.         }
  1268. }

  1269. //角色登入登出处理
  1270. function hook_user_inout_game_world()
  1271. {
  1272.         //选择角色处理函数 Hook GameWorld::reach_game_world
  1273.         Interceptor.attach(ptr(0x86C4E50), {
  1274.                 //函数入口, 拿到函数参数args
  1275.                 onEnter: function (args) {
  1276.                         //保存函数参数
  1277.                         this.user = args[1];

  1278.                         //console.log('[GameWorld::reach_game_world] this.user=' + this.user);
  1279.                 },
  1280.                 //原函数执行完毕, 这里可以得到并修改返回值retval
  1281.                 onLeave: function (retval) {
  1282.                         //给角色发消息问候
  1283.             use_ftcoin_change_luck_point(this.user);//开启幸运点
  1284.                         VillageAttackedStart(this.user);//开启怪物攻城
  1285.                         api_CUser_SendNotiPacketMessage(this.user, 'Hello ' + api_CUserCharacInfo_getCurCharacName(this.user), 2);

  1286.                         //离线奖励处理
  1287.                         send_offline_reward(this.user);
  1288.                 }
  1289.         });

  1290.         //角色退出时处理函数 Hook GameWorld::leave_game_world
  1291.         Interceptor.attach(ptr(0x86C5288), {

  1292.                 onEnter: function (args) {

  1293.                         var user = args[1];

  1294.                         //console.log('[GameWorld::leave_game_world] user=' + user);
  1295.                 },
  1296.                 onLeave: function (retval) {
  1297.                 }
  1298.         });
  1299. }

  1300. //角色每日首次登录奖励
  1301. function hook_user_first_login()
  1302. {
  1303.         //角色每日重置处理函数 Hook CUser::AddDailyItem
  1304.         Interceptor.attach(ptr(0x8656CAA), {

  1305.                 onEnter: function (args) {
  1306.                         //保存函数参数
  1307.                         var user = args[0];

  1308.                         //console.log('[CUser::AddDailyItem] user=' + user);

  1309.                         //发送每日首次登陆奖励
  1310.                         send_first_login_reward(user);
  1311.                 },
  1312.                 onLeave: function (retval) {
  1313.                 }
  1314.         });
  1315. }
  1316. //从客户端封包中读取数据
  1317. var PacketBuf_get_byte = new NativeFunction(ptr(0x858CF22), 'int', ['pointer', 'pointer'], {"abi":"sysv"});
  1318. var PacketBuf_get_short = new NativeFunction(ptr(0x858CFC0), 'int', ['pointer', 'pointer'], {"abi":"sysv"});
  1319. var PacketBuf_get_int = new NativeFunction(ptr(0x858D27E), 'int', ['pointer', 'pointer'], {"abi":"sysv"});
  1320. var PacketBuf_get_binary = new NativeFunction(ptr(0x858D3B2), 'int', ['pointer', 'pointer', 'int'], {"abi":"sysv"});

  1321. //服务器组包
  1322. var PacketGuard_PacketGuard = new NativeFunction(ptr(0x858DD4C), 'int', ['pointer'], {"abi":"sysv"});
  1323. var InterfacePacketBuf_put_header = new NativeFunction(ptr(0x80CB8FC), 'int', ['pointer', 'int', 'int'], {"abi":"sysv"});
  1324. var InterfacePacketBuf_put_byte = new NativeFunction(ptr(0x80CB920), 'int', ['pointer', 'uint8'], {"abi":"sysv"});
  1325. var InterfacePacketBuf_put_short = new NativeFunction(ptr(0x80D9EA4), 'int', ['pointer', 'uint16'], {"abi":"sysv"});
  1326. var InterfacePacketBuf_put_int = new NativeFunction(ptr(0x80CB93C), 'int', ['pointer', 'int'], {"abi":"sysv"});
  1327. var InterfacePacketBuf_put_binary = new NativeFunction(ptr(0x811DF08), 'int', ['pointer', 'pointer', 'int'], {"abi":"sysv"});
  1328. var InterfacePacketBuf_finalize = new NativeFunction(ptr(0x80CB958), 'int', ['pointer', 'int'], {"abi":"sysv"});
  1329. var Destroy_PacketGuard_PacketGuard = new NativeFunction(ptr(0x858DE80), 'int', ['pointer'], {"abi":"sysv"});

  1330.   //从客户端封包中读取数据(失败会抛异常, 调用方必须做异常处理)
  1331. function api_PacketBuf_get_byte(packet_buf)
  1332. {
  1333.         var data = Memory.alloc(1);

  1334.         if(PacketBuf_get_byte(packet_buf, data))
  1335.         {
  1336.                 return data.readU8();
  1337.         }

  1338.         throw  new Error('PacketBuf_get_byte Fail!');
  1339. }
  1340. function api_PacketBuf_get_short(packet_buf)
  1341. {
  1342.         var data = Memory.alloc(2);

  1343.         if(PacketBuf_get_short(packet_buf, data))
  1344.         {
  1345.                 return data.readShort();
  1346.         }

  1347.         throw  new Error('PacketBuf_get_short Fail!');
  1348. }
  1349. function api_PacketBuf_get_int(packet_buf)
  1350. {
  1351.         var data = Memory.alloc(4);

  1352.         if(PacketBuf_get_int(packet_buf, data))
  1353.         {
  1354.                 return data.readInt();
  1355.         }


  1356.         throw  new Error('PacketBuf_get_int Fail!');
  1357. }
  1358. function api_PacketBuf_get_binary(packet_buf, len)
  1359. {
  1360.         var data = Memory.alloc(len);

  1361.         if(PacketBuf_get_binary(packet_buf, data, len))
  1362.         {
  1363.                 return data.readByteArray(len);
  1364.         }

  1365.         throw  new Error('PacketBuf_get_binary Fail!');
  1366. }

  1367. //获取原始封包数据
  1368. function api_PacketBuf_get_buf(packet_buf)
  1369. {
  1370.         return packet_buf.add(20).readPointer().add(13);
  1371. }

  1372. //获取GameWorld实例
  1373. var G_GameWorld = new NativeFunction(ptr(0x80DA3A7), 'pointer', [], {"abi":"sysv"});
  1374. //根据server_id查找user
  1375. var GameWorld_find_from_world = new NativeFunction(ptr(0x86C4B9C), 'pointer', ['pointer', 'int'], {"abi":"sysv"});
  1376. //城镇瞬移
  1377. var GameWorld_move_area = new NativeFunction(ptr(0x86C5A84), 'pointer', ['pointer', 'pointer', 'int', 'int', 'int', 'int', 'int', 'int', 'int', 'int', 'int'], {"abi":"sysv"});


  1378. //处理GM信息
  1379. function hook_gm_command()
  1380. {
  1381.         //HOOK Dispatcher_New_Gmdebug_Command::dispatch_sig
  1382.         Interceptor.attach(ptr(0x820BBDE), {

  1383.                 onEnter: function (args) {

  1384.                         //获取原始封包数据
  1385.                         var raw_packet_buf = api_PacketBuf_get_buf(args[2]);

  1386.                         //解析GM DEBUG命令
  1387.                         var msg_len = raw_packet_buf.readInt();                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             
  1388.                         var msg = raw_packet_buf.add(4).readUtf8String(msg_len);

  1389.                         var user = args[1];
  1390.                         console.log('User:' + user);


  1391.                         console.log('Recv_GM_DEBUG_INFO: ['+ api_CUserCharacInfo_getCurCharacName(user) + '] ' + msg);
  1392.                         //去除命令开头的 '//'
  1393.                         msg = msg.slice(2);
  1394.                         if(msg == 'attackstart')
  1395.                         {        //GM模式开启怪物攻城
  1396.                                 VillageAttackedStart(user);
  1397.                                 Inter_OnTimeEventRewardStart(user);
  1398.                         }
  1399.                         else if(msg == 'attackend')
  1400.                         {        //GM模式关闭怪物攻城
  1401.                                 VillageAttackedEnd();
  1402.                                 VillageAttackedReward_send_reward_item(user);
  1403.                         }
  1404.                         else if(msg == 'kick')
  1405.                         {
  1406.                                 //踢掉用户
  1407.                                 api_CUser_SendNotiPacketMessage(user, 'GM踢掉了玩家:'+api_CUserCharacInfo_getCurCharacName(user), 0);
  1408.                                 var kick = new NativeFunction(ptr(0x86489F4), 'int', ['pointer', 'int', 'int', 'int'], {"abi":"sysv"});
  1409.                                 kick(user,60,1,0);
  1410.                                 api_CUser_SendNotiPacketMessage(user, 'GM命令完成', 1);
  1411.                         }
  1412.                         else if(msg.indexOf('move ') == 0)
  1413.                         {
  1414.                                 //城镇瞬移
  1415.                                 var msg_group = msg.split(' ');
  1416.                                 if(msg_group.length == 5)
  1417.                                 {
  1418.                                         var village = parseInt(msg_group[1]);
  1419.                                         var area = parseInt(msg_group[2]);
  1420.                                         var pos_x = parseInt(msg_group[3]);
  1421.                                         var pos_y = parseInt(msg_group[4]);
  1422.                                         GameWorld_move_area(G_GameWorld(), user, village, area, pos_x, pos_y, 0, 0, 0, 0, 0);
  1423.                                         api_CUser_SendNotiPacketMessage(user, 'GM命令完成', 1);
  1424.                                 }
  1425.                                 else
  1426.                                 {
  1427.                                         api_CUser_SendNotiPacketMessage(user, '格式错误. 使用示例: //move 2 1 100 100', 2);
  1428.                                 }
  1429.                         }
  1430.                         else if(msg.indexOf('item ') == 0)
  1431.                         {
  1432.                                 //获得物品
  1433.                                 var msg_group = msg.split(' ');
  1434.                                 if(msg_group.length == 3)
  1435.                                 {
  1436.                                         var item_id = parseInt(msg_group[1]);
  1437.                                         var item_cnt = parseInt(msg_group[2]);
  1438.                                          //发送道具到玩家背包
  1439.                                         api_CUser_AddItem(user, item_id, item_cnt);
  1440.                                         api_CUser_SendNotiPacketMessage(user, 'GM命令完成', 1);
  1441.                                 }
  1442.                                 else
  1443.                                 {
  1444.                                         api_CUser_SendNotiPacketMessage(user, '格式错误. item: //item 1 1', 2);
  1445.                                 }
  1446.                         }
  1447.                 },
  1448.                 onLeave: function (retval) {
  1449.                 }
  1450.         });
  1451. }
  1452.                
  1453.         //允许赛利亚房间的人互相可见
  1454. function share_seria_room()
  1455. {
  1456.         //Hook Area::insert_user
  1457.         Interceptor.attach(ptr(0x86C25A6), {

  1458.                 onEnter: function (args) {
  1459.                         //修改标志位, 让服务器广播赛利亚旅馆消息
  1460.                         args[0].add(0x68).writeInt(0);
  1461.                 },
  1462.                 onLeave: function (retval) {
  1463.                 }
  1464.         });
  1465. }

  1466. //hookCUser::DisConnSig
  1467. function CUser_is_ConnSig()
  1468. {
  1469.                
  1470.         Interceptor.attach(ptr(0x86489F4), {
  1471.         
  1472.                 onEnter: function (args) {
  1473.                         //CUser *a1, int a2, int a3, int a4
  1474.                         console.log("CUserisConnSig--------------------------state:"+args[0],args[1],args[2],args[3]);
  1475.                         var cu =args[0]
  1476.                         //var a2 = args[1].readInt();
  1477.                         //var a3 = args[2].readInt();
  1478.                         //var a4 = args[3].readInt();
  1479.                         //console.log('-' + '-' + '-' + '-' + '-' + '-' + '-' + '-' + '-')
  1480.                 },
  1481.                 onLeave: function (retval) {
  1482.                 }
  1483.         });
  1484. }

  1485. //调用Encrypt解密函数
  1486. var decrypt = new NativeFunction(ptr(0x848DB5E), 'pointer', ['pointer', 'pointer', 'pointer'], {"abi":"sysv"});

  1487. //拦截Encryption::Encrypt
  1488. function hook_encrypt ()
  1489. {
  1490.         Interceptor.attach(ptr(0x848DA70), {
  1491.         
  1492.                 onEnter: function (args) {
  1493.                         console.log("Encrypt:"+args[0],args[1],args[2]);
  1494.                         //var u = a.readUtf8String(args[0])
  1495.                         //console.log(decrypt(args[0],args[1],args[2]));
  1496.                 },
  1497.                 onLeave: function (retval) {
  1498.                 }
  1499.         });
  1500. }

  1501. //拦截Encryption::decrypt
  1502. function hookdecrypt ()
  1503. {
  1504.         Interceptor.attach(ptr(0x848DB5E), {
  1505.         
  1506.                 onEnter: function (args) {
  1507.                         console.log("decrypt:"+args[0],args[1],args[2]);
  1508.                 },
  1509.                 onLeave: function (retval) {
  1510.                 }
  1511.         });
  1512. }

  1513. //拦截encrypt_packet
  1514. function hookencrypt_packet ()
  1515. {
  1516.         Interceptor.attach(ptr(0x858D86A), {
  1517.         
  1518.                 onEnter: function (args) {
  1519.                         console.log("encrypt_packet:"+args[0]);
  1520.                 },
  1521.                 onLeave: function (retval) {
  1522.                 }
  1523.         });
  1524. }

  1525. //拦截DisPatcher_Login
  1526. function DisPatcher_Login()
  1527. {

  1528.         Interceptor.attach(ptr(0x81E8C78), {

  1529.         onEnter: function (args) {
  1530.                 console.log('DisPatcher_Login:' + args[0] , args[1] , args[2] , args[3] , args[4] );
  1531.                 },
  1532.                 onLeave: function (retval) {
  1533.                 }
  1534.         });
  1535. }

  1536. //拦截DisPatcher_ResPeer::dispatch_sig
  1537. function DisPatcher_ResPeer_dispatch_sig()
  1538. {

  1539.         Interceptor.attach(ptr(0x81F088E), {

  1540.         onEnter: function (args) {
  1541.                 console.log('DisPatcher_ResPeer_dispatch_sig:' + args[0] , args[1] , args[2] , args[3] );
  1542.                 },
  1543.                 onLeave: function (retval) {
  1544.                 }
  1545.         });
  1546. }

  1547. //拦截PacketDispatcher::doDispatch
  1548. function PacketDispatcher_doDispatch()
  1549. {

  1550.         Interceptor.attach(ptr(0x8594922), {

  1551.         onEnter: function (args) {
  1552.                 //int a1, CUser *a2, int a3, unsigned __int16 a4, char *a5, signed int a6, int a7, __int16 a8
  1553.                
  1554.                 console.log('PacketDispatcher_doDispatch:' + args[0] , args[1] , args[2] , args[3] , args[4] , args[5] , args[6] , args[7]);
  1555.                 var a1 = args[0].readInt();
  1556.                 console.log(a1);
  1557.                 var a2 = args[1].readInt();
  1558.                 console.log(a2);
  1559.                 //var a3 = args[2].readInt();
  1560.                 //console.log(a3);
  1561.                 //var a4 = args[3].readInt();
  1562.                 //console.log(a4);
  1563.                 var a5 = args[4].readUtf16String(-1);
  1564.                 console.log(a5);
  1565.                 //var a6 = args[5].readInt();
  1566.                 //console.log(a6);
  1567.                 //var a7 = args[6].readInt();
  1568.                 //console.log(a7);
  1569.                 //var a8 = args[7].readInt();
  1570.                 //console.log(a8);
  1571.                 //console.log(a1+'-'+a2+'-'+a3+'-'+a4+'-'+a6+'-'+a7+'-'+a8);
  1572.                 },
  1573.                 onLeave: function (retval) {
  1574.                 }
  1575.         });
  1576. }

  1577. //拦截PacketDispatcher::PacketDispatcher
  1578. function PacketDispatcher_PacketDispatcher()
  1579. {

  1580.         Interceptor.attach(ptr(0x8590A2E), {

  1581.         onEnter: function (args) {
  1582.                 console.log('PacketDispatcher_PacketDispatcher:' + args[0] );
  1583.                 var a1 = args[0].readInt();
  1584.                 },
  1585.                 onLeave: function (retval) {
  1586.                 }
  1587.         });
  1588. }

  1589. //拦截CUser::SendCmdOkPacket
  1590. function CUser_SendCmdOkPacket()
  1591. {

  1592.         Interceptor.attach(ptr(0x867BEA0), {

  1593.         onEnter: function (args) {
  1594.                 console.log('CUser_SendCmdOkPacket:' + args[0] + args[1]);
  1595.                 //var a1 = args[0].readInt();
  1596.                 var a2 = args[0].readInt();
  1597.                 console.log("CUser_SendCmdOkPacket:"+a2);
  1598.                 },
  1599.                 onLeave: function (retval) {
  1600.                 }
  1601.         });
  1602. }

  1603. function start()
  1604. {
  1605.         //开启时装镶嵌
  1606.         fix_use_emblem();
  1607.         console.log('fix_use_emblem--------------------OK');
  1608. }

  1609. rpc.exports = {
  1610.         init: function (stage, parameters) {
  1611.                 console.log('FRida Frame=====================================================load start');
  1612.                 console.log('[init] stage=' + stage + ', parameters=' + JSON.stringify(parameters));

  1613.         //延迟加载插件
  1614.         //awake();

  1615.                 //开启修复绝望之塔
  1616.                 //fix_TOD(true);

  1617.                 //开启在线奖励
  1618.                 enable_online_reward();
  1619.                 console.log('enable_online_reward--------------------OK');
  1620.         
  1621.                 //每日首次登录处理
  1622.                 hook_user_first_login();
  1623.                 console.log('hook_user_first_login--------------------OK');
  1624.         
  1625.                 //开启离线奖励
  1626.                 hook_user_inout_game_world();
  1627.                 console.log('hook_user_inout_game_world--------------------OK');
  1628.         
  1629.                 //捕获游戏事件
  1630.                 hook_history_log();
  1631.                 console.log('hook_history_log--------------------OK');
  1632.         
  1633.                 //开启时装镶嵌
  1634.                 fix_use_emblem();
  1635.                 console.log('fix_use_emblem--------------------OK');
  1636.         
  1637.                 //解除每日角色创建限制
  1638.                 //disable_check_create_character_limit();
  1639.                 //console.log('disable_check_create_character_limit--------------------OK');
  1640.         
  1641.                 //开启怪物攻城
  1642.                 //VillageAttackedStart();
  1643.         
  1644.                 //开启所有角色GM
  1645.                 //hook_check_gm();
  1646.                 //console.log('hook_check_gm--------------------OK');

  1647.                 //hookENcrypt
  1648.                 //hook_encrypt();
  1649.                 //console.log('hook_encrypt--------------------OK');

  1650.                 //hookDEcrypt
  1651.                 //hookdecrypt();

  1652.                 //
  1653.                 //encrypt_packet();

  1654.                 //CUser_SendCmdOkPacket
  1655.                 //CUser_SendCmdOkPacket();
  1656.                 //console.log('CUser_SendCmdOkPacket---------------OK');

  1657.                 //
  1658.                 //CUser_is_ConnSig();
  1659.                 //console.log('CUser_is_ConnSig--------------------OK');

  1660.                 //
  1661.                 //DisPatcher_Login();
  1662.                 //console.log('DisPatcher_Login--------------------OK');

  1663.                 //开启自定义GM命令
  1664.                 //hook_gm_command();
  1665.                 //console.log('hook_gm_command--------------------OK');

  1666.                 //赛利亚房间互相可见
  1667.                 //share_seria_room();
  1668.                 //console.log('share_seria_room---------------------OK');

  1669.                 //
  1670.                 //PacketDispatcher_doDispatch();
  1671.                 //console.log('PacketDispatcher_doDispatch----------------------OK');

  1672.                 //
  1673.                 //DisPatcher_ResPeer_dispatch_sig();
  1674.                 //console.log('DisPatcher_ResPeer_dispatch_sig--------------------OK');

  1675.                 //PacketDispatcher_PacketDispatcher
  1676.                 //PacketDispatcher_PacketDispatcher();
  1677.                 //console.log('PacketDispatcher_PacketDispatcher---------------------OK');

  1678.         console.log('FRida Frame=====================================================load end');
  1679.                 console.log( "    +--------+-------+-------+-------+-------+ ");
  1680.                 console.log( "    + Game FRida Frame running...            + ");
  1681.                 console.log( "    + Start...                               + ");
  1682.                 console.log( "    +--------+-------+-------+-------+-------+ ");
  1683.         },
  1684.         dispose: function () {

  1685.                 console.log('[dispose]');
  1686.         }
  1687. };
复制代码
unvtce.config

  1. {
  2.      "interaction":{
  3.     "type": "script",
  4.     "path": "fuccaic.c",
  5.     "on_change": "reload"
  6.   }
  7. }
复制代码







本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
回复

使用道具 举报

0

主题

129

回帖

143

积分

六品通判

黄金
0
银两
74
金币
14 个

TGL新人活跃会员

发表于 2022-9-10 23:17:40 | 显示全部楼层
刷刷金币,但是还是感谢分享
回复

使用道具 举报

0

主题

140

回帖

146

积分

六品通判

黄金
0
银两
93
金币
6 个

TGL新人活跃会员

发表于 2022-9-13 19:24:27 | 显示全部楼层
哈哈,白嫖就是舒服。
回复

使用道具 举报

0

主题

149

回帖

166

积分

六品通判

黄金
0
银两
86
金币
17 个

TGL新人活跃会员

发表于 2022-9-20 16:14:52 | 显示全部楼层
大家一起刷刷分吧!!!
回复

使用道具 举报

0

主题

140

回帖

146

积分

六品通判

黄金
0
银两
93
金币
6 个

TGL新人活跃会员

发表于 2022-9-23 05:52:24 | 显示全部楼层
看帖回帖是美德
回复

使用道具 举报

0

主题

167

回帖

184

积分

六品通判

黄金
0
银两
100
金币
17 个

TGL新人活跃会员

发表于 2022-9-23 19:28:10 | 显示全部楼层
贪玩有你更精彩
回复

使用道具 举报

0

主题

148

回帖

165

积分

六品通判

黄金
0
银两
89
金币
17 个

TGL新人活跃会员

发表于 2022-9-26 22:45:16 | 显示全部楼层
念了十几年书,还是幼儿园。
回复

使用道具 举报

0

主题

179

回帖

189

积分

六品通判

黄金
0
银两
112
金币
10 个

TGL新人活跃会员

发表于 2022-9-27 15:05:22 | 显示全部楼层
我是个演员,一看见漂亮mm眼就圆…
回复

使用道具 举报

0

主题

155

回帖

154

积分

六品通判

黄金
0
银两
99
金币
-1 个

TGL新人活跃会员

发表于 2022-10-2 11:32:06 | 显示全部楼层
大家一起刷刷分吧!!!
回复

使用道具 举报

0

主题

144

回帖

151

积分

六品通判

黄金
0
银两
85
金币
7 个

TGL新人活跃会员

发表于 2022-10-4 18:51:53 | 显示全部楼层
好东西,真的很不错
回复

使用道具 举报

0

主题

186

回帖

208

积分

六品通判

黄金
0
银两
109
金币
22 个

TGL新人活跃会员

发表于 2022-10-5 19:44:06 | 显示全部楼层
贪玩有你更精彩
回复

使用道具 举报

0

主题

137

回帖

148

积分

六品通判

黄金
0
银两
87
金币
11 个

TGL新人活跃会员

发表于 2022-10-11 17:19:50 | 显示全部楼层
与其混,与其熬,不如二,不如飙。
回复

使用道具 举报

0

主题

140

回帖

154

积分

六品通判

黄金
0
银两
73
金币
14 个

TGL新人活跃会员

发表于 2022-10-13 06:49:28 | 显示全部楼层
刷刷金币,但是还是感谢分享
回复

使用道具 举报

0

主题

142

回帖

153

积分

六品通判

黄金
0
银两
84
金币
11 个

TGL新人活跃会员

发表于 2022-10-17 02:19:41 | 显示全部楼层
有些事,总能让你看清一些人,放下一些执着!
回复

使用道具 举报

0

主题

141

回帖

151

积分

六品通判

黄金
0
银两
92
金币
10 个

TGL新人活跃会员

发表于 2022-10-17 02:33:22 | 显示全部楼层
有些事,总能让你看清一些人,放下一些执着!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

举报|手机版|TGL游戏爱好者 渝ICP备2021011488号-2 |网站地图

GMT+8, 2024-5-13 03:02 , Processed in 0.120942 second(s), 18 queries , Redis On.

Powered by Discuz! W1.0

Cpoyright © 2001-2024 Discuz! Team.

关灯 在本版发帖QQ客服返回顶部
快速回复 返回顶部 返回列表