DOF攻城镶嵌教程
LD_PRELOAD=/bin/unvtce.so ./df_game_r siroco11 start &上面加入到RUN里面即可。但是要搭配DP使用。然后bin目录自创文件。代码我按照顺序去写直接复制就好。
fuccaic.c
unvtce.config
unvtce.so
/*
读写任意内存: js通过NativePointer类可以操作内存, 除了读写内存该类提供了很多实用的接口, 包括修改内存保护属性, 特征码搜索, 从内存中读取字符串等.
hook任意函数: js通过Interceptor.attach接口可以实现对汇编的hook. 使用该接口时不必考虑32位或者64位程序, 也不必考虑被hook函数的调用约定, 甚至可以在函数内部进行hook.
通过Interceptor.attach可以拿到函数的入参和返回值, 并可以对函数返回值进行修改.
此外还可以使用更高级的Interceptor.replace接口, 该接口可以重写被hook的函数, 彻底改变程序执行流程.
执行任意函数: js通过NativeFunction类, 可以在js脚本内执行游戏进程内的所有C函数.
整数用readInt()读utf8字符串用readUtf8String(-1)读 utf16用readUtf16String(-1)读
linux平台: 修改run脚本, 添加LD_PRELOAD启动df_game_r, 即:
LD_PRELOAD=./frida-gadget-12.11.13-linux-x86.so ./df_game_r siroco11 start &
windows平台, 将frida-gadget-15.1.27-windows-x86.dll放到游戏目录下, 使用补丁大合集自带的注入dll功能在游戏进程启动时注入
frida 官网地址: https://frida.re
frida提供的js api接口文档地址: https://frida.re/docs/javascript-api/
linux平台下载地址:https://github.com/frida/frida/releases/download/12.11.13/frida-gadget-12.11.13-linux-x86.so.xz
windows平台下载地址:https://github.com/frida/frida/releases/download/15.1.27/frida-gadget-15.1.27-windows-x86.dll.xz
作者:初级程序员_ https://www.bilibili.com/read/cv17379503?spm_id_from=333.999.list.card_article.click
出处:bilibili
看雪: https://bbs.pediy.com/user-905049.htm
*/
//本地时间戳
function get_timestamp()
{
var date = new Date();
date = new Date(date.setHours(date.getHours() + 10)); //转换到本地时间
var year = date.getFullYear().toString();
var month = (date.getMonth() + 1).toString();
var day = date.getDate().toString();
var hour = date.getHours().toString();
var minute = date.getMinutes().toString();
var second = date.getSeconds().toString();
var ms = date.getMilliseconds().toString();
return year + '-' + month + '-' + day + ' ' + hour + ':' + minute + ':' + second;
}
//linux创建文件夹
function api_mkdir(path)
{
var opendir = new NativeFunction(Module.getExportByName(null, 'opendir'), 'int', ['pointer'], {"abi":"sysv"});
var mkdir = new NativeFunction(Module.getExportByName(null, 'mkdir'), 'int', ['pointer', 'int'], {"abi":"sysv"});
var path_ptr = Memory.allocUtf8String(path);
if(opendir(path_ptr))
return true;
return mkdir(path_ptr, 0x1FF);
}
//服务器环境
var G_CEnvironment = new NativeFunction(ptr(0x080CC181), 'pointer', [], {"abi":"sysv"});
//获取当前服务器配置文件名
var CEnvironment_get_file_name = new NativeFunction(ptr(0x80DA39A), 'pointer', ['pointer'], {"abi":"sysv"});
//获取当前频道名
function api_CEnvironment_get_file_name()
{
var filename = CEnvironment_get_file_name(G_CEnvironment());
return filename.readUtf8String(-1);
}
//文件记录日志
var frida_log_dir_path = './frida_log/'
var f_log = null;
var log_day = null;
function log(msg)
{
var date = new Date();
date = new Date(date.setHours(date.getHours() + 10)); //转换到本地时间
var year = date.getFullYear().toString();
var month = (date.getMonth() + 1).toString();
var day = date.getDate().toString();
var hour = date.getHours().toString();
var minute = date.getMinutes().toString();
var second = date.getSeconds().toString();
var ms = date.getMilliseconds().toString();
//日志按日期记录
if((f_log == null) || (log_day != day))
{
api_mkdir(frida_log_dir_path);
f_log = new File(frida_log_dir_path + 'frida_' + api_CEnvironment_get_file_name() + '_' + year + '_' + month + '_' + day + '.log', 'a+');
log_day = day;
}
//时间戳
var timestamp = year + '-' + month + '-' + day + ' ' + hour + ':' + minute + ':' + second + '.' + ms;
//控制台日志
console.log('[' + timestamp + ']' + msg + '\n');
//文件日志
f_log.write('[' + timestamp + ']' + msg + '\n');
//立即写日志到文件中
f_log.flush();
}
//生成随机整数(不包含max)
function get_random_int(min, max)
{
return Math.floor(Math.random() * (max - min)) + min;
}
//内存十六进制打印
function bin2hex(p, len)
{
var hex = '';
for(var i = 0; i < len; i++)
{
var s = p.add(i).readU8().toString(16);
if(s.length == 1)
s = '0' + s;
hex += s;
if (i != len - 1)
hex += ' ';
}
return hex;
}
//延迟加载插件
function awake()
{
//Hook check_argv
Interceptor.attach(ptr(0x829EA5A), {
onEnter: function (args) {
},
onLeave: function (retval) {
//等待check_argv函数执行结束 再加载插件
start();
}
});
}
//所有账号角色开启GM权限
function hook_check_gm()
{
//GM账户
//WongWork::CGMAccounts::isGM
Interceptor.attach(ptr(0x8109346), {
onEnter: function (args) {
},
onLeave: function (retval) {
//强制返回true
retval.replace(1);
}
});
//GM角色
//CUser::isGMUser
Interceptor.attach(ptr(0x814589C), {
onEnter: function (args) {
},
onLeave: function (retval) {
//强制返回true
retval.replace(1);
}
});
}
//解除每日创建角色数量限制
function disable_check_create_character_limit()
{
//DB_CreateCharac::CheckLimitCreateNewCharac
Interceptor.attach(ptr(0x8401922), {
onEnter: function (args) {
},
onLeave: function (retval) {
//强制返回允许创建
retval.replace(1);
}
});
}
//获取副本id
var CDungeon_get_index = new NativeFunction(ptr(0x080FDCF0),'int', ['pointer'], {"abi":"sysv"});
//修复绝望之塔
//skip_user_apc: 为true时, 跳过每10层的UserAPC
function fix_TOD(skip_user_apc)
{
//每日进入次数限制
//TOD_UserState::getEnterCount
Interceptor.attach(ptr(0x08643872), {
onEnter: function (args) {
//今日已进入次数强制清零
args.add(0x10).writeInt(0);
},
onLeave: function (retval) {
}
});
//每10层挑战玩家APC 服务器内角色不足10个无法进入
if(skip_user_apc)
{
//跳过10/20/.../90层
//TOD_UserState::getTodayEnterLayer
Interceptor.attach(ptr(0x0864383E), {
onEnter: function (args) {
//绝望之塔当前层数
var today_enter_layer = args.add(0x14).readShort();
if(((today_enter_layer%10) == 9) && (today_enter_layer > 0) && (today_enter_layer < 100))
{
//当前层数为10的倍数时直接进入下一层
args.add(0x14).writeShort(today_enter_layer + 1);
}
},
onLeave: function (retval) {
}
});
}
//修复金币异常
//CParty::UseAncientDungeonItems
var CParty_UseAncientDungeonItems_ptr = ptr(0x859EAC2);
var CParty_UseAncientDungeonItems = new NativeFunction(CParty_UseAncientDungeonItems_ptr,'int', ['pointer', 'pointer', 'pointer', 'pointer'], {"abi":"sysv"});
Interceptor.replace(CParty_UseAncientDungeonItems_ptr, new NativeCallback(function (party, dungeon, inven_item, a4) {
//当前进入的地下城id
var dungeon_index = CDungeon_get_index(dungeon);
//根据地下城id判断是否为绝望之塔
if((dungeon_index >= 11008) && (dungeon_index <= 11107))
{
//绝望之塔 不再扣除金币
return 1;
}
//其他副本执行原始扣除道具逻辑
return CParty_UseAncientDungeonItems(party, dungeon, inven_item, a4);
}, 'int', ['pointer', 'pointer', 'pointer', 'pointer']));
}
//根据账号查找已登录角色
var GameWorld_find_user_from_world_byaccid = new NativeFunction(ptr(0x86C4D40), 'pointer', ['pointer', 'int'], {"abi":"sysv"});
//获取玩家任务信息
var CUser_getCurCharacQuestW = new NativeFunction(ptr(0x814AA5E),'pointer', ['pointer'], {"abi":"sysv"});
//任务相关操作(第二个参数为协议编号: 33=接受任务, 34=放弃任务, 35=任务完成条件已满足, 36=提交任务领取奖励)
var CUser_quest_action = new NativeFunction(ptr(0x0866DA8A),'int', ['pointer', 'int', 'int', 'int', 'int'], {"abi":"sysv"});
//发包给客户端
var CUser_Send = new NativeFunction(ptr(0x86485BA), 'int', ['pointer', 'pointer'], {"abi":"sysv"});
//设置GM完成任务模式(无条件完成任务)
var CUser_setGmQuestFlag = new NativeFunction(ptr(0x822FC8E),'int', ['pointer', 'int'], {"abi":"sysv"});
//是否GM任务模式
var CUser_getGmQuestFlag = new NativeFunction(ptr(0x822FC8E),'int', ['pointer'], {"abi":"sysv"});
//通知客户端更新已完成任务列表
var CUser_send_clear_quest_list = new NativeFunction(ptr(0x868B044),'int', ['pointer'], {"abi":"sysv"});
//计算任务基础奖励(不包含道具奖励)
var CUser_quest_basic_reward = new NativeFunction(ptr(0x866E7A8),'int', ['pointer', 'pointer', 'pointer', 'pointer', 'pointer', 'pointer', 'int'], {"abi":"sysv"});
//通知客户端QP更新
var CUser_sendCharacQp = new NativeFunction(ptr(0x868AC24),'int', ['pointer'], {"abi":"sysv"});
//通知客户端QuestPiece更新
var CUser_sendCharacQuestPiece = new NativeFunction(ptr(0x868AF2C),'int', ['pointer'], {"abi":"sysv"});
//获取角色状态
var CUser_get_state = new NativeFunction(ptr(0x80DA38C), 'int', ['pointer'], {"abi":"sysv"});
//通知客户端角色属性更新
var CUser_SendNotiPacket = new NativeFunction(ptr(0x867BA5C), 'int', ['pointer', 'int', 'int', 'int'], {"abi":"sysv"});
//获取DataManager实例
var G_CDataManager = new NativeFunction(ptr(0x80CC19B), 'pointer', [], {"abi":"sysv"});
//从pvf中获取任务数据
var CDataManager_find_quest = new NativeFunction(ptr(0x835FDC6), 'pointer', ['pointer', 'int'], {"abi":"sysv"});
var UserQuest_finish_quest = new NativeFunction(ptr(0x86AC854), 'int', ['pointer', 'int'], {"abi":"sysv"});
//通知客户端更新角色任务列表
var UserQuest_get_quest_info = new NativeFunction(ptr(0x86ABBA8), 'int', ['pointer', 'pointer'], {"abi":"sysv"});
//重置所有任务为未完成状态
var UserQuest_reset = new NativeFunction(ptr(0x86AB894), 'int', ['pointer'], {"abi":"sysv"});
//设置任务为已完成状态
var WongWork_CQuestClear_setClearedQuest = new NativeFunction(ptr(0x808BA78), 'int', ['pointer', 'int'], {"abi":"sysv"});
//重置任务为未完成状态
var WongWork_CQuestClear_resetClearedQuests = new NativeFunction(ptr(0x808BAAC), 'int', ['pointer', 'int'], {"abi":"sysv"});
//任务是否已完成
var WongWork_CQuestClear_isClearedQuest = new NativeFunction(ptr(0x808BAE0), 'int', ['pointer', 'int'], {"abi":"sysv"});
//检测当前角色是否可接该任务
var stSelectQuestParam_stSelectQuestParam = new NativeFunction(ptr(0x83480B4), 'pointer', ['pointer', 'pointer'], {"abi":"sysv"});
var Quest_check_possible = new NativeFunction(ptr(0x8352D86), 'int', ['pointer', 'pointer'], {"abi":"sysv"});
//服务器组包
var PacketGuard_PacketGuard = new NativeFunction(ptr(0x858DD4C), 'int', ['pointer'], {"abi":"sysv"});
var InterfacePacketBuf_put_header = new NativeFunction(ptr(0x80CB8FC), 'int', ['pointer', 'int', 'int'], {"abi":"sysv"});
var InterfacePacketBuf_put_byte = new NativeFunction(ptr(0x80CB920), 'int', ['pointer', 'uint8'], {"abi":"sysv"});
var InterfacePacketBuf_put_short = new NativeFunction(ptr(0x80D9EA4), 'int', ['pointer', 'uint16'], {"abi":"sysv"});
var InterfacePacketBuf_put_int = new NativeFunction(ptr(0x80CB93C), 'int', ['pointer', 'int'], {"abi":"sysv"});
var InterfacePacketBuf_put_binary = new NativeFunction(ptr(0x811DF08), 'int', ['pointer', 'pointer', 'int'], {"abi":"sysv"});
var InterfacePacketBuf_finalize = new NativeFunction(ptr(0x80CB958), 'int', ['pointer', 'int'], {"abi":"sysv"});
var Destroy_PacketGuard_PacketGuard = new NativeFunction(ptr(0x858DE80), 'int', ['pointer'], {"abi":"sysv"});
//服务器组包
function api_PacketGuard_PacketGuard()
{
var packet_guard = Memory.alloc(0x20000);
PacketGuard_PacketGuard(packet_guard);
return packet_guard;
}
//无条件完成指定任务并领取奖励
function api_force_clear_quest(user, quest_id)
{
//设置GM完成任务模式(无条件完成任务)
CUser_setGmQuestFlag(user, 1);
//接受任务
CUser_quest_action(user, 33, quest_id, 0, 0);
//完成任务
CUser_quest_action(user, 35, quest_id, 0, 0);
//领取任务奖励(倒数第二个参数表示领取奖励的编号, -1=领取不需要选择的奖励; 0=领取可选奖励中的第1个奖励; 1=领取可选奖励中的第二个奖励)
CUser_quest_action(user, 36, quest_id, -1, 1);
//服务端有反作弊机制: 任务完成时间间隔不能小于1秒.这里将上次任务完成时间清零 可以连续提交任务
user.add(0x79644).writeInt(0);
//关闭GM完成任务模式(不需要材料直接完成)
CUser_setGmQuestFlag(user, 0);
return;
}
//重置所有任务(需要小退重新选择角色刷新)
function api_reset_all_quest(user)
{
var user_quest = CUser_getCurCharacQuestW(user);
//清空已接任务列表
for(var i=0; i<20; i++)
{
user_quest.add(4 * (i + 7500 + 2)).writeInt(0);
}
//所有任务设置未完成状态
for(var i=0; i<29999; i++)
{
WongWork_CQuestClear_resetClearedQuests(user_quest.add(4), i);
}
api_CUser_SendNotiPacketMessage(user, '所有任务已重置, 请重新选择角色刷新任务列表!', 14);
}
//完成当前已接任务并领取奖励
function clear_doing_quest(user)
{
//玩家任务信息
var user_quest = CUser_getCurCharacQuestW(user);
//遍历20个已接任务
//任务列表(保存任务id): user_quest.add(4 * (i + 7500 + 2))
//任务完成状态(0=已满足任务条件): user_quest.add(4 * (i + 7520 + 2))
for(var i=0; i<20; i++)
{
//任务id
var quest_id = user_quest.add(4 * (i + 7500 + 2)).readInt();
if(quest_id > 0)
{
//无条件完成任务并领取奖励
api_force_clear_quest(user, quest_id);
}
}
//通知客户端更新已完成任务列表
CUser_send_clear_quest_list(user);
//通知客户端更新任务列表
var packet_guard = api_PacketGuard_PacketGuard();
UserQuest_get_quest_info(user_quest, packet_guard);
CUser_Send(user, packet_guard);
Destroy_PacketGuard_PacketGuard(packet_guard);
}
//完成角色当前可接的所有任务(仅发送金币/经验/QP等基础奖励 无道具奖励)
var QUEST_GRADE_COMMON_UNIQUE = 5; //任务脚本中字段对应的常量定义 可以在importQuestScript函数中找到
var QUEST_GRADE_NORMALY_REPEAT = 4; //可重复提交的重复任务
var QUEST_GRADE_DAILY = 3; //每日任务
var QUEST_GRADE_EPIC = 0; //史诗任务
function clear_all_quest_by_character_level(user)
{
//log('clear_all_quest_by_character_level start!');
//玩家任务信息
var user_quest = CUser_getCurCharacQuestW(user);
//玩家已完成任务信息
var WongWork_CQuestClear = user_quest.add(4);
//玩家当前等级
var charac_lv = CUserCharacInfo_get_charac_level(user);
//本次完成任务数量
var clear_quest_cnt = 0;
//pvf数据
var data_manager = G_CDataManager();
//首先完成当前已接任务
clear_doing_quest(user);
//完成当前等级所有任务总经验奖励
var total_exp_bonus = 0;
//完成当前等级所有任务总金币奖励
var total_gold_bonus = 0;
//任务点奖励
var total_quest_point_bonus = 0;
var total_quest_piece_bonus = 0;
//任务最大编号: 29999
for(var quest_id=1; quest_id<30000; quest_id++)
{
//跳过已完成的任务
if(WongWork_CQuestClear_isClearedQuest(WongWork_CQuestClear, quest_id))
continue;
//获取任务数据
var quest = CDataManager_find_quest(data_manager, quest_id);
if(!quest.isNull())
{
//任务类型
var quest_grade = quest.add(8).readInt();
//跳过grade为类型的任务(转职等任务)
//跳过可重复提交的任务
//跳过每日任务
if((quest_grade != QUEST_GRADE_COMMON_UNIQUE) && (quest_grade != QUEST_GRADE_NORMALY_REPEAT) && (quest_grade != QUEST_GRADE_DAILY))
{
//判断任务当前是否可接
//var stSelectQuestParam = Memory.alloc(100);
//stSelectQuestParam_stSelectQuestParam(stSelectQuestParam, user);
//if(Quest_check_possible(quest, stSelectQuestParam))
//只判断任务最低等级要求 忽略 职业/前置 等任务要求 可一次性完成当前等级所有任务
var quest_min_lv = quest.add(0x20).readInt();
if(quest_min_lv <= charac_lv)
{
//获取该任务的基础奖励
var exp_bonus = Memory.alloc(4);
var gold_bonus = Memory.alloc(4);
var quest_point_bonus = Memory.alloc(4);
var quest_piece_bonus = Memory.alloc(4);
//QP奖励已直接发送到角色 经验/金币只返回结果需要手动发送
CUser_quest_basic_reward(user,quest, exp_bonus, gold_bonus, quest_point_bonus, quest_piece_bonus, 1);
//统计本次自动完成任务的基础奖励
var exp = exp_bonus.readInt();
var gold = gold_bonus.readInt();
var quest_point = quest_point_bonus.readInt();
var quest_piece = quest_piece_bonus.readInt();
if(exp > 0)
total_exp_bonus += exp;
if(gold > 0)
total_gold_bonus += gold;
if(quest_point > 0)
total_quest_point_bonus += quest_point; //没有字段的任务quest_point=10000
if(quest_piece > 0)
total_quest_piece_bonus += quest_piece;
//将该任务设置为已完成状态
WongWork_CQuestClear_setClearedQuest(user_quest.add(4), quest_id);
//本次自动完成任务计数
clear_quest_cnt++;
}
}
}
}
//通知客户端更新
if(clear_quest_cnt > 0)
{
//发送任务经验奖励
if(total_exp_bonus > 0)
api_CUser_gain_exp_sp(user, total_exp_bonus);
//发送任务金币奖励
if(total_gold_bonus > 0)
CInventory_gain_money(CUserCharacInfo_getCurCharacInvenW(user), total_gold_bonus, 0, 0, 0);
//通知客户端更新奖励数据
if ( CUser_get_state(user) == 3 )
{
CUser_SendNotiPacket(user, 0, 2, 0);
CUser_SendNotiPacket(user, 1, 2, 1);
CUser_SendUpdateItemList(user, 1, 0, 0);
CUser_sendCharacQp(user);
CUser_sendCharacQuestPiece(user);
}
//通知客户端更新已完成任务列表
CUser_send_clear_quest_list(user);
//通知客户端更新任务列表
var packet_guard = api_PacketGuard_PacketGuard();
UserQuest_get_quest_info(user_quest, packet_guard);
CUser_Send(user, packet_guard);
Destroy_PacketGuard_PacketGuard(packet_guard);
//公告通知客户端本次自动完成任务数据
api_CUser_SendNotiPacketMessage(user, '已自动完成当前等级任务数量: ' + clear_quest_cnt, 14);
api_CUser_SendNotiPacketMessage(user, '任务经验奖励: ' + total_exp_bonus, 14);
api_CUser_SendNotiPacketMessage(user, '任务金币奖励: ' + total_gold_bonus, 14);
api_CUser_SendNotiPacketMessage(user, '任务QuestPoint奖励: ' + total_quest_point_bonus, 14);
api_CUser_SendNotiPacketMessage(user, '任务QuestPiece奖励: ' + total_quest_piece_bonus, 14);
}
//log('clear_all_quest_by_character_level end!');
return;
}
//捕获玩家游戏事件
function hook_history_log()
{
//cHistoryTrace::operator()
Interceptor.attach(ptr(0x854F990), {
onEnter: function (args) {
//解析日志内容: "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"
var history_log = args.readUtf8String(-1);
var group = history_log.split(',');
//角色信息
var account_id = parseInt(group);
var time_hh_mm_ss = group;
var charac_name = group;
var charac_no = group;
var charac_level = group;
var charac_job = group;
var charac_growtype = group;
var user_web_address = group;
var user_peer_ip2 = group;
var user_port = group;
var channel_index = group; //当前频道id
//玩家游戏事件
var game_event = group.slice(1); //删除多余空格
//触发游戏事件的角色
var user = GameWorld_find_user_from_world_byaccid(G_GameWorld(), account_id);
if(user.isNull())
return;
//道具减少:Item-,1,10000113,63,1,3,63,0,0,0,0,0,0000000000000000000000000000,0,0,00000000000000000000
if(game_event == 'Item-')
{
var item_id = parseInt(group); //本次操作道具id
var item_cnt = parseInt(group); //本次操作道具数量
var reason = parseInt(group); //本次操作原因
//log('玩家[' + charac_name + ']道具减少, 原因:' + reason + '(道具id=' + item_id + ', 使用数量=' + item_cnt);
if(5 == reason)
{
//丢弃道具
}
else if(3 == reason)
{
//
//使用道具
//
//这里并未改变道具原始效果 原始效果成功执行后触发下面的代码
if(10000113 == item_id)
{
//任务完成券
clear_doing_quest(user);
}
}
else if(9 == reason)
{
//分解道具
}
else if(10 == reason)
{
//使用属性石头
}
}
else if(game_event == 'KillMob')
{
//杀死怪物
//魔法封印装备词条升级
boost_random_option_equ(user);
}
else if(game_event == 'Money+')
{
var cur_money = parseInt(group); //当前持有的金币数量
var add_money = parseInt(group); //本次获得金币数量
var reason = parseInt(group); //本次获得金币原因
//log('玩家[' + charac_name + ']获取金币, 原因:' + reason + '(当前持有金币=' + cur_money + ', 本次获得金币数量=' + add_money);
if(4 == reason)
{
//副本拾取
}
else if(5 == reason)
{
//副本通关翻牌获取金币
}
}
else if(game_event == 'DungeonLeave')
{
//离开副本
//刷完副本后, 重置异界+极限祭坛次数
CUser_DimensionInoutUpdate(user, 1, 1);
}
},
onLeave: function (retval) {
}
});
}
//重置异界/极限祭坛次数
var CUser_DimensionInoutUpdate = new NativeFunction(ptr(0x8656C12),'int', ['pointer', 'int', 'int'], {"abi":"sysv"});
//设置幸运点数
var CUserCharacInfo_SetCurCharacLuckPoint = new NativeFunction(ptr(0x0864670A), 'int', ['pointer', 'int'], {"abi":"sysv"});
//获取角色当前幸运点
var CUserCharacInfo_GetCurCharacLuckPoint = new NativeFunction(ptr(0x822F828), 'int', ['pointer'], {"abi":"sysv"});
//设置角色属性改变脏标记(角色上线时把所有属性从数据库缓存到内存中, 只有设置了脏标记, 角色下线时才能正确存档到数据库, 否则变动的属性下线后可能会回档)
var CUserCharacInfo_enableSaveCharacStat = new NativeFunction(ptr(0x819A870), 'int', ['pointer'], {"abi":"sysv"});
//幸运点上下限
var MAX_LUCK_POINT = 99999;
var MIN_LUCK_POINT = 1;
//设置角色幸运点
function api_CUserCharacInfo_SetCurCharacLuckPoint(user, new_luck_point)
{
if(new_luck_point > MAX_LUCK_POINT)
new_luck_point = MAX_LUCK_POINT;
else if(new_luck_point < MIN_LUCK_POINT)
new_luck_point = MIN_LUCK_POINT;
CUserCharacInfo_enableSaveCharacStat(user);
CUserCharacInfo_SetCurCharacLuckPoint(user, new_luck_point);
return new_luck_point;
}
//使用命运硬币后, 可以改变自身幸运点
//查询角色当前幸运点GM命令: //show lp
//当前角色幸运点拉满GM命令: //max lp
function use_ftcoin_change_luck_point(user)
{
//抛命运硬币
var rand = get_random_int(0, 100);
//当前幸运点数
var new_luck_point = null;
if(rand == 0)
{
//1%几率将玩家幸运点充满(最大值10W)
new_luck_point = MAX_LUCK_POINT;
}
else if(rand == 1)
{
//1%几率将玩家幸运点耗尽
new_luck_point = MIN_LUCK_POINT;
}
else if(rand < 51)
{
//49%几率当前幸运点增加20%
new_luck_point = Math.floor(CUserCharacInfo_GetCurCharacLuckPoint(user) * 1.2);
}
else
{
//49%几率当前幸运点降低20%
new_luck_point = Math.floor(CUserCharacInfo_GetCurCharacLuckPoint(user) * 0.8);
}
//修改角色幸运点
new_luck_point = api_CUserCharacInfo_SetCurCharacLuckPoint(user, new_luck_point);
//通知客户端当前角色幸运点已改变
api_CUser_SendNotiPacketMessage(user, '命运已被改变, 当前幸运点数: ' + new_luck_point, 0);
}
//使用角色幸运值加成装备爆率
function enable_drop_use_luck_piont()
{
//由于roll点爆装函数拿不到user, 在杀怪和翻牌函数入口保存当前正在处理的user
var cur_luck_user = null;
//DisPatcher_DieMob::dispatch_sig
Interceptor.attach(ptr(0x81EB0C4), {
onEnter: function (args) {
cur_luck_user = args;
},
onLeave: function (retval) {
cur_luck_user = null;
}
});
//CParty::SetPlayResult
Interceptor.attach(ptr(0x85B2412), {
onEnter: function (args) {
cur_luck_user = args;
},
onLeave: function (retval) {
cur_luck_user = null;
}
});
//修改决定出货品质(rarity)的函数 使出货率享受角色幸运值加成
//CLuckPoint::GetItemRarity
var CLuckPoint_GetItemRarity_ptr = ptr(0x8550BE4);
var CLuckPoint_GetItemRarity = new NativeFunction(CLuckPoint_GetItemRarity_ptr,'int', ['pointer', 'pointer', 'int', 'int'], {"abi":"sysv"});
Interceptor.replace(CLuckPoint_GetItemRarity_ptr, new NativeCallback(function (a1, a2, roll, a4) {
//使用角色幸运值roll点代替纯随机roll点
if(cur_luck_user)
{
//获取当前角色幸运值
var luck_point = CUserCharacInfo_GetCurCharacLuckPoint(cur_luck_user);
//roll点范围1-100W, roll点越大, 出货率越高
//角色幸运值范围1-10W
//使用角色 [当前幸运值*10] 作为roll点下限, 幸运值越高, roll点越大
roll = get_random_int(luck_point*10, 1000000);
}
//执行原始计算爆装品质函数
var rarity = CLuckPoint_GetItemRarity(a1, a2, roll, a4);
//调整角色幸运值
if(cur_luck_user)
{
var rate = 1.0;
//出货粉装以上, 降低角色幸运值
if(rarity >= 3)
{
//出货品质越高, 幸运值下降约快
rate = 1 - (rarity*0.01);
}
else
{
//未出货时, 提升幸运值
rate = 1.01;
}
//设置新的幸运值
var new_luck_point = Math.floor(CUserCharacInfo_GetCurCharacLuckPoint(cur_luck_user) * rate);
api_CUserCharacInfo_SetCurCharacLuckPoint(cur_luck_user, new_luck_point);
}
return rarity;
}, 'int', ['pointer', 'pointer', 'int', 'int']));
}
//获取背包槽中的道具
var INVENTORY_TYPE_BODY = 0; //身上穿的装备
var INVENTORY_TYPE_ITEM = 1; //物品栏
var INVENTORY_TYPE_AVARTAR = 2; //时装栏
var CInventory_GetInvenRef = new NativeFunction(ptr(0x84FC1DE), 'pointer', ['pointer', 'int', 'int'], {"abi":"sysv"});
//检查背包中道具是否为空
var Inven_Item_isEmpty = new NativeFunction(ptr(0x811ED66), 'int', ['pointer'], {"abi":"sysv"});
//获取背包中道具item_id
var Inven_Item_getKey = new NativeFunction(ptr(0x850D14E), 'int', ['pointer'], {"abi":"sysv"});
//道具是否是装备
var Inven_Item_isEquipableItemType = new NativeFunction(ptr(0x08150812), 'int', ['pointer'], {"abi":"sysv"});
//获取装备pvf数据
var CDataManager_find_item = new NativeFunction(ptr(0x835FA32), 'pointer', ['pointer', 'int'], {"abi":"sysv"});
//是否魔法封印装备
var CEquipItem_IsRandomOption = new NativeFunction(ptr(0x8514E5E), 'int', ['pointer'], {"abi":"sysv"});
//解封魔法封印
var random_option_CRandomOptionItemHandle_give_option = new NativeFunction(ptr(0x85F2CC6),'int', ['pointer', 'int', 'int', 'int', 'int', 'int', 'pointer'], {"abi":"sysv"});
//获取装备品级
var CItem_get_rarity = new NativeFunction(ptr(0x080F12D6), 'int', ['pointer'], {"abi":"sysv"});
//获取装备可穿戴等级
var CItem_getUsableLevel = new NativeFunction(ptr(0x80F12EE), 'int', ['pointer'], {"abi":"sysv"});
//获取装备
var CItem_getItemGroupName = new NativeFunction(ptr(0x80F1312), 'int', ['pointer'], {"abi":"sysv"});
//获取装备魔法封印等级?
var CEquipItem_GetRandomOptionGrade = new NativeFunction(ptr(0x8514E6E), 'int', ['pointer'], {"abi":"sysv"});
//增加魔法封印装备的魔法封印等级
function _boost_random_option_equ(inven_item)
{
//空装备
if(Inven_Item_isEmpty(inven_item))
return false;
//获取装备当前魔法封印属性
var random_option = inven_item.add(37);
//随机选取一个词条槽
var random_option_slot = get_random_int(0, 3);
//若词条槽已有魔法封印
if(random_option.add(3*random_option_slot).readU8())
{
//每个词条有2个属性值
var value_slot = get_random_int(1, 3);
//当前词条等级
var random_option_level = random_option.add(3*random_option_slot + value_slot).readU8();
if(random_option_level < 0xFF)
{
//1%概率词条等级+1
if(get_random_int(random_option_level, 100000) < 1000)
{
random_option.add(3*random_option_slot + value_slot).writeU8(random_option_level + 1);
return true;
}
}
}
return false;
}
//穿戴中的魔法封印装备词条升级
function boost_random_option_equ(user)
{
//遍历身上的装备 为拥有魔法封印属性的装备提升魔法封印等级
var inven = CUserCharacInfo_getCurCharacInvenW(user);
for(var slot=10; slot<=21; slot++)
{
var inven_item = CInventory_GetInvenRef(inven, INVENTORY_TYPE_BODY, slot);
if(_boost_random_option_equ(inven_item))
{
//通知客户端更新
CUser_SendUpdateItemList(user, 1, 3, slot);
}
}
}
//魔法封印属性转换时可以继承
function change_random_option_inherit()
{
//random_option::CRandomOptionItemHandle::change_option
Interceptor.attach(ptr(0x85F3340), {
onEnter: function (args) {
//保存原始魔法封印属性
this.random_option = args;
//本次变换的属性编号
this.change_random_option_index = args.toInt32();
//记录原始属性
this.random_optio_type = this.random_option.add(3*this.change_random_option_index).readU8();
this.random_optio_value_1 = this.random_option.add(3*this.change_random_option_index + 1).readU8();
this.random_optio_value_2 = this.random_option.add(3*this.change_random_option_index + 2).readU8();
},
onLeave: function (retval) {
//魔法封印转换成功
if(retval == 1)
{
//获取未被附魔的魔法封印槽
var index = -1;
if(this.random_option.add(0).readU8() == 0)
index = 0;
else if(this.random_option.add(3).readU8() == 0)
index = 1;
else if(this.random_option.add(6).readU8() == 0)
index = 2;
//当魔法封印词条不足3个时, 若变换出等级极低的属性, 可直接附魔到装备空的魔法封印槽内
if(index >= 0)
{
if((this.random_option.add(11).readU8() <= 5) && (this.random_option.add(12).readU8() <= 5))
{
//魔法封印附魔
this.random_option.add(3*index).writeU8(this.random_option.add(10).readU8());
this.random_option.add(3*index + 1).writeU8(this.random_option.add(11).readU8());
this.random_option.add(3*index + 2).writeU8(this.random_option.add(12).readU8());
//清空本次变换的属性(可以继续选择其他词条变换)
this.random_option.add(10).writeInt(0);
return;
}
}
//用变换后的词条覆盖原始魔法封印词条
this.random_option.add(3*this.change_random_option_index).writeU8(this.random_option.add(10).readU8());
//若变换后的属性低于原来的值 则继承原有属性值 否则使用变换后的属性
if(this.random_option.add(11).readU8() > this.random_optio_value_1)
this.random_option.add(3*this.change_random_option_index + 1).writeU8(this.random_option.add(11).readU8());
if(this.random_option.add(12).readU8() > this.random_optio_value_2)
this.random_option.add(3*this.change_random_option_index + 2).writeU8(this.random_option.add(12).readU8());
//清空本次变换的属性(可以继续选择其他词条变换)
this.random_option.add(10).writeInt(0);
}
}
});
}
//魔法封印自动解封
function auto_unseal_random_option_equipment(user)
{
//CInventory::insertItemIntoInventory
Interceptor.attach(ptr(0x8502D86), {
onEnter: function (args) {
this.user = args.readPointer();
},
onLeave: function (retval) {
//物品栏新增物品的位置
var slot = retval.toInt32();
if(slot > 0 )
{
//获取道具的角色
var user = this.user;
//角色背包
var inven = CUserCharacInfo_getCurCharacInvenW(user);
//背包中新增的道具
var inven_item = CInventory_GetInvenRef(inven, INVENTORY_TYPE_ITEM, slot);
//过滤道具类型
if(!Inven_Item_isEquipableItemType(inven_item))
return;
//装备id
var item_id = Inven_Item_getKey(inven_item);
//pvf中获取装备数据
var citem = CDataManager_find_item(G_CDataManager(), item_id);
//检查装备是否为魔法封印类型
if(!CEquipItem_IsRandomOption(citem))
return;
//是否已被解除魔法封印(魔法封印前10个字节是否为0)
var random_option = inven_item.add(37);
if(random_option.readU32() || random_option.add(4).readU32() || random_option.add(8).readShort())
{
return;
}
//尝试解除魔法封印
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));
if(ret)
{
//通知客户端有装备更新
CUser_SendUpdateItemList(user, 1, 0, slot);
}
}
}
});
}
//本次登录时间
var CUserCharacInfo_GetLoginTick = new NativeFunction(ptr(0x822F692),'int', ['pointer'], {"abi":"sysv"});
//点券充值
var WongWork_IPG_CIPGHelper_IPGInput = new NativeFunction(ptr(0x80FFCA4),'int', ['pointer', 'pointer', 'int', 'int', 'pointer', 'pointer', 'pointer', 'pointer', 'pointer', 'pointer'], {"abi":"sysv"});
//代币充值
var WongWork_IPG_CIPGHelper_IPGInputPoint = new NativeFunction(ptr(0x80FFFC0),'int', ['pointer', 'pointer','int', 'int', 'pointer', 'pointer'], {"abi":"sysv"});
//同步点券数据库
var WongWork_IPG_CIPGHelper_IPGQuery = new NativeFunction(ptr(0x8100790),'int', ['pointer', 'pointer'], {"abi":"sysv"});
//点券充值 (禁止直接修改billing库所有表字段, 点券相关操作务必调用数据库存储过程!)
function api_recharge_cash_cera(user, amount)
{
//充值
WongWork_IPG_CIPGHelper_IPGInput(ptr(0x941F734).readPointer(), user, 5, amount, ptr(0x8C7FA20), ptr(0x8C7FA20),
Memory.allocUtf8String('GM'), ptr(0), ptr(0), ptr(0));
//通知客户端充值结果
WongWork_IPG_CIPGHelper_IPGQuery(ptr(0x941F734).readPointer(), user);
}
//代币充值 (禁止直接修改billing库所有表字段, 点券相关操作务必调用数据库存储过程!)
function api_recharge_cash_cera_point(user, amount)
{
//充值
WongWork_IPG_CIPGHelper_IPGInputPoint(ptr(0x941F734).readPointer(), user, amount, 4, ptr(0), ptr(0));
//通知客户端充值结果
WongWork_IPG_CIPGHelper_IPGQuery(ptr(0x941F734).readPointer(), user);
}
//在线奖励
function enable_online_reward()
{
//在线每5min发一次奖, 在线时间越长, 奖励越高
//CUser::WorkPerFiveMin
Interceptor.attach(ptr(0x8652F0C), {
onEnter: function (args) {
var user = args;
//当前系统时间
var cur_time = api_CSystemTime_getCurSec();
//本次登录时间
var login_tick = CUserCharacInfo_GetLoginTick(user);
if(login_tick > 0)
{
//在线时长(分钟)
var diff_time = Math.floor((cur_time - login_tick) / 60);
//在线10min后开始计算
if(diff_time < 10)
return;
//在线奖励最多发送1天
if(diff_time > 1*24*60)
return;
//奖励: 每分钟0.1点券
var REWARD_CASH_CERA_PER_MIN = 0.1;
//计算奖励
var reward_cash_cera = Math.floor(diff_time*REWARD_CASH_CERA_PER_MIN);
//发点券
api_recharge_cash_cera(user, reward_cash_cera);
//发消息通知客户端奖励已发送
//api_CUser_SendNotiPacketMessage(user, '[' + get_timestamp() + '] 在线奖励已发送(当前阶段点券奖励:' + reward_cash_cera + ')', 6);
}
},
onLeave: function (retval) {
}
});
}
//获取当前角色id
var CUserCharacInfo_getCurCharacNo = new NativeFunction(ptr(0x80CBC4E), 'int', ['pointer'], {"abi":"sysv"});
//道具是否被锁
var CUser_CheckItemLock = new NativeFunction(ptr(0x8646942), 'int', ['pointer', 'int', 'int'], {"abi":"sysv"});
//道具是否为消耗品
var CItem_is_stackable = new NativeFunction(ptr(0x80F12FA), 'int', ['pointer'], {"abi":"sysv"});
//获取消耗品类型
var CStackableItem_GetItemType = new NativeFunction(ptr(0x8514A84),'int', ['pointer'], {"abi":"sysv"});
//获取徽章支持的镶嵌槽类型
var CStackableItem_getJewelTargetSocket = new NativeFunction(ptr(0x0822CA28),'int', ['pointer'], {"abi":"sysv"});
//获取时装管理器
var CInventory_GetAvatarItemMgrR = new NativeFunction(ptr(0x80DD576), 'pointer', ['pointer'], {"abi":"sysv"});
//获取道具附加信息
var Inven_Item_get_add_info = new NativeFunction(ptr(0x80F783A), 'int', ['pointer'], {"abi":"sysv"});
//获取时装插槽数据
var WongWork_CAvatarItemMgr_getJewelSocketData = new NativeFunction(ptr(0x82F98F8), 'pointer', ['pointer', 'int'], {"abi":"sysv"});
//背包中删除道具(背包指针, 背包类型, 槽, 数量, 删除原因, 记录删除日志)
var CInventory_delete_item = new NativeFunction(ptr(0x850400C), 'int', ['pointer', 'int', 'int', 'int', 'int', 'int'], {"abi":"sysv"});
//时装镶嵌数据存盘
var DB_UpdateAvatarJewelSlot_makeRequest = new NativeFunction(ptr(0x843081C), 'pointer', ['int', 'int', 'pointer'], {"abi":"sysv"});
//获取时装在数据库中的uid
function api_get_avartar_ui_id(avartar)
{
return avartar.add(7).readInt();
}
//设置时装插槽数据(时装插槽数据指针, 插槽, 徽章id)
//jewel_type: 红=0x1, 黄=0x2, 绿=0x4, 蓝=0x8, 白金=0x10
function api_set_JewelSocketData(jewelSocketData, slot, emblem_item_id)
{
if(!jewelSocketData.isNull())
{
//每个槽数据长6个字节: 2字节槽类型+4字节徽章item_id
//镶嵌不改变槽类型, 这里只修改徽章id
jewelSocketData.add(slot*6+2).writeInt(emblem_item_id);
}
return;
}
//修复时装镶嵌
function fix_use_emblem()
{
//Dispatcher_UseJewel::dispatch_sig
Interceptor.attach(ptr(0x8217BD6), {
onEnter: function (args) {
try {
var user = args;
var packet_buf = args;
console.log('收到角色[' + api_CUserCharacInfo_getCurCharacName(user) + ']的镶嵌请求');
console.log('Ptext packet: '+bin2hex(packet_buf.add(20).readPointer(),40));
//校验角色状态是否允许镶嵌
var state = CUser_get_state(user);
if(state != 3)
{
return;
}
//解析packet_buf
//时装所在的背包槽
var avartar_inven_slot = api_PacketBuf_get_short(packet_buf);
console.log(avartar_inven_slot+'---------------------OK');
//时装item_id
var avartar_item_id = api_PacketBuf_get_int(packet_buf);
console.log(avartar_item_id+'---------------------OK');
//本次镶嵌徽章数量
var emblem_cnt = api_PacketBuf_get_byte(packet_buf);
console.log(emblem_cnt+'---------------------OK');
log('avartar_inven_slot=' + avartar_inven_slot + ', avartar_item_id=' + avartar_item_id + ', emblem_cnt=' + emblem_cnt);
//获取时装道具
var inven = CUserCharacInfo_getCurCharacInvenW(user);
var avartar = CInventory_GetInvenRef(inven, INVENTORY_TYPE_AVARTAR, avartar_inven_slot);
//校验时装 数据是否合法
if(Inven_Item_isEmpty(avartar) || (Inven_Item_getKey(avartar) != avartar_item_id) || CUser_CheckItemLock(user, 2, avartar_inven_slot))
{
return;
}
//获取时装插槽数据
var avartar_add_info = Inven_Item_get_add_info(avartar);
var inven_avartar_mgr = CInventory_GetAvatarItemMgrR(inven);
var jewel_socket_data = WongWork_CAvatarItemMgr_getJewelSocketData(inven_avartar_mgr, avartar_add_info);
log('jewel_socket_data=' + jewel_socket_data + ':' + bin2hex(jewel_socket_data, 30));
if(jewel_socket_data.isNull())
{
return;
}
//最多只支持3个插槽
if(emblem_cnt <= 3)
{
var emblems = {};
for(var i=0; i<emblem_cnt; i++)
{
//徽章所在的背包槽
var emblem_inven_slot = api_PacketBuf_get_short(packet_buf);
//徽章item_id
var emblem_item_id = api_PacketBuf_get_int(packet_buf);
//该徽章镶嵌的时装插槽id
var avartar_socket_slot = api_PacketBuf_get_byte(packet_buf);
//log('emblem_inven_slot=' + emblem_inven_slot + ', emblem_item_id=' + emblem_item_id + ', avartar_socket_slot=' + avartar_socket_slot);
//获取徽章道具
var emblem = CInventory_GetInvenRef(inven, INVENTORY_TYPE_ITEM, emblem_inven_slot);
//校验徽章及插槽数据是否合法
if(Inven_Item_isEmpty(emblem) || (Inven_Item_getKey(emblem) != emblem_item_id) || (avartar_socket_slot >= 3))
{
return;
}
//校验徽章是否满足时装插槽颜色要求
//获取徽章pvf数据
var citem = CDataManager_find_item(G_CDataManager(), emblem_item_id);
if(citem.isNull())
{
return;
}
//校验徽章类型
if(!CItem_is_stackable(citem) ||(CStackableItem_GetItemType(citem) != 20))
{
return;
}
//获取徽章支持的插槽
var emblem_socket_type = CStackableItem_getJewelTargetSocket(citem);
//获取要镶嵌的时装插槽类型
var avartar_socket_type = jewel_socket_data.add(avartar_socket_slot*6).readShort();
if(!(emblem_socket_type & avartar_socket_type))
{
//插槽类型不匹配
//log('socket type not match!');
return;
}
emblems = ;
}
//开始镶嵌
for (var avartar_socket_slot in emblems) {
//删除徽章
var emblem_inven_slot = emblems;
CInventory_delete_item(inven, 1, emblem_inven_slot, 1, 8, 1);
//设置时装插槽数据
var emblem_item_id = emblems;
api_set_JewelSocketData(jewel_socket_data, avartar_socket_slot, emblem_item_id);
//log('徽章item_id=' + emblem_item_id + '已成功镶嵌进avartar_socket_slot=' + avartar_socket_slot + '的槽内!');
}
//时装插槽数据存档
DB_UpdateAvatarJewelSlot_makeRequest(CUserCharacInfo_getCurCharacNo(user), api_get_avartar_ui_id(avartar), jewel_socket_data);
//通知客户端时装数据已更新
CUser_SendUpdateItemList(user, 1, 1, avartar_inven_slot);
//回包给客户端
var packet_guard = api_PacketGuard_PacketGuard();
InterfacePacketBuf_put_header(packet_guard, 1, 204);
InterfacePacketBuf_put_int(packet_guard, 1);
InterfacePacketBuf_finalize(packet_guard, 1);
CUser_Send(user, packet_guard);
Destroy_PacketGuard_PacketGuard(packet_guard);
//log('镶嵌请求已处理完成!');
}
} catch (error) {
console.log('fix_use_emblem throw Exception:' + error);
}
},
onLeave: function (retval) {
//返回值改为0不再踢线
retval.replace(0);
}
});
}
//获取角色名字
var CUserCharacInfo_getCurCharacName = new NativeFunction(ptr(0x8101028), 'pointer', ['pointer'], {"abi":"sysv"});
//给角色发消息
var CUser_SendNotiPacketMessage = new NativeFunction(ptr(0x86886CE), 'int', ['pointer', 'pointer', 'int'], {"abi":"sysv"});
//获取角色上次退出游戏时间
var CUserCharacInfo_getCurCharacLastPlayTick = new NativeFunction(ptr(0x82A66AA), 'int', ['pointer'], {"abi":"sysv"});
//获取角色等级
var CUserCharacInfo_get_charac_level = new NativeFunction(ptr(0x80DA2B8), 'int', ['pointer'], {"abi":"sysv"});
//获取角色当前等级升级所需经验
var CUserCharacInfo_get_level_up_exp = new NativeFunction(ptr(0x0864E3BA), 'int', ['pointer', 'int'], {"abi":"sysv"});
//角色增加经验
var CUser_gain_exp_sp = new NativeFunction(ptr(0x866A3FE), 'int', ['pointer', 'int', 'pointer', 'pointer', 'int', 'int', 'int'], {"abi":"sysv"});
//发送道具
var CUser_AddItem = new NativeFunction(ptr(0x867B6D4), 'int', ['pointer', 'int', 'int', 'int', 'pointer', 'int'], {"abi":"sysv"});
//获取角色背包
var CUserCharacInfo_getCurCharacInvenW = new NativeFunction(ptr(0x80DA28E), 'pointer', ['pointer'], {"abi":"sysv"});
//减少金币
var CInventory_use_money = new NativeFunction(ptr(0x84FF54C), 'int', ['pointer', 'int', 'int', 'int'], {"abi":"sysv"});
//增加金币
var CInventory_gain_money = new NativeFunction(ptr(0x84FF29C), 'int', ['pointer', 'int', 'int', 'int', 'int'], {"abi":"sysv"});
//通知客户端道具更新(客户端指针, 通知方式[仅客户端=1, 世界广播=0, 小队=2, war room=3], itemSpace[装备=0, 时装=1], 道具所在的背包槽)
var CUser_SendUpdateItemList = new NativeFunction(ptr(0x867C65A), 'int', ['pointer', 'int', 'int', 'int'], {"abi":"sysv"});
//获取系统时间
var CSystemTime_getCurSec = new NativeFunction(ptr(0x80CBC9E), 'int', ['pointer'], {"abi":"sysv"});
var GlobalData_s_systemTime_ = ptr(0x941F714);
//怪物攻城
function VillageAttackedStart(user)
{
var Inter_VillageAttackedCountdown = new NativeFunction(ptr(0x84DFAE0), 'pointer', ['pointer' ,'pointer' ,'pointer'], {"abi":"sysv"});
var Inter_VillageAttackedStart_dispatch_sig = new NativeFunction(ptr(0x84DF47A), 'pointer', ['pointer' ,'pointer' ,'pointer'], {"abi":"sysv"});
var a3 =Memory.alloc(100);
a3.add(10).writeInt(1200);//持续时间按秒计算
a3.add(14).writeInt(100);//防御点数
a3.add(18).writeInt(100);//成功防守所需点数
//Inter_VillageAttackedCountdown(ptr(0),ptr(0),a3);//通知什么时候开始攻城
Inter_VillageAttackedStart_dispatch_sig(ptr(0),user,a3);//怪物开始攻城
console.log('VillageAttack----------------------------Start');
}
//结束怪物攻城
function VillageAttackedEnd()
{
var Inter_VillageAttackedEnd_dispatch_sig = new NativeFunction(ptr(0x84DF6A4), 'pointer', ['pointer' ,'pointer' ,'pointer'], {"abi":"sysv"});
var Inter_VillageAttackedCountdown = new NativeFunction(ptr(0x84DFAE0), 'pointer', ['pointer' ,'pointer' ,'pointer'], {"abi":"sysv"});
var Inter_VillageAttackedUpdate = new NativeFunction(ptr(0x84DFBE6), 'pointer', ['pointer' ,'pointer' ,'pointer'], {"abi":"sysv"});
var Inter_VillageAttackedScore = new NativeFunction(ptr(0x84DFD16), 'pointer', ['pointer' ,'pointer' ,'pointer'], {"abi":"sysv"});
var Inter_VillageAttackedReward = new NativeFunction(ptr(0x84DFEA6), 'pointer', ['pointer' ,'pointer' ,'pointer'], {"abi":"sysv"});
var Inter_VillageAttackedReward_send_reward_item =new NativeFunction(ptr(0x84E0390), 'pointer', ['pointer' ,'pointer' ,'pointer' ,'int'], {"abi":"sysv"});
var Inter_VillageAttackedRewardServer = new NativeFunction(ptr(0x84E05C2), 'pointer', [], {"abi":"sysv"});
var a3 =Memory.alloc(100);
a3.add(10).writeInt(1200);//持续时间按秒计算
a3.add(14).writeInt(100);//防御点数
a3.add(18).writeInt(100);//成功防御所需点数
Inter_VillageAttackedEnd_dispatch_sig(ptr(0),ptr(0),a3);//结束怪物攻城
//Inter_VillageAttackedCountdown(ptr(0),ptr(0),a3);
//Inter_VillageAttackedUpdate(ptr(0),ptr(0),a3);
//Inter_VillageAttackedScore(ptr(0),ptr(0),a3);
//Inter_VillageAttackedReward(ptr(0),ptr(0),a3);
//Inter_VillageAttackedReward_send_reward_item(ptr(0),ptr(0),a3,ptr(199));
Inter_VillageAttackedRewardServer();//关闭逆袭之谷.限时任务
console.log('VillageAttack-------------------------End');
}
//怪物攻城发送奖励
function VillageAttackedReward_send_reward_item(user)
{
var Inter_VillageAttackedReward = new NativeFunction(ptr(0x84DFEA6), 'pointer', ['pointer' ,'pointer' ,'pointer'], {"abi":"sysv"});
var Inter_VillageAttackedReward_send_reward_item =new NativeFunction(ptr(0x84E0390), 'pointer', ['pointer' ,'pointer' ,'int' ,'int'], {"abi":"sysv"});
var a3 =Memory.alloc(100);
a3.add(18).writeInt(100);//成功防御所需点数
Inter_VillageAttackedReward(ptr(0),user,a3);
//Inter_VillageAttackedReward_send_reward_item(ptr(0),ptr(0),ptr(0),a3);
//Inter_VillageAttackedReward *this, CUser *a2, unsigned int a3, int a4
console.log('VillageAttackedReward_send_reward_item-------------------------OK');
}
//
function PcroomResponse_IsShutdonTimeOverLogin()
{
Inter_PcroomResponse_IsShutdonTimeOverLogin = new NativeFunction(ptr(0x84DB40E), 'pointer', [], {"abi":"sysv"});
Inter_PcroomResponse_IsShutdonTimeOverLogin();
console.log('Inter_PcroomResponse_IsShutdonTimeOverLogin');
}
//warstart
function WarRoom_Start()
{
var Inter_WarRoom_Start = new NativeFunction(ptr(0x86BD6D4),'pointer',['pointer'], {"abi":"sysv"});
Inter_WarRoom_Start(ptr(0));
}
//Warjoin
function Warroom_join()
{
var Inte_WarRoom_Join = new NativeFunction(ptr(0x86BAE9A),'pointer',['pointer','pointer','int'], {"abi":"sysv"});
Inter_WarRoom_Join(ptr(0),user,0);
}
//PCroom
function Pcroom(user)
{
var Inter_PcroomResponse_dispatch_sig =new NativeFunction(ptr(0x84DB452), 'pointer', ['pointer' ,'pointer' ,'pointer'], {"abi":"sysv"});
var a3 =Memory.alloc(100);
a3.add(18).writeInt(7);//
a3.add(22).writeInt(0);//
Inter_PcroomResponse(ptr(0),user,a3);
//Inter_PcroomResponse *this, CUser *a2, char *a3
}
//CUser::setPcRoomAuth
function CUser_setPcRoomAuth(user)
{
Inter_CUser_setPcRoomAuth = new NativeFunction(ptr(0x84EC834),'pointer',['pointer' ,'pointer'], {"abi":"sysv"});
Inter_CUser_setPcRoomAuth(user,1)
console.log('====================================ok')
}
//Inter_OnTimeEventRewardStart::dispatch_sig
function Inter_OnTimeEventRewardStart(user)
{
var Inter_OnTimeEventRewardStart_dispatch_sig = new NativeFunction(ptr(0x84E0DC6), 'pointer', ['pointer' ,'pointer' ,'pointer'], {"abi":"sysv"});
var a3 =Memory.alloc(100);
a3.add(10).writeInt(0);//
a3.add(18).writeInt(100);//
a3.add(22).writeInt(100);//
a3.add(14).writeInt(100);//
Inter_OnTimeEventRewardStart_dispatch_sig(ptr(0),user,a3);
console.log('Inter_OnTimeEventRewardStart-------------------------OK');
}
//发送邮件
function SYSTEMMAil()
{
var ReqDBSendNewSystemMail = new NativeFunction(ptr(0x85555E8),'pointer' [''], {"abi":"sysv"});
/* char *src,
(Inven_Item *)v21,
0,
CurCharacNo,
strlen(&s),
strlen,
12,
ServerGroup,
0,
0;
*/
}
//组队改街头PK
//var raw_packet_buf = api_PacketBuf_get_byte();
//获取系统UTC时间(秒)
function api_CSystemTime_getCurSec()
{
return GlobalData_s_systemTime_.readInt();
}
//给角色发经验
function api_CUser_gain_exp_sp(user, exp)
{
var a2 = Memory.alloc(4);
var a3 = Memory.alloc(4);
CUser_gain_exp_sp(user, exp, a2, a3, 0, 0, 0);
}
//给角色发道具
function api_CUser_AddItem(user, item_id, item_cnt)
{
var item_space = Memory.alloc(4);
var slot = CUser_AddItem(user, item_id, item_cnt, 6, item_space, 0);
if(slot >= 0)
{
//通知客户端有游戏道具更新
CUser_SendUpdateItemList(user, 1, item_space.readInt(), slot);
}
return;
}
//获取角色名字
function api_CUserCharacInfo_getCurCharacName(user)
{
var p = CUserCharacInfo_getCurCharacName(user);
if(p.isNull())
{
return '';
}
return p.readUtf8String(-1);
}
//给角色发消息
function api_CUser_SendNotiPacketMessage(user, msg, msg_type)
{
var p = Memory.allocUtf8String(msg);
CUser_SendNotiPacketMessage(user, p, msg_type);
return;
}
//发送离线奖励
function send_offline_reward(user)
{
//当前系统时间
var cur_time = api_CSystemTime_getCurSec();
//用户上次退出游戏时间
var user_last_play_time = CUserCharacInfo_getCurCharacLastPlayTick(user);
//新创建的角色首次登陆user_last_play_time为0
if(user_last_play_time > 0)
{
//离线时长(分钟)
var diff_time = (cur_time - user_last_play_time) / 60;
//离线10min后开始计算
if(diff_time < 10)
return;
//离线奖励最多发送3天
if(diff_time > 3*24*60)
diff_time = 3*24*60;
//经验奖励: 每分钟当前等级经验的0.2%
var REWARD_EXP_PER_MIN = 0.002;
//金币奖励: 每分钟当前等级*100
var REWARD_GOLD_PER_MIN = 100;
//计算奖励
var cur_level = CUserCharacInfo_get_charac_level(user);
var reward_exp = Math.floor(CUserCharacInfo_get_level_up_exp(user, cur_level) * REWARD_EXP_PER_MIN * diff_time);
var reward_gold = Math.floor(cur_level * REWARD_GOLD_PER_MIN * diff_time);
//发经验
api_CUser_gain_exp_sp(user, reward_exp);
//发金币
CInventory_gain_money(CUserCharacInfo_getCurCharacInvenW(user), reward_gold, 0, 0, 0);
//通知客户端有游戏道具更新
CUser_SendUpdateItemList(user, 1, 0, 0);
//发消息通知客户端奖励已发送
//api_CUser_SendNotiPacketMessage(user, '离线奖励已发送(经验奖励:' + reward_exp + ', 金币奖励:' + reward_gold + ')', 6);
}
}
//发送每日首次登陆奖励
function send_first_login_reward(user)
{
//奖励道具列表(道具id, 每级奖励数量)
var REWARD_LIST = [, ];
//获取玩家登录
var cur_level = CUserCharacInfo_get_charac_level(user);
for(var i=0; i<REWARD_LIST.length; i++)
{
//道具id
var reward_item_id = REWARD_LIST;
//道具数量
var reward_item_cnt = 1 + Math.floor((cur_level * REWARD_LIST));
//发送道具到玩家背包
api_CUser_AddItem(user, reward_item_id, reward_item_cnt);
}
}
//角色登入登出处理
function hook_user_inout_game_world()
{
//选择角色处理函数 Hook GameWorld::reach_game_world
Interceptor.attach(ptr(0x86C4E50), {
//函数入口, 拿到函数参数args
onEnter: function (args) {
//保存函数参数
this.user = args;
//console.log(' this.user=' + this.user);
},
//原函数执行完毕, 这里可以得到并修改返回值retval
onLeave: function (retval) {
//给角色发消息问候
use_ftcoin_change_luck_point(this.user);//开启幸运点
VillageAttackedStart(this.user);//开启怪物攻城
api_CUser_SendNotiPacketMessage(this.user, 'Hello ' + api_CUserCharacInfo_getCurCharacName(this.user), 2);
//离线奖励处理
send_offline_reward(this.user);
}
});
//角色退出时处理函数 Hook GameWorld::leave_game_world
Interceptor.attach(ptr(0x86C5288), {
onEnter: function (args) {
var user = args;
//console.log(' user=' + user);
},
onLeave: function (retval) {
}
});
}
//角色每日首次登录奖励
function hook_user_first_login()
{
//角色每日重置处理函数 Hook CUser::AddDailyItem
Interceptor.attach(ptr(0x8656CAA), {
onEnter: function (args) {
//保存函数参数
var user = args;
//console.log(' user=' + user);
//发送每日首次登陆奖励
send_first_login_reward(user);
},
onLeave: function (retval) {
}
});
}
//从客户端封包中读取数据
var PacketBuf_get_byte = new NativeFunction(ptr(0x858CF22), 'int', ['pointer', 'pointer'], {"abi":"sysv"});
var PacketBuf_get_short = new NativeFunction(ptr(0x858CFC0), 'int', ['pointer', 'pointer'], {"abi":"sysv"});
var PacketBuf_get_int = new NativeFunction(ptr(0x858D27E), 'int', ['pointer', 'pointer'], {"abi":"sysv"});
var PacketBuf_get_binary = new NativeFunction(ptr(0x858D3B2), 'int', ['pointer', 'pointer', 'int'], {"abi":"sysv"});
//服务器组包
var PacketGuard_PacketGuard = new NativeFunction(ptr(0x858DD4C), 'int', ['pointer'], {"abi":"sysv"});
var InterfacePacketBuf_put_header = new NativeFunction(ptr(0x80CB8FC), 'int', ['pointer', 'int', 'int'], {"abi":"sysv"});
var InterfacePacketBuf_put_byte = new NativeFunction(ptr(0x80CB920), 'int', ['pointer', 'uint8'], {"abi":"sysv"});
var InterfacePacketBuf_put_short = new NativeFunction(ptr(0x80D9EA4), 'int', ['pointer', 'uint16'], {"abi":"sysv"});
var InterfacePacketBuf_put_int = new NativeFunction(ptr(0x80CB93C), 'int', ['pointer', 'int'], {"abi":"sysv"});
var InterfacePacketBuf_put_binary = new NativeFunction(ptr(0x811DF08), 'int', ['pointer', 'pointer', 'int'], {"abi":"sysv"});
var InterfacePacketBuf_finalize = new NativeFunction(ptr(0x80CB958), 'int', ['pointer', 'int'], {"abi":"sysv"});
var Destroy_PacketGuard_PacketGuard = new NativeFunction(ptr(0x858DE80), 'int', ['pointer'], {"abi":"sysv"});
//从客户端封包中读取数据(失败会抛异常, 调用方必须做异常处理)
function api_PacketBuf_get_byte(packet_buf)
{
var data = Memory.alloc(1);
if(PacketBuf_get_byte(packet_buf, data))
{
return data.readU8();
}
thrownew Error('PacketBuf_get_byte Fail!');
}
function api_PacketBuf_get_short(packet_buf)
{
var data = Memory.alloc(2);
if(PacketBuf_get_short(packet_buf, data))
{
return data.readShort();
}
thrownew Error('PacketBuf_get_short Fail!');
}
function api_PacketBuf_get_int(packet_buf)
{
var data = Memory.alloc(4);
if(PacketBuf_get_int(packet_buf, data))
{
return data.readInt();
}
thrownew Error('PacketBuf_get_int Fail!');
}
function api_PacketBuf_get_binary(packet_buf, len)
{
var data = Memory.alloc(len);
if(PacketBuf_get_binary(packet_buf, data, len))
{
return data.readByteArray(len);
}
thrownew Error('PacketBuf_get_binary Fail!');
}
//获取原始封包数据
function api_PacketBuf_get_buf(packet_buf)
{
return packet_buf.add(20).readPointer().add(13);
}
//获取GameWorld实例
var G_GameWorld = new NativeFunction(ptr(0x80DA3A7), 'pointer', [], {"abi":"sysv"});
//根据server_id查找user
var GameWorld_find_from_world = new NativeFunction(ptr(0x86C4B9C), 'pointer', ['pointer', 'int'], {"abi":"sysv"});
//城镇瞬移
var GameWorld_move_area = new NativeFunction(ptr(0x86C5A84), 'pointer', ['pointer', 'pointer', 'int', 'int', 'int', 'int', 'int', 'int', 'int', 'int', 'int'], {"abi":"sysv"});
//处理GM信息
function hook_gm_command()
{
//HOOK Dispatcher_New_Gmdebug_Command::dispatch_sig
Interceptor.attach(ptr(0x820BBDE), {
onEnter: function (args) {
//获取原始封包数据
var raw_packet_buf = api_PacketBuf_get_buf(args);
//解析GM DEBUG命令
var msg_len = raw_packet_buf.readInt();
var msg = raw_packet_buf.add(4).readUtf8String(msg_len);
var user = args;
console.log('User:' + user);
console.log('Recv_GM_DEBUG_INFO: ['+ api_CUserCharacInfo_getCurCharacName(user) + '] ' + msg);
//去除命令开头的 '//'
msg = msg.slice(2);
if(msg == 'attackstart')
{ //GM模式开启怪物攻城
VillageAttackedStart(user);
Inter_OnTimeEventRewardStart(user);
}
else if(msg == 'attackend')
{ //GM模式关闭怪物攻城
VillageAttackedEnd();
VillageAttackedReward_send_reward_item(user);
}
else if(msg == 'kick')
{
//踢掉用户
api_CUser_SendNotiPacketMessage(user, 'GM踢掉了玩家:'+api_CUserCharacInfo_getCurCharacName(user), 0);
var kick = new NativeFunction(ptr(0x86489F4), 'int', ['pointer', 'int', 'int', 'int'], {"abi":"sysv"});
kick(user,60,1,0);
api_CUser_SendNotiPacketMessage(user, 'GM命令完成', 1);
}
else if(msg.indexOf('move ') == 0)
{
//城镇瞬移
var msg_group = msg.split(' ');
if(msg_group.length == 5)
{
var village = parseInt(msg_group);
var area = parseInt(msg_group);
var pos_x = parseInt(msg_group);
var pos_y = parseInt(msg_group);
GameWorld_move_area(G_GameWorld(), user, village, area, pos_x, pos_y, 0, 0, 0, 0, 0);
api_CUser_SendNotiPacketMessage(user, 'GM命令完成', 1);
}
else
{
api_CUser_SendNotiPacketMessage(user, '格式错误. 使用示例: //move 2 1 100 100', 2);
}
}
else if(msg.indexOf('item ') == 0)
{
//获得物品
var msg_group = msg.split(' ');
if(msg_group.length == 3)
{
var item_id = parseInt(msg_group);
var item_cnt = parseInt(msg_group);
//发送道具到玩家背包
api_CUser_AddItem(user, item_id, item_cnt);
api_CUser_SendNotiPacketMessage(user, 'GM命令完成', 1);
}
else
{
api_CUser_SendNotiPacketMessage(user, '格式错误. item: //item 1 1', 2);
}
}
},
onLeave: function (retval) {
}
});
}
//允许赛利亚房间的人互相可见
function share_seria_room()
{
//Hook Area::insert_user
Interceptor.attach(ptr(0x86C25A6), {
onEnter: function (args) {
//修改标志位, 让服务器广播赛利亚旅馆消息
args.add(0x68).writeInt(0);
},
onLeave: function (retval) {
}
});
}
//hookCUser::DisConnSig
function CUser_is_ConnSig()
{
Interceptor.attach(ptr(0x86489F4), {
onEnter: function (args) {
//CUser *a1, int a2, int a3, int a4
console.log("CUserisConnSig--------------------------state:"+args,args,args,args);
var cu =args
//var a2 = args.readInt();
//var a3 = args.readInt();
//var a4 = args.readInt();
//console.log('-' + '-' + '-' + '-' + '-' + '-' + '-' + '-' + '-')
},
onLeave: function (retval) {
}
});
}
//调用Encrypt解密函数
var decrypt = new NativeFunction(ptr(0x848DB5E), 'pointer', ['pointer', 'pointer', 'pointer'], {"abi":"sysv"});
//拦截Encryption::Encrypt
function hook_encrypt ()
{
Interceptor.attach(ptr(0x848DA70), {
onEnter: function (args) {
console.log("Encrypt:"+args,args,args);
//var u = a.readUtf8String(args)
//console.log(decrypt(args,args,args));
},
onLeave: function (retval) {
}
});
}
//拦截Encryption::decrypt
function hookdecrypt ()
{
Interceptor.attach(ptr(0x848DB5E), {
onEnter: function (args) {
console.log("decrypt:"+args,args,args);
},
onLeave: function (retval) {
}
});
}
//拦截encrypt_packet
function hookencrypt_packet ()
{
Interceptor.attach(ptr(0x858D86A), {
onEnter: function (args) {
console.log("encrypt_packet:"+args);
},
onLeave: function (retval) {
}
});
}
//拦截DisPatcher_Login
function DisPatcher_Login()
{
Interceptor.attach(ptr(0x81E8C78), {
onEnter: function (args) {
console.log('DisPatcher_Login:' + args , args , args , args , args );
},
onLeave: function (retval) {
}
});
}
//拦截DisPatcher_ResPeer::dispatch_sig
function DisPatcher_ResPeer_dispatch_sig()
{
Interceptor.attach(ptr(0x81F088E), {
onEnter: function (args) {
console.log('DisPatcher_ResPeer_dispatch_sig:' + args , args , args , args );
},
onLeave: function (retval) {
}
});
}
//拦截PacketDispatcher::doDispatch
function PacketDispatcher_doDispatch()
{
Interceptor.attach(ptr(0x8594922), {
onEnter: function (args) {
//int a1, CUser *a2, int a3, unsigned __int16 a4, char *a5, signed int a6, int a7, __int16 a8
console.log('PacketDispatcher_doDispatch:' + args , args , args , args , args , args , args , args);
var a1 = args.readInt();
console.log(a1);
var a2 = args.readInt();
console.log(a2);
//var a3 = args.readInt();
//console.log(a3);
//var a4 = args.readInt();
//console.log(a4);
var a5 = args.readUtf16String(-1);
console.log(a5);
//var a6 = args.readInt();
//console.log(a6);
//var a7 = args.readInt();
//console.log(a7);
//var a8 = args.readInt();
//console.log(a8);
//console.log(a1+'-'+a2+'-'+a3+'-'+a4+'-'+a6+'-'+a7+'-'+a8);
},
onLeave: function (retval) {
}
});
}
//拦截PacketDispatcher::PacketDispatcher
function PacketDispatcher_PacketDispatcher()
{
Interceptor.attach(ptr(0x8590A2E), {
onEnter: function (args) {
console.log('PacketDispatcher_PacketDispatcher:' + args );
var a1 = args.readInt();
},
onLeave: function (retval) {
}
});
}
//拦截CUser::SendCmdOkPacket
function CUser_SendCmdOkPacket()
{
Interceptor.attach(ptr(0x867BEA0), {
onEnter: function (args) {
console.log('CUser_SendCmdOkPacket:' + args + args);
//var a1 = args.readInt();
var a2 = args.readInt();
console.log("CUser_SendCmdOkPacket:"+a2);
},
onLeave: function (retval) {
}
});
}
function start()
{
//开启时装镶嵌
fix_use_emblem();
console.log('fix_use_emblem--------------------OK');
}
rpc.exports = {
init: function (stage, parameters) {
console.log('FRida Frame=====================================================load start');
console.log(' stage=' + stage + ', parameters=' + JSON.stringify(parameters));
//延迟加载插件
//awake();
//开启修复绝望之塔
//fix_TOD(true);
//开启在线奖励
enable_online_reward();
console.log('enable_online_reward--------------------OK');
//每日首次登录处理
hook_user_first_login();
console.log('hook_user_first_login--------------------OK');
//开启离线奖励
hook_user_inout_game_world();
console.log('hook_user_inout_game_world--------------------OK');
//捕获游戏事件
hook_history_log();
console.log('hook_history_log--------------------OK');
//开启时装镶嵌
fix_use_emblem();
console.log('fix_use_emblem--------------------OK');
//解除每日角色创建限制
//disable_check_create_character_limit();
//console.log('disable_check_create_character_limit--------------------OK');
//开启怪物攻城
//VillageAttackedStart();
//开启所有角色GM
//hook_check_gm();
//console.log('hook_check_gm--------------------OK');
//hookENcrypt
//hook_encrypt();
//console.log('hook_encrypt--------------------OK');
//hookDEcrypt
//hookdecrypt();
//
//encrypt_packet();
//CUser_SendCmdOkPacket
//CUser_SendCmdOkPacket();
//console.log('CUser_SendCmdOkPacket---------------OK');
//
//CUser_is_ConnSig();
//console.log('CUser_is_ConnSig--------------------OK');
//
//DisPatcher_Login();
//console.log('DisPatcher_Login--------------------OK');
//开启自定义GM命令
//hook_gm_command();
//console.log('hook_gm_command--------------------OK');
//赛利亚房间互相可见
//share_seria_room();
//console.log('share_seria_room---------------------OK');
//
//PacketDispatcher_doDispatch();
//console.log('PacketDispatcher_doDispatch----------------------OK');
//
//DisPatcher_ResPeer_dispatch_sig();
//console.log('DisPatcher_ResPeer_dispatch_sig--------------------OK');
//PacketDispatcher_PacketDispatcher
//PacketDispatcher_PacketDispatcher();
//console.log('PacketDispatcher_PacketDispatcher---------------------OK');
console.log('FRida Frame=====================================================load end');
console.log( " +--------+-------+-------+-------+-------+ ");
console.log( " + Game FRida Frame running... + ");
console.log( " + Start... + ");
console.log( " +--------+-------+-------+-------+-------+ ");
},
dispose: function () {
console.log('');
}
};unvtce.config
{
"interaction":{
"type": "script",
"path": "fuccaic.c",
"on_change": "reload"
}
}
刷刷金币,但是还是感谢分享 哈哈,白嫖就是舒服。 大家一起刷刷分吧!!! 看帖回帖是美德 贪玩有你更精彩 念了十几年书,还是幼儿园。 我是个演员,一看见漂亮mm眼就圆… 大家一起刷刷分吧!!! 好东西,真的很不错 贪玩有你更精彩 与其混,与其熬,不如二,不如飙。 刷刷金币,但是还是感谢分享 有些事,总能让你看清一些人,放下一些执着! 有些事,总能让你看清一些人,放下一些执着!