gtabbs吧 关注:2,631贴子:16,533
  • 5回复贴,共1

CLEO4之浅析IntOperations.cleo内部实现

只看楼主收藏回复

这是第二个cleo4原带.cleo的实现分析,最后一个有空可能会弃坑,当然我最希望在弃坑的前提下有人能帮我解决那最后一个,这次来个详讲,把opcodes.h等一并介绍了...还有这次是在线目测,错误率可能比较大,而且效率比较低..
至于IntOperations你们也懂的,提供了强大的逻辑运算,下面就是分析了,一些文件我就分楼层发了


IP属地:中国香港1楼2013-08-19 15:52回复
    opcodes.c↓
    #include "stdafx.h" //windows api需要包含的头文件
    #include "CLEO.h" //预处理,包含cleo头文件的内容
    //宏定义IntOperations里面各个opcodes的操作码,大致为与或非异或等逻辑运算
    #define OPCODE_INTOP_AND0x0B10
    #define OPCODE_INTOP_OR0x0B11
    #define OPCODE_INTOP_XOR0x0B12
    #define OPCODE_INTOP_NOT0x0B13
    #define OPCODE_INTOP_MOD0x0B14
    #define OPCODE_INTOP_SHR0x0B15
    #define OPCODE_INTOP_SHL0x0B16
    //声明回调函数,后面参数是一个函数指针
    //在.cleo中回调函数运用非常广泛,所谓回调函数就是调用函数指针调用的一个函数
    //如下面就是随手写的一个回调函数的实现
    /*
    #incldue<windows.h>
    #include<stdio.h>
    void msgbox()
    {
    MessageBox(0,"","",0);
    }
    void callback(void(*msgbox)) //指向函数msgbox的指针
    {
    msgbox(); //调用指向函数的指针
    }
    int main()
    {
    callback(msgbox); //调用调用指向函数的指针的那个函数
    return 0;
    }
    好吧,貌似扯远了,反正就是上面那个意思
    OpcodeResult WINAPI Script_IntOp_AND(CScriptThread* thread);
    OpcodeResult WINAPI Script_IntOp_OR (CScriptThread* thread);
    OpcodeResult WINAPI Script_IntOp_XOR(CScriptThread* thread);
    OpcodeResult WINAPI Script_IntOp_NOT(CScriptThread* thread);
    OpcodeResult WINAPI Script_IntOp_MOD(CScriptThread* thread);
    OpcodeResult WINAPI Script_IntOp_SHR(CScriptThread* thread);
    OpcodeResult WINAPI Script_IntOp_SHL(CScriptThread* thread);
    BOOL InitOpcodes() //入口点改变,因此没有main
    {
    BOOL result = FALSE; //定义布尔值变量result为0;
    //对CLEO版本进行检查
    if (CLEO_GetVersion() < CLEO_VERSION)
    {
    MessageBox(HWND_DESKTOP, "An incorrect version of CLEO was loaded.", "IntOpearations.cleo", MB_ICONERROR); //调用MessageBox()函数进行报错,第一个参数是句柄,第二个参数是显示的字符串,第三个参数是title,第四个参数是错误图标
    return FALSE; 返回0
    }
    //opcodes注册
    if (CLEO_RegisterOpcode(OPCODE_INTOP_AND, &Script_IntOp_AND))
    result = TRUE;
    if (CLEO_RegisterOpcode(OPCODE_INTOP_OR, &Script_IntOp_OR ))
    result = TRUE;
    if (CLEO_RegisterOpcode(OPCODE_INTOP_XOR, &Script_IntOp_XOR))
    result = TRUE;
    if (CLEO_RegisterOpcode(OPCODE_INTOP_NOT, &Script_IntOp_NOT))
    result = TRUE;
    if (CLEO_RegisterOpcode(OPCODE_INTOP_MOD, &Script_IntOp_MOD))
    result = TRUE;
    if (CLEO_RegisterOpcode(OPCODE_INTOP_SHR, &Script_IntOp_SHR))
    result = TRUE;
    if (CLEO_RegisterOpcode(OPCODE_INTOP_SHL, &Script_IntOp_SHL))
    result = TRUE;
    return result;
    }这个布尔值函数完毕,下面就是具体每个opcode的实现了


    IP属地:中国香港2楼2013-08-19 15:52
    回复
      这是逻辑运算符 看得出来下面的功能就是让cleo实现这些,楼主就不继续赘述了
      And(逻辑与)
      Or(逻辑或)
      Xor(逻辑异或)
      Not(逻辑非)
      Or(逻辑或)
      OpcodeResult WINAPI Script_IntOp_AND(CScriptThread* thread)
      {
      int a = CLEO_GetIntOpcodeParam(thread);
      int b = CLEO_GetIntOpcodeParam(thread);
      CLEO_SetIntOpcodeParam(thread, a & b); 与
      return OR_CONTINUE;
      }
      OpcodeResult WINAPI Script_IntOp_OR(CScriptThread* thread)
      {
      /*这是CLEO_GetIntOpcodeParam(的定义
      DWORD WINAPI CLEO_GetIntOpcodeParam(CScriptThread* thread);
      float WINAPI CLEO_GetFloatOpcodeParam(CScriptThread* thread);*/
      int a = CLEO_GetIntOpcodeParam(thread); int b = CLEO_GetIntOpcodeParam(thread);
      CLEO_SetIntOpcodeParam(thread, a | b); //“|”为位或,然后后面就是逻辑非等等
      return OR_CONTINUE; //OR_CONTINUE表示成功,OR_INTERRUPT表示失败,具体在cleo.h里面我会说(前提是有时间)


      IP属地:中国香港3楼2013-08-19 15:52
      回复
        stdafx.h↓
        #pragma once //预处理指令,强制编译一次
        #define _CRT_SECURE_NO_WARNINGS
        #include <windows.h> //因为使用了MessageBox(),所以必须包含这个头文件
        opcodes.h↓
        #pragma once
        BOOL InitOpcodes(); //opcodes.c里面的布尔值变量声明


        IP属地:中国香港4楼2013-08-19 15:53
        回复
          好吧,这才是cleo.h核心部分
          typedef struct CScriptThread CScriptThread;//别名CScriptThread代表struct CScriptThread
          #pragma pack(push,1)
          struct CScriptThread{
          CScriptThread*next; //队列中指向下一个元素的指针?老实说我也不知道,因为如果后面根本没有入队出队操作,更别说申请新内存、栈、插队等了..- -或许是他的手误或者为以后的准备吧
          CScriptThread*prev; //队列前一个元素
          charthreadName[8]; //对线程的命名,也就是03A4: name_thread 'MAIN',从[8]看得出来对自定义名称有限制的,而且注意是char类型的
          BYTE*baseIp;//script中指向内存的开始位置
          BYTE*ip; //当前索引的指针
          BYTE*stack[8]; //返回栈,这里用的是数组所以是一个顺序栈
          WORDsp; //当前堆栈中处理的数据
          WORD_f3A;//padding
          SCRIPT_VARtls[34];//定义线程中的局部变量为一个数组,现在知道了局部变量为什么有限制了吧或许我们可以改改这个34,但是就不知道其他地方有没有同样的限制,等我哪天有空去看看cleo4里面的源码,说不定可以突破这个局部变量选择
          BYTEisActive; //当前响应的线程
          charcondResult;//结果,或者假..其实这里用布尔值应该会更好
          charmissionCleanupFlag;//清理任务
          charexternal;//script.img中的的线程
          BYTE_fC8;//unknown
          BYTE_fC9;//unknown
          BYTE_fCA;//unknown
          BYTE_fCB;//unknown
          DWORDwakeTime;//时间,当脚本开始后再次使用0001操作码
          WORDlogicalOp;//if的参数
          BYTEnotFlag;//opcode & 0x8000不等于0..话说0x8000操作码我怎么没有找到
          BYTEwbCheckEnabled; //任务成功或者失败的检查标志
          BYTEwastedOrBusted; //玩家状态
          BYTE_fD5;//unknown
          WORD_fD6;//unknown
          DWORDsceneSkip;//场景转换,可以理解为瞬移..
          BYTEmissionFlag;//任务线程
          BYTE_fDD[3];//padding
          };


          IP属地:中国香港本楼含有高级字体6楼2013-08-19 15:54
          回复

            好了,此贴终结


            IP属地:中国香港7楼2013-08-19 15:54
            回复