挂海论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
 友情提示:文字/图片广告均非网站意见,请担保交易勿直接付款,由此产生的责任自负
玩游戏来117游戏网(H5不下载也能玩手游传奇,吃鸡,竞技都有)不懂社区·好资源不错过·各位资源站大佬欢迎来采集搬运IOS签名/udid证书出售/送证书加群1040456405 ██【我要租此广告位】██
... .
查看: 3935|回复: 10
打印 上一主题 下一主题

[讨论交流] 脱机写作——参考参考

[复制链接]
3正式会员
160/300

160

积分

51

主题

5

听众
已帮网友解决0 个问题
好评
0
贡献
109
海币
2143
交易币
0
跳转到指定楼层
楼主
发表于 2015-2-8 17:29:19 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
提醒:若下载的软件是收费的"请不要付款",可能是骗子,请立即联系本站举报,执意要付款被骗后本站概不负责。(任何交易请走第三方中介,请勿直接付款交易以免被骗!切记).

友情提示:文字/图片广告均非本站意见,请担保交易勿直接付款,由此产生的责任自负!!!↑↑


做的是任务挂,用LUA做功能的,挂中提供接口函数。
由于内挂大部分是HOOK游戏处理封包位置来做相应功能的,所以转脱机算是很方便。因为LUA脚本来做功能的,其实脱机也就是把接口写好就行了。

其实脱机可以抛弃不少封包处理,有很多不明白的封包,只要不和封号有关,不和功能需求有关,直接PASS。


先说点大局, 脱机要做单文档,也就是象游戏一样,一个程序一个客户端,方便管理,也方便写作,为什么呢,全局变量可以随便扔。-


游戏登陆部分,一般是一个帐号验证服务器,一个游戏服务器,然后靠KEY来相互关联,我的逻辑块是:

