transaction_type proto_to_transaction( const proto::Transaction& proto_tx) { transaction_type result_tx; result_tx.version = proto_tx.version(); result_tx.locktime = proto_tx.locktime(); for (size_t i = 0; i < proto_tx.inputs_size(); ++i) { const proto::Transaction::Input& proto_input = proto_tx.inputs(i); transaction_input_type tx_input; const std::string& prev_out_hash = proto_input.previous_output_hash(); std::copy(prev_out_hash.begin(), prev_out_hash.end(), tx_input.previous_output.hash.begin()); tx_input.previous_output.index = proto_input.previous_output_index(); const data_chunk& raw_script = read_raw_script(proto_input); if (previous_output_is_null(tx_input.previous_output)) tx_input.input_script = coinbase_script(raw_script); else tx_input.input_script = parse_script(raw_script); tx_input.sequence = proto_input.sequence(); result_tx.inputs.push_back(tx_input); } for (size_t i = 0; i < proto_tx.outputs_size(); ++i) { const proto::Transaction::Output& proto_output = proto_tx.outputs(i); transaction_output_type tx_output; tx_output.value = proto_output.value(); tx_output.output_script = parse_script(read_raw_script(proto_output)); result_tx.outputs.push_back(tx_output); } return result_tx; }
script read_script(deserializer& deserial) { data_chunk raw_script = read_raw_script(deserial); #ifndef BITCOIN_DISABLE_ASSERTS std::string assert_msg = pretty_hex(raw_script); #endif BITCOIN_ASSERT_MSG( raw_script == save_script(parse_script(raw_script)), assert_msg.c_str()); // Eventually plan to move parse_script to inside here return parse_script(raw_script); }
static void run_from_res(const char *name) { const char *data; DWORD size, len; BSTR str; HRSRC src; HRESULT hres; strict_dispid_check = FALSE; test_name = name; src = FindResourceA(NULL, name, (LPCSTR)40); ok(src != NULL, "Could not find resource %s\n", name); size = SizeofResource(NULL, src); data = LoadResource(NULL, src); len = MultiByteToWideChar(CP_ACP, 0, data, size, NULL, 0); str = SysAllocStringLen(NULL, len); MultiByteToWideChar(CP_ACP, 0, data, size, str, len); SET_EXPECT(global_success_d); SET_EXPECT(global_success_i); hres = parse_script(SCRIPTITEM_GLOBALMEMBERS, str); CHECK_CALLED(global_success_d); CHECK_CALLED(global_success_i); ok(hres == S_OK, "parse_script failed: %08x\n", hres); SysFreeString(str); }
void process_wad_script (const char *name) { char *buf; QFile *file; int bytes; script_t *script; file = Qopen (name, "rt"); if (!file) Sys_Error ("couldn't open %s. %s", name, strerror(errno)); bytes = Qfilesize (file); buf = malloc (bytes + 1); bytes = Qread (file, buf, bytes); buf[bytes] = 0; Qclose (file); dstring_copystr (&destfile, name); dstring_appendstr (&destfile, ".wad"); script = Script_New (); Script_Start (script, name, buf); parse_script (script); if (wadfile) wad_close (wadfile); }
int parse_script_and_set_config(int argc, char *argv[], struct config *config, struct script *script, const char *script_path, const char *script_buffer) { struct invocation invocation = { .argc = argc, .argv = argv, .config = config, .script = script, }; DEBUGP("parse_and_run_script: %s\n", script_path); assert(script_path != NULL); init_script(script); set_default_config(config); config->script_path = strdup(script_path); if (script_buffer != NULL) copy_script(script_buffer, script); else read_script(script_path, script); return parse_script(config, script, &invocation); }
void continue_script(script_t *script, char *continue_point) { current_script = script; // continue from place specified rover = continue_point; parse_script(); // run }
static void parse_script_af(DWORD flags, const char *src) { BSTR tmp; HRESULT hres; tmp = a2bstr(src); hres = parse_script(flags, tmp); SysFreeString(tmp); ok(hres == S_OK, "parse_script failed: %08x\n", hres); }
void run_script(script_t *script) { // set current script current_script = script; // start at the beginning of the script rover = current_script->data; // haleyjd: no last if so it sure wasn't true current_script->lastiftrue = false; parse_script(); // run it }
static void run_from_file(const char *filename) { BSTR script_str; HRESULT hres; script_str = get_script_from_file(filename); if(!script_str) return; strict_dispid_check = FALSE; hres = parse_script(SCRIPTITEM_GLOBALMEMBERS, script_str); SysFreeString(script_str); ok(hres == S_OK, "parse_script failed: %08x\n", hres); }
int run_script(const char script[], int fd, unsigned int flags){ scmd_t *cmd_list = NULL; int result = parse_script(script, &cmd_list, flags); if( result != 0 ){ return result; } sspace_t pspace, hspace; memset(&pspace, 0, sizeof(sspace_t)); memset(&hspace, 0, sizeof(sspace_t)); enum cmd_result code = RNONE; int line = 1, nflag = flags & NFLAG; TRY_REALLOC(outbuff, MIN_CHUNK); TRY_REALLOC(sub_buff, MIN_CHUNK); outbuff[0] = '\0'; sub_buff[0] = '\0'; while( (result = s_getline(&pspace, fd) > 0 ) ){ if( code != RNONE ){ result = print_space(&pspace); if( result < 0 ){ goto exit; } switch(code){ case RQUIT: return SUCCESS; default: if( code < 0 ){ result = code; goto exit; } break; } } pspace.is_deleted = nflag; code = run_line(cmd_list, &pspace, &hspace, line, flags); line++; } result = print_space(&pspace); exit: /* TODO: clean */ scmd_list_free(cmd_list); free(outbuff); free(sub_buff); if( pspace.space != NULL ){ free(pspace.space); } if( pspace.text != NULL ){ free(pspace.text); } return result; }
/** \brief Parse a sequence of commands. This method also perform error management. */ bool parser_imp::parse_commands() { bool done = false; while (!done) { protected_call([&]() { check_interrupted(); switch (curr()) { case scanner::token::CommandId: if (!parse_command()) done = true; break; case scanner::token::ScriptBlock: parse_script(); break; case scanner::token::Period: show_prompt(); next(); break; case scanner::token::Eof: done = true; break; default: throw parser_error("Command expected", pos()); } }, [&]() { sync_command(); }); } return !m_found_errors; }
Pattern::Pattern(const std::string &patternStr) : cutoffValue(1000) { // read the script from file std:: vector<MYWCHAR_T> script; toWStringV(&script, patternStr); // parse the script std:: vector<TRACE_ITEM> trace; std:: map<std:: vector<MYWCHAR_T>, text::Helper::NodeFormat> nodeFormatsInScript; std:: string errorMessage; if (! parse_script(script, &trace, &nodeFormatsInScript, &errorMessage)) { throw ParseError(errorMessage); } if (! nodeFormatsInScript.empty()) { throw ParseError("node format in script is not implemented"); } // prepare interpreter interp.setProgram(trace, script); common::EscapeSequenceHelper::decode(&varName, "TEXT"); }
/** * No need to explain this. * * @param argc Number of arguments. * @param argv Arguments array. * @return Return code. */ int main(int argc, char **argv) { bool running = true; char *script_file = NULL; char *csv_file = NULL; char *ctok = NULL; gnuplot_ctrl *gp = gnuplot_init(); char prompt[64] = "> "; if (argc == 2) { if (argv[1][strlen(argv[1]) - 3] == '.' && argv[1][strlen(argv[1]) - 2] == 'p' && argv[1][strlen(argv[1]) - 1] == 'c') { // Script file. script_file = argv[1]; running = parse_script(script_file, ctok, &csv_file, gp, prompt); } else { // CSV file. csv_file = argv[1]; generate_prompt(prompt, csv_file); } } while (running) { char *buffer = NULL; buffer = readline(prompt); if (buffer && *buffer) { add_history(buffer); ctok = strtok(buffer, " "); } else { continue; } running = parse_cmd_line(ctok, &csv_file, gp, prompt, false); } gnuplot_close(gp); return EXIT_SUCCESS; }
/*========================================== * アイテムデータベースの読み込み *------------------------------------------ */ static int itemdb_read_itemdb(void) { FILE *fp; char line[4096]; int ln=0,lines=0; int nameid,j; char *str[32],*p,*np; struct item_data *id; struct script_code *script = NULL; int i=0; const char *filename[] = { "db/item_db.txt", #ifdef PRE_RENEWAL "db/pre/item_db_pre.txt", #endif "db/addon/item_db_add.txt" }; const char *filename2; for(i = 0; i < sizeof(filename)/sizeof(filename[0]); i++) { fp = fopen(filename[i], "r"); if(fp == NULL) { if(i > 0) continue; printf("itemdb_read_itemdb: open [%s] failed !\n", filename[i]); continue; } lines=ln=0; while(fgets(line,sizeof(line),fp)){ lines++; if(line[0] == '\0' || line[0] == '\r' || line[0] == '\n') continue; if(line[0]=='/' && line[1]=='/') continue; memset(str,0,sizeof(str)); for(j=0,np=p=line;j<18 && p;j++){ str[j]=p; p=strchr(p,','); if(p){ *p++=0; np=p; } } if(str[0] == NULL) continue; nameid = atoi(str[0]); if(nameid <= 0) continue; ln++; //ID,Name,Jname,Type,Price,Sell,Weight,ATK,DEF,Range,Slot,Job,Gender,Loc,wLV,eLV,View,Refine id = itemdb_search(nameid); strncpy(id->name,str[1],48); strncpy(id->jname,str[2],48); id->type = atoi(str[3]); // buy≠sell*2 は item_value_db.txt で指定してください。 if(atoi(str[5])) { // sell値を優先とする id->value_buy = atoi(str[5])*2; id->value_sell = atoi(str[5]); } else { id->value_buy = atoi(str[4]); id->value_sell = atoi(str[4])/2; } id->weight = atoi(str[6]); itemdb_split_atoi(str[7],&id->atk,&id->matk); itemdb_split_atoi(str[8],&id->def,&id->mdef); id->range = atoi(str[9]); id->slot = atoi(str[10]); if(id->slot < 0 || id->slot > 4) { id->slot = 0; } id->class_ = (unsigned int)strtoul(str[11],NULL,0); id->sex = atoi(str[12]); if(id->equip != atoi(str[13])) { id->equip = atoi(str[13]); } id->wlv = atoi(str[14]); if(id->wlv < 0 || id->wlv > MAX_WEAPON_LEVEL) { id->wlv = 0; } id->elv = atoi(str[15]); id->look = atoi(str[16]); id->refine = atoi(str[17]); id->flag.available = 1; id->flag.value_notdc = 0; id->flag.value_notoc = 0; id->flag.pet_egg = 0; id->flag.pet_acce = 0; id->view_id = 0; id->group = 0; id->delay = 0; id->upper = 0; id->zone = 0; // force \0 terminal id->name[47] = '\0'; id->jname[47] = '\0'; if((p = strchr(np, '{')) == NULL) continue; np = parse_script_line_end(p, filename[i], lines); if(!np) continue; if(id->use_script) { script_free_code(id->use_script); } script = parse_script(p, filename[i], lines); id->use_script = (script_is_error(script))? NULL: script; np++; if(*np != ',') continue; if((p = strchr(np + 1, '{')) == NULL) continue; np = parse_script_line_end(p, filename[i], lines); if(!np) continue; if(id->equip_script) { script_free_code(id->equip_script); } script = parse_script(p, filename[i], lines); id->equip_script = (script_is_error(script))? NULL: script; } fclose(fp); printf("read %s done (count=%d)\n",filename[i],ln); } filename2 = "db/item_db2.txt"; fp = fopen(filename2, "r"); if(fp == NULL) { printf("itemdb_read_itemdb: open [%s] failed !\n", filename2); return 0; } ln=0; while(fgets(line,sizeof(line),fp)){ if(line[0] == '\0' || line[0] == '\r' || line[0] == '\n') continue; if(line[0]=='/' && line[1]=='/') continue; memset(str,0,sizeof(str)); for(j=0,np=p=line;j<11 && p;j++){ str[j]=p; p=strchr(p,','); if(p){ *p++=0; np=p; } } if(str[0] == NULL) continue; nameid = atoi(str[0]); if(nameid <= 0 || !(id = itemdb_exists(nameid))) continue; ln++; id->upper = atoi(str[1]); id->zone = atoi(str[2]); id->flag.dropable = (atoi(str[3]) == 0)? 0: 1; id->flag.sellable = (atoi(str[4]) == 0)? 0: 1; id->flag.storageable = (atoi(str[5]) == 0)? 0: 1; id->flag.guildstorageable = (atoi(str[6]) == 0)? 0: 1; id->flag.cartable = (atoi(str[7]) == 0)? 0: 1; id->delay = atoi(str[8]); id->flag.buyingable = (atoi(str[9]) == 0)? 0: 1; id->flag.nonconsume = (atoi(str[10]) == 0)? 0: 1; } fclose(fp); printf("read %s (count=%d)\n", filename2, ln); filename2 = "db/item_arrowtype.txt", fp = fopen(filename2, "r"); if(fp == NULL){ printf("itemdb_read_itemdb: open [%s] failed !\n", filename2); return 0; } while(fgets(line,sizeof(line),fp)){ if(line[0] == '\0' || line[0] == '\r' || line[0] == '\n') continue; if(line[0]=='/' && line[1]=='/') continue; memset(str,0,sizeof(str)); for(j=0,np=p=line;j<4 && p;j++){ str[j]=p; p=strchr(p,','); if(p){ *p++=0; np=p; } } if(str[0] == NULL || str[3] == NULL) continue; nameid = atoi(str[0]); if(nameid <= 0 || !(id = itemdb_exists(nameid))) continue; //ID,Name,Jname,type id->arrow_type = atoi(str[3]); } fclose(fp); printf("read %s done\n", filename2); filename2 = "db/item_cardtype.txt"; fp = fopen(filename2, "r"); if(fp == NULL) { printf("itemdb_read_itemdb: open [%s] failed !\n", filename2); return 0; } while(fgets(line,sizeof(line),fp)){ if(line[0] == '\0' || line[0] == '\r' || line[0] == '\n') continue; if(line[0]=='/' && line[1]=='/') continue; memset(str,0,sizeof(str)); for(j=0,np=p=line;j<4 && p;j++){ str[j]=p; p=strchr(p,','); if(p){ *p++=0; np=p; } } if(str[0] == NULL || str[3] == NULL) continue; nameid = atoi(str[0]); if(nameid <= 0 || !(id = itemdb_exists(nameid))) continue; //ID,Name,Jname,type id->card_type = atoi(str[3]); } fclose(fp); printf("read %s done\n", filename2); filename2 = "db/item_group_db.txt"; fp = fopen(filename2, "r"); if(fp == NULL) { printf("itemdb_read_itemdb: open [%s] failed !\n", filename2); return 0; } while(fgets(line,sizeof(line),fp)) { int group_id; if(line[0] == '\0' || line[0] == '\r' || line[0] == '\n') continue; if(line[0]=='/' && line[1]=='/') continue; memset(str,0,sizeof(str)); for(j=0,np=p=line;j<4 && p;j++){ str[j]=p; p=strchr(p,','); if(p){ *p++=0; np=p; } } if(str[0] == NULL || str[3] == NULL) continue; nameid = atoi(str[0]); if(nameid <= 0 || !(id = itemdb_exists(nameid))) continue; //ID,Name,Jname,Group group_id = atoi(str[3]); if(group_id >= MAX_ITEMGROUP) { printf("item_group: invalid group id(%d) ID %d\n", group_id, nameid); continue; } id->group = group_id; } fclose(fp); printf("read %s done\n", filename2); return 0; }
void parser_imp::parse_script_expr() { return parse_script(true); }
/*====================================== * SQL *=================================== */ static int itemdb_read_sqldb(void) { unsigned short nameid; struct item_data *id; char script[65535 + 2 + 1]; // Maximum length of MySQL TEXT type (65535) + 2 bytes for curly brackets + 1 byte for terminator char *item_db_name[] = { item_db_db, item_db2_db }; long unsigned int ln = 0; int i; // ---------- for (i = 0; i < 2; i++) { sprintf(tmp_sql, "SELECT * FROM `%s`", item_db_name[i]); // Execute the query; if the query execution succeeded... if (mysql_query(&mmysql_handle, tmp_sql) == 0) { sql_res = mysql_store_result(&mmysql_handle); // If the storage of the query result succeeded... if (sql_res) { // Parse each row in the query result into sql_row while ((sql_row = mysql_fetch_row(sql_res))) { /* +----+--------------+---------------+------+-----------+------------+--------+--------+---------+-------+-------+------------+---------------+-----------------+--------------+-------------+------+------------+--------------+ | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | +----+--------------+---------------+------+-----------+------------+--------+--------+---------+-------+-------+------------+---------------+-----------------+--------------+-------------+------+------------+--------------+ | id | name_english | name_japanese | type | price_buy | price_sell | weight | attack | defence | range | slots | equip_jobs | equip_upper | equip_genders | equip_locations | weapon_level | equip_level | refineable | view | script | +----+--------------+---------------+------+-----------+------------+--------+--------+---------+-------+-------+------------+---------------+-----------------+--------------+-------------+------+------------+--------------+ */ nameid = atoi(sql_row[0]); // If the identifier is not within the valid range, process the next row if (nameid == 0 || nameid >= 20000) continue; ln++; // ---------- id = itemdb_search(nameid); memcpy(id->name, sql_row[1], ITEM_NAME_LENGTH-1); memcpy(id->jname, sql_row[2], ITEM_NAME_LENGTH-1); id->type = atoi(sql_row[3]); if (id->type == 11) { //Items that are consumed upon target confirmation //(yggdrasil leaf, spells & pet lures) [Skotlex] id->type = 2; id->flag.delay_consume=1; } // If price_buy is not NULL and price_sell is not NULL... if ((sql_row[4] != NULL) && (sql_row[5] != NULL)) { id->value_buy = atoi(sql_row[4]); id->value_sell = atoi(sql_row[5]); } // If price_buy is not NULL and price_sell is NULL... else if ((sql_row[4] != NULL) && (sql_row[5] == NULL)) { id->value_buy = atoi(sql_row[4]); id->value_sell = atoi(sql_row[4]) / 2; } // If price_buy is NULL and price_sell is not NULL... else if ((sql_row[4] == NULL) && (sql_row[5] != NULL)) { id->value_buy = atoi(sql_row[5]) * 2; id->value_sell = atoi(sql_row[5]); } // If price_buy is NULL and price_sell is NULL... if ((sql_row[4] == NULL) && (sql_row[5] == NULL)) { id->value_buy = 0; id->value_sell = 0; } id->weight = atoi(sql_row[6]); id->atk = (sql_row[7] != NULL) ? atoi(sql_row[7]) : 0; id->def = (sql_row[8] != NULL) ? atoi(sql_row[8]) : 0; id->range = (sql_row[9] != NULL) ? atoi(sql_row[9]) : 0; id->slot = (sql_row[10] != NULL) ? atoi(sql_row[10]) : 0; if (id->slot > MAX_SLOTS) { ShowWarning("itemdb_read_sqldb: Item %d (%s) specifies %d slots, but the server only supports up to %d\n", nameid, id->jname, id->slot, MAX_SLOTS); id->slot = MAX_SLOTS; } itemdb_jobid2mapid(id->class_base, (sql_row[11] != NULL) ? atoi(sql_row[11]) : 0); id->class_upper= (sql_row[12] != NULL) ? atoi(sql_row[12]) : 0; id->sex = (sql_row[13] != NULL) ? atoi(sql_row[13]) : 0; id->equip = (sql_row[14] != NULL) ? atoi(sql_row[14]) : 0; id->wlv = (sql_row[15] != NULL) ? atoi(sql_row[15]) : 0; id->elv = (sql_row[16] != NULL) ? atoi(sql_row[16]) : 0; id->flag.no_refine = (sql_row[17] == NULL || atoi(sql_row[17]) == 1)?0:1; id->look = (sql_row[18] != NULL) ? atoi(sql_row[18]) : 0; id->view_id = 0; id->sex = itemdb_gendercheck(id); //Apply gender filtering. // ---------- if (id->script) aFree(id->script); if (sql_row[19] != NULL) { if (sql_row[19][0] == '{') id->script = parse_script((unsigned char *) sql_row[19], 0); else { sprintf(script, "{%s}", sql_row[19]); id->script = parse_script((unsigned char *) script, 0); } } else id->script = NULL; // ---------- id->flag.available = 1; id->flag.value_notdc = 0; id->flag.value_notoc = 0; } ShowStatus("Done reading '"CL_WHITE"%lu"CL_RESET"' entries in '"CL_WHITE"%s"CL_RESET"'.\n", ln, item_db_name[i]); ln = 0; } else { ShowSQL("DB error (%s) - %s\n",item_db_name[i], mysql_error(&mmysql_handle)); ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmp_sql); } // Free the query result mysql_free_result(sql_res); } else { ShowSQL("DB error (%s) - %s\n",item_db_name[i], mysql_error(&mmysql_handle)); ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmp_sql); } } return 0; }
int main(int argc, char *argv[]) { int script_shmid; int ret; char **args; char binary[16] = "launcher"; pid_t launcher_pid; char buffer[128]; FILE *from_child; char *test_case_id_s; int test_case_id; char *result_s; int result; struct item_data it_data; char *exdata; int exdata_len; /* init script and view */ db_msg("core: parse script %s...\n", SCRIPT_NAME); script_shmid = parse_script(SCRIPT_NAME); if (script_shmid == -1) { db_error("core: parse script failed\n"); return -1; } db_msg("core: init script...\n"); ret = init_script(script_shmid); if (ret) { db_error("core: init script failed(%d)\n", ret); return -1; } db_msg("core: init view...\n"); ret = init_view(); if (ret) { db_error("core: init view failed(%d)\n", ret); return -1; } /* parse and draw all test cases to view */ db_msg("core: parse test case from script...\n"); ret = parse_testcase(); if (ret < 0) { db_error("core: parse all test case from script failed(%d)\n", ret); return -1; } else if (ret == 0) { db_warn("core: NO TEST CASE to be run\n"); return -1; } db_msg("core: draw test case to view...\n"); ret = draw_testcases(); if (ret) { db_error("core: draw all test cases to view failed(%d)\n", ret); return -1; } view_sync(); /* create named pipe */ unlink(CMD_PIPE_NAME); if (mkfifo(CMD_PIPE_NAME, S_IFIFO | 0666) == -1) { db_error("core: mkfifo error(%s)\n", strerror(errno)); return -1; } /* fork launcher process */ db_msg("core: fork launcher process...\n"); args = malloc(sizeof(char *) * 6); args[0] = binary; args[1] = malloc(10); sprintf(args[1], "%d", DRAGONBOARD_VERSION); args[2] = malloc(10); sprintf(args[2], "%d", script_shmid); args[3] = malloc(10); sprintf(args[3], "%d", total_testcases); args[4] = malloc(10); sprintf(args[4], "%d", base_info_shmid); args[5] = NULL; launcher_pid = fork(); if (launcher_pid < 0) { db_error("core: fork launcher process failed(%s)\n", strerror(errno)); } else if (launcher_pid == 0) { execvp(binary, args); db_error("core: can't run %s(%s)\n", binary, strerror(errno)); _exit(-1); } /* listening to child process */ db_msg("core: listening to child process, starting...\n"); from_child = fopen(CMD_PIPE_NAME, "r"); while (1) { if (fgets(buffer, sizeof(buffer), from_child) == NULL) { continue; } db_dump("core: command from child: %s", buffer); /* test completion */ test_case_id_s = strtok(buffer, " \n"); db_dump("test case id #%s\n", test_case_id_s); if (strcmp(buffer, TEST_COMPLETION) == 0) break; if (test_case_id_s == NULL) continue; test_case_id = atoi(test_case_id_s); result_s = strtok(NULL, " \n"); db_dump("result: %s\n", result_s); if (result_s == NULL) continue; result = atoi(result_s); exdata = strtok(NULL, "\n"); db_dump("%s TEST %s\n", base_info[test_case_id].name, (result == 0) ? "OK" : "Fail"); /* update view item */ memset(&it_data, 0, sizeof(struct item_data)); strncpy(it_data.name, base_info[test_case_id].name, 32); strncpy(it_data.display_name, base_info[test_case_id].display_name, 64); it_data.category = base_info[test_case_id].category; it_data.status = result; if (exdata) { /* trim space */ while (*exdata == ' ' || *exdata == '\t') exdata++; exdata_len = strlen(exdata); exdata_len--; while (exdata >= 0 && (exdata[exdata_len] == ' ' || exdata[exdata_len] == '\t')) exdata_len--; if (exdata_len > 0) { exdata[++exdata_len] = '\0'; db_dump("extra data len #%d: %s\n", exdata_len, exdata); strncpy(it_data.exdata, exdata, 64); } } view_update_item(test_case_id, &it_data); } fclose(from_child); db_msg("core: listening to child process, stoping...\n"); deparse_testcase(); exit_view(); deinit_script(); deparse_script(script_shmid); return 0; }
bool itemdb_readdb(ZString filename) { bool rv = true; int ln = 0, lines = 0; { io::ReadFile in(filename); if (!in.is_open()) { PRINTF("can't read %s\n", filename); return false; } lines = 0; FString line; while (in.getline(line)) { lines++; if (is_comment(line)) continue; // a line is 17 normal fields followed by 2 {} fields // the fields are separated by ", *", but there may be , // in the {}. auto it = std::find(line.begin(), line.end(), '{'); XString main_part = line.xislice_h(it).rstrip(); // According to the code, tail_part may be empty. See later. ZString tail_part = line.xislice_t(it); item_data idv {}; if (!extract( main_part, record<','>( &idv.nameid, lstripping(&idv.name), lstripping(&idv.jname), lstripping(&idv.type), lstripping(&idv.value_buy), lstripping(&idv.value_sell), lstripping(&idv.weight), lstripping(&idv.atk), lstripping(&idv.def), lstripping(&idv.range), lstripping(&idv.magic_bonus), lstripping(&idv.slot), lstripping(&idv.sex), lstripping(&idv.equip), lstripping(&idv.wlv), lstripping(&idv.elv), lstripping(&idv.look) ) ) ) { PRINTF("%s:%d: error: bad item line: %s\n", filename, lines, line); rv = false; continue; } ln++; struct item_data *id = itemdb_search(idv.nameid); *id = std::move(idv); if (id->value_buy == 0 && id->value_sell == 0) { } else if (id->value_buy == 0) { id->value_buy = id->value_sell * 2; } else if (id->value_sell == 0) { id->value_sell = id->value_buy / 2; } id->use_script = NULL; id->equip_script = NULL; if (!tail_part) continue; id->use_script = parse_script(tail_part, lines); tail_part = tail_part.xislice_t(std::find(tail_part.begin() + 1, tail_part.end(), '{')); if (!tail_part) continue; id->equip_script = parse_script(tail_part, lines); } PRINTF("read %s done (count=%d)\n", filename, ln); } return rv; }
/*========================================== * アイテムデータベースの読み込み *------------------------------------------ */ static int itemdb_readdb(void) { FILE *fp; char line[1024]; int ln=0,lines=0; int nameid,j; char *str[32],*p,*np; struct item_data *id; int i=0; char *filename[]={ "item_db.txt","item_db2.txt" }; for(i=0;i<2;i++){ sprintf(line, "%s/%s", db_path, filename[i]); fp=fopen(line,"r"); if(fp==NULL){ if(i>0) continue; ShowFatalError("can't read %s\n",line); exit(1); } lines=0; while(fgets(line,1020,fp)){ lines++; if(line[0]=='/' && line[1]=='/') continue; memset(str,0,sizeof(str)); for(j=0,np=p=line;j<19 && p;j++){ str[j]=p; p=strchr(p,','); if(p){ *p++=0; np=p; } } if(str[0]==NULL) continue; nameid=atoi(str[0]); if(nameid<=0) continue; if (j < 19) { //Crash-fix on broken item lines. [Skotlex] ShowWarning("Reading %s: Insufficient fields for item with id %d, skipping.\n", filename[i], nameid); continue; } ln++; //ID,Name,Jname,Type,Price,Sell,Weight,ATK,DEF,Range,Slot,Job,Job Upper,Gender,Loc,wLV,eLV,refineable,View id=itemdb_load(nameid); strncpy(id->name, str[1], ITEM_NAME_LENGTH-1); strncpy(id->jname, str[2], ITEM_NAME_LENGTH-1); id->type=atoi(str[3]); if (id->type == IT_DELAYCONSUME) { //Items that are consumed upon target confirmation //(yggdrasil leaf, spells & pet lures) [Skotlex] id->type = IT_USABLE; id->flag.delay_consume=1; } { int buy = atoi(str[4]), sell = atoi(str[5]); // if buying price > selling price * 2 consider it valid and don't change it [celest] if (buy && sell && buy > sell*2){ id->value_buy = buy; id->value_sell = sell; } else { // buy≠sell*2 は item_value_db.txt で指定してください。 if (sell) { // sell値を優先とする id->value_buy = sell*2; id->value_sell = sell; } else { id->value_buy = buy; id->value_sell = buy/2; } } // check for bad prices that can possibly cause exploits if (id->value_buy*75/100 < id->value_sell*124/100) { ShowWarning ("Item %s [%d] buying:%d < selling:%d\n", id->name, id->nameid, id->value_buy*75/100, id->value_sell*124/100); } } id->weight=atoi(str[6]); id->atk=atoi(str[7]); id->def=atoi(str[8]); id->range=atoi(str[9]); id->slot=atoi(str[10]); if (id->slot > MAX_SLOTS) { ShowWarning("itemdb_readdb: Item %d (%s) specifies %d slots, but the server only supports up to %d\n", nameid, id->jname, id->slot, MAX_SLOTS); id->slot = MAX_SLOTS; } itemdb_jobid2mapid(id->class_base, (unsigned int)strtoul(str[11],NULL,0)); id->class_upper = atoi(str[12]); id->sex = atoi(str[13]); if(id->equip != atoi(str[14])){ id->equip=atoi(str[14]); } if (!id->equip && itemdb_isequip2(id)) { ShowWarning("Item %d (%s) is an equipment with no equip-field! Making it an etc item.\n", nameid, id->jname); id->type = 3; } id->wlv=atoi(str[15]); id->elv=atoi(str[16]); id->flag.no_refine = atoi(str[17])?0:1; //If the refine column is 1, no_refine is 0 id->look=atoi(str[18]); id->flag.available=1; id->flag.value_notdc=0; id->flag.value_notoc=0; id->view_id=0; id->sex = itemdb_gendercheck(id); //Apply gender filtering. if (id->script) { script_free_code(id->script); id->script=NULL; } if (id->equip_script) { script_free_code(id->equip_script); id->equip_script=NULL; } if (id->unequip_script) { script_free_code(id->unequip_script); id->unequip_script=NULL; } if((p=strchr(np,'{'))==NULL) continue; str[19] = p; //Script np = strchr(p,'}'); while (np && np[1] && np[1] != ',') np = strchr(np+1,'}'); //Jump close brackets until the next field is found. if (!np || !np[1]) { //Couldn't find the end of the script field. id->script = parse_script(str[19],filename[i],lines,0); continue; } np[1] = '\0'; //Set end of script id->script = parse_script(str[19],filename[i],lines,0); np+=2; //Skip to next field if(!np || (p=strchr(np,'{'))==NULL) continue; str[20] = p; //Equip Script np = strchr(p,'}'); while (np && np[1] && np[1] != ',') np = strchr(np+1,'}'); //Jump close brackets until the next field is found. if (!np || !np[1]) { //Couldn't find the end of the script field. id->equip_script = parse_script(str[20],filename[i],lines,0); continue; } np[1] = '\0'; //Set end of script id->equip_script = parse_script(str[20],filename[i],lines,0); np+=2; //Skip comma, to next field if(!np || (p=strchr(np,'{'))==NULL) continue; //Unequip script, last column. id->unequip_script = parse_script(p,filename[i],lines,0); } fclose(fp); if (ln > 0) { ShowStatus("Done reading '"CL_WHITE"%d"CL_RESET"' entries in '"CL_WHITE"%s"CL_RESET"'.\n",ln,filename[i]); } ln=0; // reset to 0 } return 0; }
/*====================================== * SQL *=================================== */ static int itemdb_read_sqldb(void) { unsigned short nameid; struct item_data *id; char script[65535 + 2 + 1]; // Maximum length of MySQL TEXT type (65535) + 2 bytes for curly brackets + 1 byte for terminator char *item_db_name[] = { item_db_db, item_db2_db }; long unsigned int ln = 0; int i; // ---------- for (i = 0; i < 2; i++) { sprintf(tmp_sql, "SELECT * FROM `%s`", item_db_name[i]); // Execute the query; if the query execution succeeded... if (mysql_query(&mmysql_handle, tmp_sql) == 0) { sql_res = mysql_store_result(&mmysql_handle); // If the storage of the query result succeeded... if (sql_res) { // Parse each row in the query result into sql_row while ((sql_row = mysql_fetch_row(sql_res))) { /*Table structure is: 00 id 01 name_english 02 name_japanese 03 type 04 price_buy 05 price_sell 06 weight 07 attack 08 defence 09 range 10 slots 11 equip_jobs 12 equip_upper 13 equip_genders 14 equip_locations 15 weapon_level 16 equip_level 17 refineable 18 view 19 script 20 equip_script 21 unequip_script */ nameid = atoi(sql_row[0]); // If the identifier is not within the valid range, process the next row if (nameid == 0) continue; ln++; // ---------- id = itemdb_load(nameid); strncpy(id->name, sql_row[1], ITEM_NAME_LENGTH-1); strncpy(id->jname, sql_row[2], ITEM_NAME_LENGTH-1); id->type = atoi(sql_row[3]); if (id->type == IT_DELAYCONSUME) { //Items that are consumed upon target confirmation //(yggdrasil leaf, spells & pet lures) [Skotlex] id->type = IT_USABLE; id->flag.delay_consume=1; } else //In case of an itemdb reload and the item type changed. id->flag.delay_consume=0; // If price_buy is not NULL and price_sell is not NULL... if ((sql_row[4] != NULL) && (sql_row[5] != NULL)) { id->value_buy = atoi(sql_row[4]); id->value_sell = atoi(sql_row[5]); } // If price_buy is not NULL and price_sell is NULL... else if ((sql_row[4] != NULL) && (sql_row[5] == NULL)) { id->value_buy = atoi(sql_row[4]); id->value_sell = atoi(sql_row[4]) / 2; } // If price_buy is NULL and price_sell is not NULL... else if ((sql_row[4] == NULL) && (sql_row[5] != NULL)) { id->value_buy = atoi(sql_row[5]) * 2; id->value_sell = atoi(sql_row[5]); } // If price_buy is NULL and price_sell is NULL... if ((sql_row[4] == NULL) && (sql_row[5] == NULL)) { id->value_buy = 0; id->value_sell = 0; } id->weight = atoi(sql_row[6]); id->atk = (sql_row[7] != NULL) ? atoi(sql_row[7]) : 0; id->def = (sql_row[8] != NULL) ? atoi(sql_row[8]) : 0; id->range = (sql_row[9] != NULL) ? atoi(sql_row[9]) : 0; id->slot = (sql_row[10] != NULL) ? atoi(sql_row[10]) : 0; if (id->slot > MAX_SLOTS) { ShowWarning("itemdb_read_sqldb: Item %d (%s) specifies %d slots, but the server only supports up to %d\n", nameid, id->jname, id->slot, MAX_SLOTS); id->slot = MAX_SLOTS; } itemdb_jobid2mapid(id->class_base, (sql_row[11] != NULL) ? (unsigned int)strtoul(sql_row[11], NULL, 0) : 0); id->class_upper= (sql_row[12] != NULL) ? atoi(sql_row[12]) : 0; id->sex = (sql_row[13] != NULL) ? atoi(sql_row[13]) : 0; id->equip = (sql_row[14] != NULL) ? atoi(sql_row[14]) : 0; if (!id->equip && itemdb_isequip2(id)) { ShowWarning("Item %d (%s) is an equipment with no equip-field! Making it an etc item.\n", nameid, id->jname); id->type = 3; } id->wlv = (sql_row[15] != NULL) ? atoi(sql_row[15]) : 0; id->elv = (sql_row[16] != NULL) ? atoi(sql_row[16]) : 0; id->flag.no_refine = (sql_row[17] == NULL || atoi(sql_row[17]) == 1)?0:1; id->look = (sql_row[18] != NULL) ? atoi(sql_row[18]) : 0; id->view_id = 0; id->sex = itemdb_gendercheck(id); //Apply gender filtering. // ---------- if (id->script) script_free_code(id->script); if (sql_row[19] != NULL) { if (sql_row[19][0] == '{') id->script = parse_script(sql_row[19],item_db_name[i], ln, 0); else { sprintf(script, "{%s}", sql_row[19]); id->script = parse_script(script, item_db_name[i], ln, 0); } } else id->script = NULL; if (id->equip_script) script_free_code(id->equip_script); if (sql_row[20] != NULL) { if (sql_row[20][0] == '{') id->equip_script = parse_script(sql_row[20], item_db_name[i], ln, 0); else { sprintf(script, "{%s}", sql_row[20]); id->equip_script = parse_script(script, item_db_name[i], ln, 0); } } else id->equip_script = NULL; if (id->unequip_script) script_free_code(id->unequip_script); if (sql_row[21] != NULL) { if (sql_row[21][0] == '{') id->unequip_script = parse_script(sql_row[21],item_db_name[i], ln, 0); else { sprintf(script, "{%s}", sql_row[21]); id->unequip_script = parse_script(script, item_db_name[i], ln, 0); } } else id->unequip_script = NULL; // ---------- id->flag.available = 1; id->flag.value_notdc = 0; id->flag.value_notoc = 0; } ShowStatus("Done reading '"CL_WHITE"%lu"CL_RESET"' entries in '"CL_WHITE"%s"CL_RESET"'.\n", ln, item_db_name[i]); ln = 0; } else { ShowSQL("DB error (%s) - %s\n",item_db_name[i], mysql_error(&mmysql_handle)); ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmp_sql); } // Free the query result mysql_free_result(sql_res); } else { ShowSQL("DB error (%s) - %s\n",item_db_name[i], mysql_error(&mmysql_handle)); ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmp_sql); } } return 0; }
/*========================================== * processes one itemdb entry *------------------------------------------*/ static bool itemdb_parse_dbrow(char** str, const char* source, int line, int scriptopt) { /* +----+--------------+---------------+------+-----------+------------+--------+--------+---------+-------+-------+------------+-------------+---------------+-----------------+--------------+-------------+------------+------+--------+--------------+----------------+ | 00 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | +----+--------------+---------------+------+-----------+------------+--------+--------+---------+-------+-------+------------+-------------+---------------+-----------------+--------------+-------------+------------+------+--------+--------------+----------------+ | id | name_english | name_japanese | type | price_buy | price_sell | weight | attack | defence | range | slots | equip_jobs | equip_upper | equip_genders | equip_locations | weapon_level | equip_level | refineable | view | script | equip_script | unequip_script | +----+--------------+---------------+------+-----------+------------+--------+--------+---------+-------+-------+------------+-------------+---------------+-----------------+--------------+-------------+------------+------+--------+--------------+----------------+ */ int nameid; struct item_data* id; nameid = atoi(str[0]); if( nameid <= 0 ) { ShowWarning("itemdb_parse_dbrow: Invalid id %d in line %d of \"%s\", skipping.\n", nameid, line, source); return false; } //ID,Name,Jname,Type,Price,Sell,Weight,ATK,DEF,Range,Slot,Job,Job Upper,Gender,Loc,wLV,eLV,refineable,View id = itemdb_load(nameid); safestrncpy(id->name, str[1], sizeof(id->name)); safestrncpy(id->jname, str[2], sizeof(id->jname)); id->type = atoi(str[3]); if( id->type < 0 || id->type == IT_UNKNOWN || id->type == IT_UNKNOWN2 || ( id->type > IT_DELAYCONSUME && id->type < IT_THROWWEAPON ) || id->type >= IT_MAX ) {// catch invalid item types ShowWarning("itemdb_parse_dbrow: Invalid item type %d for item %d. IT_ETC will be used.\n", id->type, nameid); id->type = IT_ETC; } if (id->type == IT_DELAYCONSUME) { //Items that are consumed only after target confirmation id->type = IT_USABLE; id->flag.delay_consume = 1; } else //In case of an itemdb reload and the item type changed. id->flag.delay_consume = 0; //When a particular price is not given, we should base it off the other one //(it is important to make a distinction between 'no price' and 0z) if ( str[4][0] ) id->value_buy = atoi(str[4]); else id->value_buy = atoi(str[5]) * 2; if ( str[5][0] ) id->value_sell = atoi(str[5]); else id->value_sell = id->value_buy / 2; /* if ( !str[4][0] && !str[5][0]) { ShowWarning("itemdb_parse_dbrow: No buying/selling price defined for item %d (%s), using 20/10z\n", nameid, id->jname); id->value_buy = 20; id->value_sell = 10; } else */ if (id->value_buy/124. < id->value_sell/75.) ShowWarning("itemdb_parse_dbrow: Buying/Selling [%d/%d] price of item %d (%s) allows Zeny making exploit through buying/selling at discounted/overcharged prices!\n", id->value_buy, id->value_sell, nameid, id->jname); id->weight = atoi(str[6]); #if REMODE itemdb_re_split_atoi(str[7],&id->atk,&id->matk); #else id->atk = atoi(str[7]); #endif id->def = atoi(str[8]); id->range = atoi(str[9]); id->slot = atoi(str[10]); if (id->slot > MAX_SLOTS) { ShowWarning("itemdb_parse_dbrow: Item %d (%s) specifies %d slots, but the server only supports up to %d. Using %d slots.\n", nameid, id->jname, id->slot, MAX_SLOTS, MAX_SLOTS); id->slot = MAX_SLOTS; } itemdb_jobid2mapid(id->class_base, (unsigned int)strtoul(str[11],NULL,0)); id->class_upper = atoi(str[12]); id->sex = atoi(str[13]); id->equip = atoi(str[14]); if (!id->equip && itemdb_isequip2(id)) { ShowWarning("Item %d (%s) is an equipment with no equip-field! Making it an etc item.\n", nameid, id->jname); id->type = IT_ETC; } id->wlv = atoi(str[15]); id->elv = atoi(str[16]); id->flag.no_refine = atoi(str[17]) ? 0 : 1; //FIXME: verify this id->look = atoi(str[18]); id->flag.available = 1; id->view_id = 0; id->sex = itemdb_gendercheck(id); //Apply gender filtering. if (id->script) { script_free_code(id->script); id->script = NULL; } if (id->equip_script) { script_free_code(id->equip_script); id->equip_script = NULL; } if (id->unequip_script) { script_free_code(id->unequip_script); id->unequip_script = NULL; } if (*str[19]) id->script = parse_script(str[19], source, line, scriptopt); if (*str[20]) id->equip_script = parse_script(str[20], source, line, scriptopt); if (*str[21]) id->unequip_script = parse_script(str[21], source, line, scriptopt); return true; }
static void test_scriptdisp(void) { IActiveScriptParse *parser; IDispatchEx *script_disp; IActiveScript *vbscript; DISPID id, id2; DISPPARAMS dp; EXCEPINFO ei; VARIANT v; ULONG ref; HRESULT hres; vbscript = create_vbscript(); hres = IActiveScript_QueryInterface(vbscript, &IID_IActiveScriptParse, (void**)&parser); ok(hres == S_OK, "Could not get IActiveScriptParse iface: %08x\n", hres); test_state(vbscript, SCRIPTSTATE_UNINITIALIZED); test_safety(vbscript); SET_EXPECT(GetLCID); hres = IActiveScript_SetScriptSite(vbscript, &ActiveScriptSite); ok(hres == S_OK, "SetScriptSite failed: %08x\n", hres); CHECK_CALLED(GetLCID); test_state(vbscript, SCRIPTSTATE_UNINITIALIZED); SET_EXPECT(OnStateChange_INITIALIZED); hres = IActiveScriptParse_InitNew(parser); ok(hres == S_OK, "InitNew failed: %08x\n", hres); CHECK_CALLED(OnStateChange_INITIALIZED); test_state(vbscript, SCRIPTSTATE_INITIALIZED); SET_EXPECT(OnStateChange_CONNECTED); hres = IActiveScript_SetScriptState(vbscript, SCRIPTSTATE_CONNECTED); ok(hres == S_OK, "SetScriptState(SCRIPTSTATE_CONNECTED) failed: %08x\n", hres); CHECK_CALLED(OnStateChange_CONNECTED); test_state(vbscript, SCRIPTSTATE_CONNECTED); script_disp = get_script_dispatch(vbscript); id = 100; get_disp_id(script_disp, "LCase", DISP_E_UNKNOWNNAME, &id); ok(id == -1, "id = %d, expected -1\n", id); get_disp_id(script_disp, "globalVariable", DISP_E_UNKNOWNNAME, &id); parse_script(parser, "dim globalVariable\nglobalVariable = 3"); get_disp_id(script_disp, "globalVariable", S_OK, &id); memset(&dp, 0, sizeof(dp)); memset(&ei, 0, sizeof(ei)); V_VT(&v) = VT_EMPTY; hres = IDispatchEx_InvokeEx(script_disp, id, 0, DISPATCH_PROPERTYGET|DISPATCH_METHOD, &dp, &v, &ei, NULL); ok(hres == S_OK, "InvokeEx failed: %08x\n", hres); ok(V_VT(&v) == VT_I2, "V_VT(v) = %d\n", V_VT(&v)); ok(V_I2(&v) == 3, "V_I2(v) = %d\n", V_I2(&v)); get_disp_id(script_disp, "globalVariable2", DISP_E_UNKNOWNNAME, &id); parse_script(parser, "globalVariable2 = 4"); get_disp_id(script_disp, "globalVariable2", S_OK, &id); get_disp_id(script_disp, "globalFunction", DISP_E_UNKNOWNNAME, &id); parse_script(parser, "function globalFunction()\nglobalFunction=5\nend function"); get_disp_id(script_disp, "globalFunction", S_OK, &id); SET_EXPECT(OnEnterScript); SET_EXPECT(OnLeaveScript); memset(&dp, 0, sizeof(dp)); memset(&ei, 0, sizeof(ei)); V_VT(&v) = VT_EMPTY; hres = IDispatchEx_InvokeEx(script_disp, id, 0, DISPATCH_PROPERTYGET|DISPATCH_METHOD, &dp, &v, &ei, NULL); ok(hres == S_OK, "InvokeEx failed: %08x\n", hres); ok(V_VT(&v) == VT_I2, "V_VT(v) = %d\n", V_VT(&v)); ok(V_I2(&v) == 5, "V_I2(v) = %d\n", V_I2(&v)); CHECK_CALLED(OnEnterScript); CHECK_CALLED(OnLeaveScript); SET_EXPECT(OnEnterScript); SET_EXPECT(OnLeaveScript); memset(&dp, 0, sizeof(dp)); memset(&ei, 0, sizeof(ei)); V_VT(&v) = VT_EMPTY; hres = IDispatchEx_Invoke(script_disp, id, &IID_NULL, 0, DISPATCH_PROPERTYGET|DISPATCH_METHOD, &dp, &v, &ei, NULL); ok(hres == S_OK, "InvokeEx failed: %08x\n", hres); ok(V_VT(&v) == VT_I2, "V_VT(v) = %d\n", V_VT(&v)); ok(V_I2(&v) == 5, "V_I2(v) = %d\n", V_I2(&v)); CHECK_CALLED(OnEnterScript); CHECK_CALLED(OnLeaveScript); get_disp_id(script_disp, "globalSub", DISP_E_UNKNOWNNAME, &id); parse_script(parser, "sub globalSub()\nend sub"); get_disp_id(script_disp, "globalSub", S_OK, &id); get_disp_id(script_disp, "globalSub", S_OK, &id2); ok(id == id2, "id != id2\n"); get_disp_id(script_disp, "constVariable", DISP_E_UNKNOWNNAME, &id); parse_script(parser, "const constVariable = 6"); get_disp_id(script_disp, "ConstVariable", S_OK, &id); get_disp_id(script_disp, "Constvariable", S_OK, &id2); ok(id == id2, "id != id2\n"); IDispatchEx_Release(script_disp); IActiveScriptParse_Release(parser); SET_EXPECT(OnStateChange_DISCONNECTED); SET_EXPECT(OnStateChange_INITIALIZED); SET_EXPECT(OnStateChange_CLOSED); hres = IActiveScript_Close(vbscript); ok(hres == S_OK, "Close failed: %08x\n", hres); CHECK_CALLED(OnStateChange_DISCONNECTED); CHECK_CALLED(OnStateChange_INITIALIZED); CHECK_CALLED(OnStateChange_CLOSED); ref = IActiveScript_Release(vbscript); ok(!ref, "ref = %d\n", ref); }
/** * <combo{:combo{:combo:{..}}}>,<{ script }> **/ void itemdb_read_combos() { uint32 lines = 0, count = 0; char line[1024]; char path[256]; FILE* fp; sprintf(path, "%s/%s", db_path, DBPATH"item_combo_db.txt"); if ((fp = fopen(path, "r")) == NULL) { ShowError("itemdb_read_combos: File not found \"%s\".\n", path); return; } // process rows one by one while(fgets(line, sizeof(line), fp)) { char *str[2], *p; lines++; if (line[0] == '/' && line[1] == '/') continue; memset(str, 0, sizeof(str)); p = line; p = trim(p); if (*p == '\0') continue;// empty line if (!strchr(p,',')) { /* is there even a single column? */ ShowError("itemdb_read_combos: Insufficient columns in line %d of \"%s\", skipping.\n", lines, path); continue; } str[0] = p; p = strchr(p,','); *p = '\0'; p++; str[1] = p; p = strchr(p,','); p++; if (str[1][0] != '{') { ShowError("itemdb_read_combos(#1): Invalid format (Script column) in line %d of \"%s\", skipping.\n", lines, path); continue; } /* no ending key anywhere (missing \}\) */ if ( str[1][strlen(str[1])-1] != '}' ) { ShowError("itemdb_read_combos(#2): Invalid format (Script column) in line %d of \"%s\", skipping.\n", lines, path); continue; } else { int items[MAX_ITEMS_PER_COMBO]; int v = 0, retcount = 0; struct item_data * id = NULL; int idx = 0; if((retcount = itemdb_combo_split_atoi(str[0], items)) < 2) { ShowError("itemdb_read_combos: line %d of \"%s\" doesn't have enough items to make for a combo (min:2), skipping.\n", lines, path); continue; } /* validate */ for(v = 0; v < retcount; v++) { if( !itemdb_exists(items[v]) ) { ShowError("itemdb_read_combos: line %d of \"%s\" contains unknown item ID %d, skipping.\n", lines, path,items[v]); break; } } /* failed at some item */ if( v < retcount ) continue; id = itemdb_exists(items[0]); idx = id->combos_count; /* first entry, create */ if( id->combos == NULL ) { CREATE(id->combos, struct item_combo*, 1); id->combos_count = 1; } else { RECREATE(id->combos, struct item_combo*, ++id->combos_count); } CREATE(id->combos[idx],struct item_combo,1); id->combos[idx]->nameid = aMalloc( retcount * sizeof(unsigned short) ); id->combos[idx]->count = retcount; id->combos[idx]->script = parse_script(str[1], path, lines, 0); id->combos[idx]->id = count; id->combos[idx]->isRef = false; /* populate ->nameid field */ for( v = 0; v < retcount; v++ ) { id->combos[idx]->nameid[v] = items[v]; } /* populate the children to refer to this combo */ for( v = 1; v < retcount; v++ ) { struct item_data * it = NULL; int index; it = itemdb_exists(items[v]); index = it->combos_count; if( it->combos == NULL ) { CREATE(it->combos, struct item_combo*, 1); it->combos_count = 1; } else {
/*================================== * SQL *=================================== */ static int itemdb_read_sqldb(void) { unsigned short nameid; unsigned long ln = 0; struct item_data *id; int buy_price, sell_price; char script[65535 + 2 + 1]; // Maximum length of MySQL TEXT type (65535) + 2 bytes for curly brackets + 1 byte for terminator // ---------- sql_request("SELECT * FROM `%s`", item_db_db); while (sql_get_row()) { /* +----+--------------+---------------+------+-----------+------------+--------+--------+---------+-------+-------+------------+-------------+---------------+-----------------+--------------+-------------+------------+------+--------+--------------+----------------+ | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | +----+--------------+---------------+------+-----------+------------+--------+--------+---------+-------+-------+------------+-------------+---------------+-----------------+--------------+-------------+------------+------+--------+--------------+----------------+ | id | name_english | name_japanese | type | price_buy | price_sell | weight | attack | defence | range | slots | equip_jobs | equip_upper | equip_genders | equip_locations | weapon_level | equip_level | refineable | view | script | equip_script | unequip_script | +----+--------------+---------------+------+-----------+------------+--------+--------+---------+-------+-------+------------+-------------+---------------+-----------------+--------------+-------------+------------+------+--------+--------------+----------------+ */ nameid = sql_get_integer(0); // If the identifier is not within the valid range, process the next row if (nameid == 0 || nameid >= 20000) continue; #ifdef __DEBUG if (battle_config.etc_log) { if (strlen(sql_get_string(1)) > 24) printf(CL_YELLOW "WARNING: Invalid item name" CL_RESET" (id: %d) - Name too long (> 24 char.) -> only 24 first characters are used.\n", nameid); if (strlen(sql_get_string(2)) > 24) printf(CL_YELLOW "WARNING: Invalid item jname" CL_RESET" (id: %d) - Name too long (> 24 char.) -> only 24 first characters are used.\n", nameid); } #endif ln++; if (ln % 22 == 21) { printf("Reading item #%ld (id: %d)...\r", ln, nameid); fflush(stdout); } // Insert a new row into the item database // ---------- id = itemdb_search(nameid); memset(id->name, 0, sizeof(id->name)); strncpy(id->name, sql_get_string(1), ITEM_NAME_LENGTH); memset(id->jname, 0, sizeof(id->jname)); strncpy(id->jname, sql_get_string(2), ITEM_NAME_LENGTH); id->type = sql_get_integer(3); if (id->type == 11) { id->type = 2; id->flag.delay_consume=1; } // fix NULL for buy/sell prices if (sql_get_string(4) == NULL) buy_price = 0; else buy_price = sql_get_integer(4); if (sql_get_string(5) == NULL) sell_price = 0; else sell_price = sql_get_integer(5); // If price_buy is not 0 and price_sell is not 0... if (buy_price > 0 && sell_price > 0) { id->value_buy = buy_price; id->value_sell = sell_price; // If price_buy is not 0 and price_sell is 0... } else if (buy_price > 0 && sell_price == 0) { id->value_buy = buy_price; id->value_sell = buy_price / 2; // If price_buy is 0 and price_sell is not 0... } else if (buy_price == 0 && sell_price > 0) { id->value_buy = sell_price * 2; id->value_sell = sell_price; // If price_buy is 0 and price_sell is 0... } else { id->value_buy = 0; id->value_sell = 0; } // check for bad prices that can possibly cause exploits if (((double)id->value_buy * (double)75) / 100 < ((double)id->value_sell * (double)124) / 100) { printf("Item %s [%d]: prices: buy %d / sell %d (" CL_YELLOW "WARNING" CL_RESET ").\n", id->name, id->nameid, id->value_buy, id->value_sell); printf("for merchant: buying: %d < selling:%d (" CL_YELLOW "possible exploit OC/DC" CL_RESET ").\n", id->value_buy * 75 / 100, id->value_sell * 124 / 100); id->value_buy = ((double)id->value_sell * (double)124) / (double)75 + 1; printf("->set to: buy %d, sell %d (change in database please).\n", id->value_buy, id->value_sell); } id->weight = sql_get_integer( 6); id->atk = (sql_get_string( 7) != NULL) ? sql_get_integer( 7) : 0; id->def = (sql_get_string( 8) != NULL) ? sql_get_integer( 8) : 0; id->range = (sql_get_string( 9) != NULL) ? sql_get_integer( 9) : 0; id->slot = (sql_get_string(10) != NULL) ? sql_get_integer(10) : 0; itemdb_jobid2mapid(id->class_base, (sql_get_string(11) != NULL) ? (unsigned int)strtoul(sql_get_string(11), NULL, 0) : 0); id->class_upper = (sql_get_string(12) != NULL) ? sql_get_integer(12) : 0; id->sex = (sql_get_string(13) != NULL) ? sql_get_integer(13) : 0; id->equip = (sql_get_string(14) != NULL) ? sql_get_integer(14) : 0; id->wlv = (sql_get_string(15) != NULL) ? sql_get_integer(15) : 0; id->elv = (sql_get_string(16) != NULL) ? sql_get_integer(16) : 0; id->flag.no_refine = (sql_get_integer(17) == 0 || sql_get_integer(17) == 1)?0:1; id->look = (sql_get_string(18) != NULL) ? sql_get_integer(18) : 0; id->view_id = 0; // ---------- if (sql_get_string(19) != NULL) { if (sql_get_string(19)[0] == '{') id->script = parse_script((unsigned char *)sql_get_string(19), 0); else { sprintf(script, "{%s}", sql_get_string(19)); id->script = parse_script((unsigned char *)script, 0); } } else { id->script = NULL; } if (sql_get_string(20) != NULL) { if (sql_get_string(20)[0] == '{') id->equip_script = parse_script((unsigned char *)sql_get_string(20), 0); else { sprintf(script, "{%s}", sql_get_string(20)); id->equip_script = parse_script((unsigned char *)script, 0); } } else { id->equip_script = NULL; } if (sql_get_string(21) != NULL) { if (sql_get_string(21)[0] == '{') id->unequip_script = parse_script((unsigned char *)sql_get_string(21), 0); else { sprintf(script, "{%s}", sql_get_string(21)); id->unequip_script = parse_script((unsigned char *)script, 0); } } else { id->equip_script = NULL; } // ---------- id->flag.available = 1; id->flag.value_notdc = 0; id->flag.value_notoc = 0; } printf("DB '" CL_WHITE "%s" CL_RESET "' readed ('" CL_WHITE "%ld" CL_RESET "' entrie%s).\n", item_db_db, ln, (ln > 1) ? "s" : ""); return 0; }
/*========================================== * アイテムデータベースの読み込み *------------------------------------------ */ static int itemdb_readdb(void) { FILE *fp; char line[1024]; int ln, lines = 0; int nameid, j; char *str[32], *p, *np; struct item_data *id; int i = 0; int buy_price, sell_price; char *filename[] = { "db/item_db.txt", "db/item_db2.txt" }; #define ITEM_DB_SQL_NAME "item_db_map.sql" #ifdef USE_SQL FILE *item_db_fp = NULL; // need to be initialized to avoid 'false' warning // code to create SQL item db if (create_item_db_script) { // if file exists (doesn't exist, was renamed!... unnormal that continue to exist) if (access(ITEM_DB_SQL_NAME, 0) == 0) // 0: file exist or not, 0 = success remove(ITEM_DB_SQL_NAME); // delete the file. return value = 0 (success), return value = -1 (denied access or not found file) if ((item_db_fp = fopen(ITEM_DB_SQL_NAME, "a")) != NULL) { printf("Generating the '" CL_WHITE ITEM_DB_SQL_NAME CL_RESET "' file.\n"); fprintf(item_db_fp, "# You can regenerate this file with an option in inter_athena.conf" RETCODE); fprintf(item_db_fp, RETCODE); fprintf(item_db_fp, "DROP TABLE IF EXISTS `%s`;" RETCODE, item_db_db); fprintf(item_db_fp, "CREATE TABLE `%s` (" RETCODE, item_db_db); fprintf(item_db_fp, " `id` smallint(5) unsigned NOT NULL default '0'," RETCODE); fprintf(item_db_fp, " `name_english` varchar(50) NOT NULL default ''," RETCODE); fprintf(item_db_fp, " `name_japanese` varchar(50) NOT NULL default ''," RETCODE); fprintf(item_db_fp, " `type` tinyint(2) unsigned NOT NULL default '0'," RETCODE); fprintf(item_db_fp, " `price_buy` meduimint(10) unsigned default NULL," RETCODE); fprintf(item_db_fp, " `price_sell` mediumint(10) unsigned default NULL," RETCODE); fprintf(item_db_fp, " `weight` smallint(5) unsigned NOT NULL default '0'," RETCODE); fprintf(item_db_fp, " `attack` tinyint(4) unsigned default NULL," RETCODE); fprintf(item_db_fp, " `defence` tinyint(4) unsigned default NULL," RETCODE); fprintf(item_db_fp, " `range` tinyint(2) unsigned default NULL," RETCODE); fprintf(item_db_fp, " `slots` tinyint(2) unsigned default NULL," RETCODE); // max 5, but set to tinyint(2) to avoid possible BOOL replacement fprintf(item_db_fp, " `equip_jobs` int(12) unsigned default NULL," RETCODE); fprintf(item_db_fp, " `equip_upper` tinyint(8) unsigned default NULL," RETCODE); fprintf(item_db_fp, " `equip_genders` tinyint(2) unsigned default NULL," RETCODE); // max 3 (1+2), but set to tinyint(2) to avoid possible BOOL replacement fprintf(item_db_fp, " `equip_locations` smallint(4) unsigned default NULL," RETCODE); fprintf(item_db_fp, " `weapon_level` tinyint(2) unsigned default NULL," RETCODE); // max 4, but set to tinyint(2) to avoid possible BOOL replacement fprintf(item_db_fp, " `equip_level` tinyint(3) unsigned default NULL," RETCODE); fprintf(item_db_fp, " `refineable` tinyint(1) unsigned default NULL," RETCODE); fprintf(item_db_fp, " `view` tinyint(3) unsigned default NULL," RETCODE); fprintf(item_db_fp, " `script` text," RETCODE); fprintf(item_db_fp, " `equip_script` text," RETCODE); fprintf(item_db_fp, " `unequip_script` text," RETCODE); fprintf(item_db_fp, " PRIMARY KEY (`id`)" RETCODE); fprintf(item_db_fp, ") TYPE=MyISAM;" RETCODE); fprintf(item_db_fp, RETCODE); } else { printf(CL_RED "Can not generate the '" ITEM_DB_SQL_NAME "' file." CL_RESET" \n"); create_item_db_script = 0; // not continue to try to create file after } } #endif /* USE_SQL */ for(i = 0; i < 2; i++) { ln = 0; fp = fopen(filename[i], "r"); if (fp == NULL) { if (i > 0) continue; printf("can't read %s\n", filename[i]); #ifdef USE_SQL if (create_item_db_script && item_db_fp != NULL) { fclose(item_db_fp); } #endif /* USE_SQL */ exit(1); } lines = 0; while(fgets(line, sizeof(line), fp)) { // fgets reads until maximum one less than size and add '\0' -> so, it's not necessary to add -1 lines++; if ((line[0] == '/' && line[1] == '/') || line[0] == '\0' || line[0] == '\n' || line[0] == '\r') { #ifdef USE_SQL // code to create SQL item db if (create_item_db_script && item_db_fp != NULL) { /* remove carriage return if exist */ while(line[0] != '\0' && (line[(j = strlen(line) - 1)] == '\n' || line[j] == '\r')) line[j] = '\0'; // add comments in the sql script if ((line[0] == '/' && line[1] == '/' && strlen(line) > 2)) { fprintf(item_db_fp, "#%s" RETCODE, line + 2); } else { fprintf(item_db_fp, RETCODE); } } #endif /* USE_SQL */ continue; } /* remove carriage return if exist */ while(line[0] != '\0' && (line[(j = strlen(line) - 1)] == '\n' || line[j] == '\r')) line[j] = '\0'; memset(str, 0, sizeof(str)); for(j = 0, np = p = line; j < 19 && p; j++) { str[j] = p; p = strchr(p, ','); if (p) { *p++ = 0; np = p; } } if (str[0] == NULL) continue; nameid = atoi(str[0]); if (nameid <= 0 || nameid >= 20000) continue; #ifdef __DEBUG if (battle_config.etc_log) { if (strlen(str[1]) > ITEM_NAME_LENGTH) printf(CL_YELLOW "WARNING: Invalid item name" CL_RESET" (id: %d) - Name too long (> ITEM_NAME_LENGTH char.) -> only ITEM_NAME_LENGTH first characters are used.\n", nameid); if (strlen(str[2]) > ITEM_NAME_LENGTH) printf(CL_YELLOW "WARNING: Invalid item jname" CL_RESET" (id: %d) - Name too long (> ITEM_NAME_LENGTH char.) -> only ITEM_NAME_LENGTH first characters are used.\n", nameid); } #endif ln++; if (ln % 20 == 19) { printf("Reading item #%d (id: %d)...\r", ln, nameid); fflush(stdout); } id = itemdb_search(nameid); memset(id->name, 0, sizeof(id->name)); strncpy(id->name, str[1], ITEM_NAME_LENGTH); memset(id->jname, 0, sizeof(id->jname)); strncpy(id->jname, str[2], ITEM_NAME_LENGTH); id->type = atoi(str[3]); if (id->type == 11) { id->type = 2; id->flag.delay_consume = 1; } buy_price = atoi(str[4]); sell_price = atoi(str[5]); // If price_buy is not 0 and price_sell is not 0... if (buy_price > 0 && sell_price > 0) { id->value_buy = buy_price; id->value_sell = sell_price; // If price_buy is not 0 and price_sell is 0... } else if (buy_price > 0 && sell_price == 0) { id->value_buy = buy_price; id->value_sell = buy_price / 2; // If price_buy is 0 and price_sell is not 0... } else if (buy_price == 0 && sell_price > 0) { id->value_buy = sell_price * 2; id->value_sell = sell_price; // If price_buy is 0 and price_sell is 0... } else { id->value_buy = 0; id->value_sell = 0; } // check for bad prices that can possibly cause exploits if (((double)id->value_buy * (double)75) / 100 < ((double)id->value_sell * (double)124) / 100) { printf("Item %s [%d]: prices: buy %d / sell %d (" CL_YELLOW "WARNING" CL_RESET ").\n", id->name, id->nameid, id->value_buy, id->value_sell); printf("for merchant: buying: %d < selling:%d (" CL_YELLOW "possible exploit OC/DC" CL_RESET ").\n", id->value_buy * 75 / 100, id->value_sell * 124 / 100); id->value_buy = ((double)id->value_sell * (double)124) / (double)75 + 1; printf("->set to: buy %d, sell %d (change in database please).\n", id->value_buy, id->value_sell); } id->weight = atoi(str[6]); id->atk = atoi(str[7]); id->def = atoi(str[8]); id->range = atoi(str[9]); id->slot = atoi(str[10]); itemdb_jobid2mapid(id->class_base, (unsigned int)strtoul(str[11],NULL,0)); id->class_upper = atoi(str[12]); id->sex = atoi(str[13]); if (id->equip != atoi(str[14])) { id->equip = atoi(str[14]); } id->wlv = atoi(str[15]); id->elv = atoi(str[16]); id->flag.no_refine = atoi(str[17]) ? 0 : 1; id->look = atoi(str[18]); id->flag.available = 1; id->flag.value_notdc = 0; id->flag.value_notoc = 0; id->view_id = 0; id->script = NULL; id->equip_script = NULL; id->unequip_script = NULL; if ((p = strchr(np, '{')) != NULL) { id->script = parse_script((unsigned char *)p, lines); if ((p = strchr(p + 1, '{')) != NULL) id->equip_script = parse_script((unsigned char *)p, lines); if ((p = strchr(p + 1, '{')) != NULL) id->unequip_script = parse_script((unsigned char *)p, lines); } #ifdef USE_SQL /* // code to create SQL item db if (create_item_db_script && item_db_fp != NULL) { char item_name[50]; // 24 * 2 + 1 + NULL char item_jname[50]; // 24 * 2 + 1 + NULL char script1[1024], script2[1024], script3[1024], temp_script[1024], comment_script[1024]; char *p1, *p2, *p3; struct item_data *actual_item; actual_item = id; // escape item names memset(item_name, 0, sizeof(item_name)); db_sql_escape_string(item_name, actual_item->name, strlen(actual_item->name)); memset(item_jname, 0, sizeof(item_jname)); db_sql_escape_string(item_jname, actual_item->jname, strlen(actual_item->jname)); // extract script 1, 2 and 3 memset(script1, 0, sizeof(script1)); memset(script2, 0, sizeof(script2)); memset(script3, 0, sizeof(script3)); if ((p1 = strchr(np, '{')) != NULL && (p2 = strchr(p1, '}')) != NULL && (p3 = strchr(p3, '}')) != NULL)) { while(*p1 == ' ' || *p1 == '{') p1++; while((*p2 == ' ' || *p2 == '}') && p2 > p1) p2--; while((*p3 == ' ' || *p3 == '}') && p3 > p2) p3--; if (p2 > p1) { memset(temp_script, 0, sizeof(temp_script)); strncpy(temp_script, p1, p2 - p1 + 1); memset(script1, 0, sizeof(script1)); script1[0] = '\''; db_sql_escape_string(script1 + 1, temp_script, strlen(temp_script)); strcat(script1, "'"); } // search second script if ((p1 = strchr(p2, '{')) != NULL && (p2 = strchr(p1, '}')) != NULL) { while(*p1 == ' ' || *p1 == '{') p1++; while((*p2 == ' ' || *p2 == '}') && p2 > p1) p2--; if (p2 > p1) { memset(temp_script, 0, sizeof(temp_script)); strncpy(temp_script, p1, p2 - p1 + 1); memset(script2, 0, sizeof(script2)); script2[0] = '\''; db_sql_escape_string(script2 + 1, temp_script, strlen(temp_script)); strcat(script2, "'"); } } if ((p1 = strchr(p2, '{')) != NULL && (p2 = strchr(p1, '}')) != NULL) { while(*p1 == ' ' || *p1 == '{') p1++; while((*p2 == ' ' || *p2 == '}') && p2 > p1) p2--; if (p2 > p1) { memset(temp_script, 0, sizeof(temp_script)); strncpy(temp_script, p1, p2 - p1 + 1); memset(script3, 0, sizeof(script3)); script3[0] = '\''; db_sql_escape_string(script3 + 1, temp_script, strlen(temp_script)); strcat(script3, "'"); } } } memset(comment_script, 0 , sizeof(comment_script)); if ((p1 = strchr(np, '/')) != NULL && p1[1] == '/') { comment_script[0] = ' '; comment_script[1] = '#'; strcpy(comment_script + 2, p1 + 2); } // create request fprintf(item_db_fp, "INSERT INTO `%s` VALUES (%d, '%s', '%s', %d," " %d, %d," " %d, %d, %d, %d," " %d, '%s', %d, %d, %d," " %d, %d, %d, %d," " '%s', '%s', '%s');%s" RETCODE, item_db_db, nameid, item_name, item_jname, actual_item->type, atoi(str[4]), atoi(str[5]), // id->value_buy, id->value_sell: not modified actual_item->weight, actual_item->atk, actual_item->def, actual_item->range, actual_item->slot, str[11], actual_item->class_upper, actual_item->sex, actual_item->equip, actual_item->wlv, actual_item->elv, actual_item->flag.no_refine, actual_item->look, (script1[0] == 0) ? "NULL" : script1, (script2[0] == 0) ? "NULL" : script2, (script3[0] == 0) ? "NULL" : script3, comment_script); } */ #endif /* USE_SQL */ } fclose(fp); printf("DB '" CL_WHITE "%s" CL_RESET "' readed ('" CL_WHITE "%d" CL_RESET "' %s).\n", filename[i], ln, (ln > 1) ? "entries" : "entry"); } #ifdef USE_SQL // code to create SQL item db if (create_item_db_script && item_db_fp != NULL) { fclose(item_db_fp); } #endif /* USE_SQL */ return 0; }