Alopex 發表於 2011-7-31 18:52:46

【已測】仿sea的cmd系統...

本帖最後由 Alopex 於 2011-9-6 07:50 PM 編輯

已測結束,感謝sinya,rgrg1234


atcommand.c


add:#define MAX_CMD 100 //Default the limit of cmd.



struct Command {
      char cmd_name;//The length of name.
      int gm_lv;
      int char_lv;
      int cmd_para_num;
      struct script_code *cmd_script;
};

static struct Command *cmd_db;//To be a point.
static int cmd_num = 0;

void do_init_command(const char *filename);

void do_init_command(const char *filename){
      FILE* fp;
      int line_num = 0,read_cmd_num = 0;
      char line;
      if((fp = fopen(filename, "r")) == NULL )
      {
                ShowWarning("do_init_command: File \"%s\" does not exist.\n ",filename);
                return;
      }
      memset(cmd_db, 0, sizeof(cmd_db)); //Init cmd_db.
      while(fgets(line, sizeof(line), fp) && ++line_num)
      {
                int i;
                char *str, *p;
                struct Command *cmd;

                CREATE(cmd, struct Command, 1);
                memset(str, 0, sizeof(str));
               
                p = line;

                while(ISSPACE(*p))p++;//skip space.

                if(*p == '/' && *(p+1) == '/')
                        continue; // skip "//"

                if(*p == '\0')
                        continue; // The ending of line.

                for(i = 0 ; i < 5 ; i++)
                {
                        str = p;
                        p = strchr(p, ',');
                        if(p == NULL||i==4) break;
                        *p = '\0'; // Exchange ',' for '\0';
                        p++;
                }
                if(get_atcommandinfo_byname(str) == NULL || str == NULL)// check repeated cmd.
                {
                        safestrncpy(cmd->cmd_name, str, sizeof(cmd->cmd_name));
                        cmd->gm_lv = atoi(str);
                        cmd->char_lv = atoi(str);
                        cmd->cmd_para_num = atoi(str);
                        cmd->cmd_script = parse_script(str, filename ,line_num ,0);
                        if(cmd->cmd_script)
                        {
                              cmd_db = cmd;
                              read_cmd_num++;
                              //ShowStatus("Do_init_command: Loaded Command: %s , Number : %d. \n",cmd->cmd_name,read_cmd_num);
                        }else
                              aFree(cmd);
                }else
                        aFree(cmd);
      }
      cmd_num = read_cmd_num;
      fclose(fp);
      ShowStatus("Do_init_command: Complete ! Total %lu defined in %s . \n",cmd_num,filename);
      return;
}Looking for:      info = get_atcommandinfo_byname(command);add:      if(info == NULL){
                int cmd_id;
                struct Command *cmd_info;
                char* name = (char*)command;
                if( *name == atcommand_symbol || *name == charcommand_symbol ) name++;
                ARR_FIND( 0, cmd_num, cmd_id, strcmpi(cmd_db->cmd_name, name) == 0 );//looking for name in cmd_db;
                cmd_info = ((cmd_id > cmd_num) ? NULL : cmd_db);
      
                if(cmd_info == NULL || (type && ((*atcmd_msg == atcommand_symbol && pc_isGM(sd) < cmd_info->gm_lv) || (*atcmd_msg == charcommand_symbol && pc_isGM(sd) < cmd_info->char_lv))))
                {
                        sprintf(output, msg_txt(153), command); // "%s is Unknown Command."
                        clif_displaymessage(fd, output);
                        return true;
                }
      
                {
                        int i;
                        char *str = params;
                        char *split,para_data;
                        struct map_session_data *target = (*atcmd_msg==atcommand_symbol) ? sd : ssd;
                        script_cleararray_pc(target, "@cmd_para$" ,(void*)0);//clear @cmd_para$.
                        for(i = 0 ; i < cmd_info->cmd_para_num && i < 128 ; i++)
                        {
                              split = strchr(str ,' ');
                              if(split == NULL)//To avoid empty data.
                              {
                                        script_setarray_pc(target,"@cmd_para$", i , (void*)str , (int*)0);
                                        break;
                              }
                              *split = '\0';
                              safestrncpy(para_data, str, sizeof(para_data));
                              script_setarray_pc(target,"@cmd_para$", i , (void*)para_data , (int*)0);
                              str = ++split;
                        }
                        run_script(cmd_info->cmd_script,0,target->bl.id,0);
                }
                return true;
      }map.c

looking for:do_init_duel();add:do_init_command("db/cmd_db.txt");db底下建cmd_db.txt


內容://格式:
//<玩家指令>,<@指令等級>,<#指令等級>,<參數數量>,{腳本}
// @cmd_para$[]為參數,不超過127
// 數字參數請使用atoi(@cmd_para$[])


testcommand,10,20,1,{mes "看到訊息表示成功!"+@cmd_para$;close;}

sinya 發表於 2011-7-31 20:50:14

本帖最後由 sinya 於 2011-8-1 01:17 AM 編輯

我測式成功 執行 對話窗 @ 和 # 都正常運作


this is just amazing awesome!!

可惜 我只能加5分 不然我給你加 99999999

rgrg1234 發表於 2011-7-31 22:09:48

成功加一
這真的很nice
pretty good!

dreamunreal 發表於 2011-8-1 11:48:51

U R pretty good..

嘛 其实参数数量这个东西 我也不是觉得太有用`.

把@ 和#的等级 弄成atcmd.conf 控制就好了= =~.
调整下加载顺序- -~.

rgrg1234 發表於 2011-8-1 20:38:34

加上了個可以直接重讀db的
用起來更方便=.=+

sense 發表於 2011-9-6 12:51:35

回復 1# Alopex

:91:
這代碼真棒呢!

感謝分享了。

Alopex 發表於 2011-9-6 19:51:51

修正部份bug...只輸入一個參數將無法正確達成
頁: [1]
查看完整版本: 【已測】仿sea的cmd系統...