UINT CGameRobotDlg::MainThreadCyc(LPVOID pVoid)
{//这是一个线程,外部还有个定时器再不停的检测,如果该线程退出了,再继续启动
//这样做可以让帐号退出或者什么意外的,再继续登陆注意上
//注意CreateEvent所创建的句柄,可以控制连接的断开
    if (g_pMainDlg->m_bThreaFlag)//线程还在进行中
        return 1;

//获得启动信息
    CGameRobotDlg* pThis = (CGameRobotDlg*)pVoid;
    int nSel = pThis->m_cServerList.GetCurSel();//选择的服务器
    if (nSel == LB_ERR)
        return 1;
    g_pMainDlg->m_bThreaFlag = TRUE;

    strcpy(pThis->m_LoginConnectIP, g_ServerList[nSel].Address);
    if (szLineServer[0] == 0)
        strcpy(szLineServer, g_ServerList[nSel].Title);
    pThis->GetDlgItem(IDC_EDIT_USER)->GetWindowText(pThis->m_LoginName, 0x20);
    pThis->GetDlgItem(IDC_EDIT_PASS)->GetWindowText(pThis->m_LoginPass, 0x30);
    pThis->GetDlgItem(IDC_Btn_BeginGame)->EnableWindow(FALSE);
    MD5_CTX md5;
    BYTE outmd5[16] = {0};
    md5.MD5Update((BYTE*)pThis->m_LoginPass, strlen(pThis->m_LoginPass));     
    md5.MD5Final(outmd5);
    char temp[10];
    ZeroMemory(pThis->m_LoginPass, 0x30);
    ZeroMemory(pThis->m_SelectRole, 0x20);
    for (int i=0; i<16; i++)
    {
        wsprintf(temp, "%02X", outmd5);
        strcat(pThis->m_LoginPass, temp);
    }
//////////////////////////////////////////////////////////////////////////
//登陆部分     
    pThis->m_hLoginTimeHandle = CreateEvent(NULL, TRUE, FALSE, NULL);

    pThis->m_GamePacket.m_bIsLoginGetKey = FALSE;

    pThis->m_GamePacket.m_bIsGameGetKey = FALSE;
    pThis->m_LoginSocket.UnInit();

    if (pThis->m_LoginSocket.Init(ProcessLoginRecvData, pThis->m_LoginConnectIP, GAME_CONNECT_PORT))
    {//连接登陆服务器
        pThis->m_bCheckLogin = TRUE;
        pThis->m_2CheckLogin = 0;
        pThis->KillTimer(CGameRobotDlg::B_CHECK_FADAI);//检测发呆状态,包括想象得到的无响应状态
        pThis->SetTimer(CGameRobotDlg::B_CHECK_FADAI, 1000, NULL);
        pThis->KillTimer(CGameRobotDlg::B_CHECK_LOGIN);//有时候登陆没有返回角色信息
        pThis->SetTimer(CGameRobotDlg::B_CHECK_LOGIN, 1000, NULL);

        pThis->m_GamePacket.InitGame();     
        ZeroMemory(pThis->m_GamePacket.m_RoleName, 30);
        ::WaitForSingleObject(pThis->m_hLoginTimeHandle, INFINITE);
        g_pMainDlg->AddInfo(C_RED, "登陆连接已经断开!");
        pThis->m_LoginSocket.UnInit();

        if (g_AccountUseing)
        {//帐号使用中,等待10秒
            ResetEvent(pThis->m_hLoginTimeHandle);
            ::WaitForSingleObject(pThis->m_hLoginTimeHandle, 10*1000);
        }
    }
    else
    {
        pThis->AddInfo(C_RED, "连接登陆服务器失败!");
        pThis->m_bCheckLogin = FALSE;
        if (pThis->m_3CheckLogin++ > 20)//有时候怎么连都连不上的
        {//网络环境问题的话,关闭游戏
            CloseHandle(pThis->m_hLoginTimeHandle);
            pThis->m_hLoginTimeHandle = NULL;
            g_pMainDlg->m_bThreaFlag = TRUE;
            g_pMainDlg->KillTimer(CGameRobotDlg::BEGIN_LOOP);
            g_pMainDlg->CloseGame();
            return 2;
        }
    }

    CloseHandle(pThis->m_hLoginTimeHandle);
    pThis->m_hLoginTimeHandle = NULL;

//////////////////////////////////////////////////////////////////////////
//游戏部分
    if (pThis->m_enumState == CGameRobotDlg::R_OK)
    {
        int nIndex = 0;
        pThis->m_hGameTimeHandle = CreateEvent(NULL, TRUE, FALSE, NULL);

        pThis->m_2CheckGame = 0;
        pThis->KillTimer(CGameRobotDlg::B_CHECK_GAME);//又是些检测
        pThis->SetTimer(CGameRobotDlg::B_CHECK_GAME, 1000, NULL);
        do {
            pThis->m_bChangeMap = FALSE;
            pThis->m_GameSocket.UnInit();
            g_pMainDlg->AddInfo(C_GREEN, "正在连接游戏服务器中...");
            if ((pThis->m_ConnectPort != 0) && pThis->m_GameSocket.Init(ProcessGameRecvData, pThis->m_ConnectIP, pThis->m_ConnectPort))
            {
                nIndex = 0;
                g_pMainDlg->AddInfo(C_GREEN, "连接游戏服务器成功,进入游戏循环");
                ::WaitForSingleObject(pThis->m_hGameTimeHandle, INFINITE);
                ResetEvent(pThis->m_hGameTimeHandle);
                g_pMainDlg->AddInfo(C_RED, "游戏连接已经断开!");
                pThis->m_GameSocket.UnInit();
            }
            else
            {
                pThis->AddInfo(C_RED, "连接游戏服务器失败!");
                if (pThis->m_ConnectIP[0] != 0)
                    pThis->m_bChangeMap = TRUE;
                if (nIndex++ > 5) {
                    pThis->m_bChangeMap = FALSE;
                }
            }
        } while(pThis->m_bChangeMap);//m_bChangeMap 是切换地图的标志,切换地图情况下需要再次进行网络连接

        pThis->m_2CheckGame = 0;
        pThis->KillTimer(CGameRobotDlg::B_CHECK_GAME);

        CloseHandle(pThis->m_hGameTimeHandle);
        pThis->m_hGameTimeHandle = NULL;
        //////////////////////////////////////////////////////////////////////////         
        pThis->GetDlgItem(IDC_Btn_BeginGame)->EnableWindow(TRUE);
        pThis->m_bThreaFlag = FALSE;
        return 0;
    }
    else if (pThis->m_enumState == CGameRobotDlg::R_PASS_GAME
        || pThis->m_enumState == CGameRobotDlg::R_LOGIN_RETURN)
    {
        pThis->GetDlgItem(IDC_Btn_BeginGame)->EnableWindow(TRUE);
        pThis->m_bThreaFlag = FALSE;
    }
    return 1;
}


void __stdcall ProcessLoginRecvData(char *pData, DWORD DataLength)
{//处理登陆连接
    if (g_pMainDlg == NULL || DataLength == 0)
    {
        g_pMainDlg->SetMainState(TRUE, CGameRobotDlg::R_LOGIN_RETURN);
        return;
    }
    if (g_pMainDlg->m_GamePacket.m_bIsLoginGetKey == FALSE)
    {//获得登陆KEY
        if (*(PBYTE)pData == 0x20)
        {
            g_pMainDlg->m_GamePacket.GetLoginKey(pData, DataLength);
            g_pMainDlg->m_GamePacket.m_bIsLoginGetKey = TRUE;//标志
            return;
        }
    }
    g_pMainDlg->m_GamePacket.LoginDeCrypt(pData, DataLength);//解密
    switch(*(PBYTE)pData) {
    case 1: break;
    //这里依据封包命令字做相应处理
    default:
        g_pMainDlg->AddInfo(C_RED, "缺省封包: %X == %X", *(PWORD)(pData), DataLength);
        break;
    }
}

void __stdcall ProcessGameRecvData(char *pData, DWORD DataLength)
{//处理游戏连接
    if (g_pMainDlg == NULL || DataLength == 0)
    {
        g_AttackObjectID = 0;    //攻击对象去掉
        g_pMainDlg->m_bStartAttack = FALSE;//停止攻击
        bDoScript_State = FALSE;//把脚本停掉

        g_pMainDlg->AddInfo(C_RED, "无封包了.");
        g_pMainDlg->SetMainState(FALSE, CGameRobotDlg::R_OK);
        return;
    }
    g_pMainDlg->m_2CheckGame = 0;
    if (g_pMainDlg->m_GamePacket.m_bIsGameGetKey == FALSE)
    {
        if (*(PBYTE)pData == 0x20)
        {
            //换游戏加密KEY了
            g_pMainDlg->m_GamePacket.GetGameKey(pData, DataLength);            
            g_pMainDlg->m_GamePacket.m_bIsGameGetKey = TRUE;//标志
            g_pMainDlg->m_GamePacket.m_bCanLoop = FALSE;
            bD0Flag = FALSE;
            return;
        }
    }
    g_pMainDlg->m_GamePacket.LoginDeCrypt(pData, DataLength);//解密
    ProcessGameRecvPack(pData, DataLength);//具体的封包处理了
}

给出些数据结构,可以从中看出,脱机中想做什么功能,只要相关数据就行了,有些不必了解
typedef struct  {//自己的装备
    DWORD    ItemUseKeyID;
    BYTE    at_pos;    //0 是身上, 2是包袱
    BYTE    x;
    BYTE    y;
    BYTE    CurCount; //数量
    BYTE    IsBind;    //是否绑定
    BYTE    Needlevel;//装备需求, 穿装备的功能需要
    char    name[30];
    BYTE    type1;    //物品的分类
    WORD    type2;
    WORD    type3;
    BYTE    type4;
}TMyItemData, *PTMyItemData;


typedef struct  {//玩家,怪物,NPC

    DWORD    ID;
    char    name[22];
    DWORD    x;
    DWORD    y;
    int        type;    //3是NPC
    DWORD    CurHP;
    DWORD    MaxHP;
    DWORD    CurMP;
    DWORD    MaxMP;
    BYTE    MenPai;
    BYTE    IsCaptainFlag;    //是否是队长
    BOOL    IsDead;        //是否死亡
    DWORD    GroupID;    //供组队的ID
    char    npcClassName[50];
}Object, *PObject;
map<DWORD, Object>    m_AroundObject;//周围对象(NPC,怪物,玩家)
★在这里注意下说一下★, 我们的对象链表,当他们死亡时,最好不要做删除链表操作,只要将他们的ID设置为0就好了。
一些游戏在刷怪时,包括NPC,他们的ID是比较固定的


struct GroupItem {//地面上物品
    DWORD    ID;
    char    name[22];
    DWORD    x;
    DWORD    y;
};

struct MemberInfo {//大小0x54
    DWORD    MemberID;    //成员ID,注意这个ID不是角色ID
    char    name[0x20];//+34成员的名称
};
typedef struct  {
    DWORD    GroupID;    //队伍ID
    MemberInfo pMI[6];//最多有6个成员, 其中第一个是队长
}TGroupMgr, *PTGroupMgr;

就这些差不多了,技能好像处理不是很多,就是需要个技能ID就差不多了
        case 0xD9://已经学习的技能
            //R(0x0015): D9 14 00 00 00 5B 00 00 00 08 00 00 00 00 00 00 00 00 00 00 00  
            //                          =========== =========== 技能ID以及已经学习的等级
            {//extern map<DWORD, int> g_AlreadyStudySkill
                DWORD skillid = *(PDWORD)(GameCurPack+5);
                int skilllevel= *(PDWORD)(GameCurPack+5+4);
                g_AlreadyStudySkill[skillid] = skilllevel;
            }
            break;



联系我时,请说是在 挂海论坛 上看到的,谢谢!



上一篇:写点东西,菜鸟也玩保护...
下一篇:一个剥离GPK版的DragonNest.exe
免责声明:
1、本主题所有言论和图片纯属会员个人意见,与本论坛立场无关。一切关于该内容及资源商业行为与www.52ghai.com无关。

2、本站提供的一切资源内容信息仅限用于学习和研究目的;不得将上述内容用于商业或者非法用途,否则,一切后果请用户自负。

3、本站信息来自第三方用户,非本站自制,版权归原作者享有,版权争议与本站无关。您必须在下载后的24个小时之内,从您的电脑或手机中彻底删除上述内容。

4、如果您喜欢该程序,请支持正版,购买注册,得到更好的正版服务。如有侵犯你版权的,请邮件与我们联系删除(邮箱:xhzlw@foxmail.com),本站将立即改正。

98

积分

58

主题

8

听众
已帮网友解决0 个问题
好评
0
贡献
40
海币
3476
交易币
50
沙发
发表于 2015-2-8 22:28:02 | 只看该作者
支持,赞一个

98

积分

58

主题

8

听众
已帮网友解决0 个问题
好评
0
贡献
40
海币
3476
交易币
50
板凳
发表于 2015-3-15 20:10:27 | 只看该作者
感恩无私的分享与奉献 :)
3正式会员
142/300

142

积分

91

主题

5

听众
已帮网友解决0 个问题
好评
0
贡献
51
海币
78
交易币
0
地板
发表于 2015-3-16 13:24:02 | 只看该作者
有空一起交流一下

23

积分

4

主题

4

听众
已帮网友解决0 个问题
好评
0
贡献
19
海币
668
交易币
0

推广达人热心会员宣传达人最佳新人

5#
发表于 2015-4-2 00:16:54 | 只看该作者
强烈支持楼主ing……

6

积分

121

主题

8

听众
已帮网友解决0 个问题
好评
-2
贡献
-115
海币
9
交易币
0
6#
发表于 2015-6-7 14:26:42 | 只看该作者
看帖是一种习惯,不过我回帖也是一种习惯 更是一种美德

0

积分

0

主题

2

听众
已帮网友解决0 个问题
好评
0
贡献
0
海币
304
交易币
0
7#
发表于 2015-6-29 15:27:13 | 只看该作者
你好 我只是看看不说话,看我就走。

0

积分

0

主题

2

听众
已帮网友解决0 个问题
好评
0
贡献
0
海币
-3
交易币
0
8#
发表于 2015-8-16 01:45:40 | 只看该作者
诶呀诶呀,真的满需要的~哈哈!

1

积分

0

主题

4

听众
已帮网友解决0 个问题
好评
0
贡献
1
海币
6
交易币
0
9#
发表于 2016-1-21 00:25:52 | 只看该作者
就喜欢楼主这样的哈哈哈

1

积分

0

主题

4

听众
已帮网友解决0 个问题
好评
0
贡献
1
海币
32
交易币
0
10#
发表于 2016-10-25 22:10:09 | 只看该作者
支持楼主,感谢楼主!
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

免责声明|Archiver|手机版|小黑屋|挂海论坛

GMT+8, 2025-4-5 02:06 , Processed in 0.080772 second(s), 32 queries , Gzip On.

Powered by Discuz! X3.2

本站资源来自互联网用户收集发布,如有侵权请邮件与我们联系处理。xhzlw@foxmail.com

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