Jump to content

Jonata Pontes

Members
  • Posts

    3
  • Joined

  • Last visited

About Jonata Pontes

  • Birthday 12/29/1991

Profile Information

  • Gender
    Male
  • Location
    Brzil
  • Server
    Vikings RO
  • Github: jonata516
  • Discord: Alemão#2417
  • Interests
    Aprender e compartilhar conhecimentos.

Contact Methods

Recent Profile Visitors

The recent visitors block is disabled and is not being shown to other users.

Jonata Pontes's Achievements

Drops

Drops (2/15)

  • Conversation Starter
  • First Post
  • Dedicated
  • Week One Done
  • One Month Later

Recent Badges

2

Reputation

  1. Hello, I am a pt-BR and I am not able to pull the data from mysql with accents to the server correctly. Everything that comes and goes to SQL with accents is in error. Exp: NPC PVP Bring the translation via sql: Error src: My inter_athena.conf file: // Athena InterServer configuration. // Contains settings shared/used by more than 1 server. // Options for both versions // Log Inter Connections, etc.? log_inter: 1 // Inter Log Filename inter_log_filename: log/inter.log // Level range for sharing within a party party_share_level: 255 // You can specify the codepage to use in your MySQL tables here. // (Note that this feature requires MySQL 4.1+) default_codepage: utf8mb4 // For IPs, ideally under linux, you want to use localhost instead of 127.0.0.1 // Under windows, you want to use 127.0.0.1. If you see a message like // "Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2)" // and you have localhost, switch it to 127.0.0.1 // Global SQL settings // overridden by local settings when the hostname is defined there // (currently only the login-server reads/obeys these settings) // MySQL Login server login_server_ip: 127.0.0.1 login_server_port: 3306 login_server_id: root login_server_pw: login_server_db: login_codepage:utf8mb4 login_case_sensitive: no ipban_db_ip: 127.0.0.1 ipban_db_port: 3306 ipban_db_id: root ipban_db_pw: ipban_db_db: ipban_codepage:utf8mb4 // MySQL Character server char_server_ip: 127.0.0.1 char_server_port: 3306 char_server_id: char_server_pw: char_server_db: // MySQL Map Server map_server_ip: 127.0.0.1 map_server_port: 3306 map_server_id: map_server_pw: map_server_db: // MySQL Log Database log_db_ip: 127.0.0.1 log_db_port: 3306 log_db_id: log_db_pw: log_db_db: log_codepage:utf8mb4 log_login_db: loginlog // MySQL Reconnect Settings // - mysql_reconnect_type: // 1: When MySQL disconnects during runtime, the server tries to reconnect // mysql_reconnect_count times and shuts down if unsuccessful. // 2: When mysql disconnects during runtime, it tries to reconnect indefinitely. mysql_reconnect_type: 2 mysql_reconnect_count: 1 // DO NOT CHANGE ANYTHING BEYOND THIS LINE UNLESS YOU KNOW YOUR DATABASE DAMN WELL // this is meant for people who KNOW their stuff, and for some reason want to change their // database layout. [CLOWNISIUS] // ALL MySQL Database Table names // Login Database Tables login_server_account_db: login ipban_table: ipbanlist // Shared global_acc_reg_num_table: global_acc_reg_num global_acc_reg_str_table: global_acc_reg_str // Char Database Tables char_db: char hotkey_db: hotkey scdata_db: sc_data cart_db: cart_inventory inventory_db: inventory charlog_db: charlog skill_db: skill interlog_db: interlog memo_db: memo guild_db: guild guild_alliance_db: guild_alliance guild_castle_db: guild_castle guild_expulsion_db: guild_expulsion guild_member_db: guild_member guild_skill_db: guild_skill guild_position_db: guild_position guild_storage_db: guild_storage party_db: party pet_db: pet friend_db: friends mail_db: mail mail_attachment_db: mail_attachments auction_db: auction quest_db: quest homunculus_db: homunculus skill_homunculus_db: skill_homunculus mercenary_db: mercenary mercenary_owner_db: mercenary_owner elemental_db: elemental skillcooldown_db: skillcooldown bonus_script_db: bonus_script acc_reg_num_table: acc_reg_num acc_reg_str_table: acc_reg_str char_reg_str_table: char_reg_str char_reg_num_table: char_reg_num clan_table: clan clan_alliance_table: clan_alliance // Map Database Tables buyingstore_table: buyingstores buyingstore_items_table: buyingstore_items item_table: item_db renewal-item_table: item_db_re item2_table: item_db2 renewal-item2_table: item_db2_re item_cash_table: item_cash_db item_cash2_table: item_cash_db2 mob_table: mob_db renewal-mob_table: mob_db_re mob2_table: mob_db2 renewal-mob2_table: mob_db2_re mob_skill_table: mob_skill_db renewal-mob_skill_table: mob_skill_db_re mob_skill2_table: mob_skill_db2 renewal-mob_skill2_table: mob_skill_db2_re mapreg_table: mapreg sales_table: sales vending_table: vendings vending_items_table: vending_items market_table: market roulette_table: db_roulette guild_storage_log: guild_storage_log // Use SQL item_db, mob_db and mob_skill_db for the map server? (yes/no) use_sql_db: no inter_server_conf: inter_server.yml import: conf/import/inter_conf.txt I also edited the sql file: // Copyright (c) rAthena Dev Teams - Licensed under GNU GPL // For more information, see LICENCE in the main folder #include "sql.hpp" #ifdef WIN32 #include "winapi.hpp" #endif #include <mysql.h> #include <stdlib.h>// strtoul #include "cbasetypes.hpp" #include "malloc.hpp" #include "showmsg.hpp" #include "strlib.hpp" #include "timer.hpp" // MySQL 8.0 or later removed my_bool typedef. // Reintroduce it as a bandaid fix. // See https://bugs.mysql.com/?id=87337 #if !defined(MARIADB_BASE_VERSION) && !defined(MARIADB_VERSION_ID) && MYSQL_VERSION_ID >= 80001 && MYSQL_VERSION_ID != 80002 #define my_bool bool #endif #define SQL_CONF_NAME "conf/inter_athena.conf" void ra_mysql_error_handler(unsigned int ecode); int mysql_reconnect_type; unsigned int mysql_reconnect_count; /// Sql handle struct Sql { StringBuf buf; MYSQL handle; MYSQL_RES* result; MYSQL_ROW row; unsigned long* lengths; int keepalive; }; // Column length receiver. // Takes care of the possible size missmatch between uint32 and unsigned long. struct s_column_length { uint32* out_length; unsigned long length; }; typedef struct s_column_length s_column_length; /// Sql statement struct SqlStmt { StringBuf buf; MYSQL_STMT* stmt; MYSQL_BIND* params; MYSQL_BIND* columns; s_column_length* column_lengths; size_t max_params; size_t max_columns; bool bind_params; bool bind_columns; }; /////////////////////////////////////////////////////////////////////////////// // Sql Handle /////////////////////////////////////////////////////////////////////////////// /// Allocates and initializes a new Sql handle. Sql* Sql_Malloc(void) { Sql* self; CREATE(self, Sql, 1); mysql_init(&self->handle); StringBuf_Init(&self->buf); self->lengths = NULL; self->result = NULL; self->keepalive = INVALID_TIMER; my_bool reconnect = 1; mysql_options(&self->handle, MYSQL_OPT_RECONNECT, &reconnect); return self; } static int Sql_P_Keepalive(Sql* self); /** * Establishes a connection to schema * @param self : sql handle * @param user : username to access * @param passwd : password * @param host : hostname * @param port : port * @param db : schema name * @return */ int Sql_Connect(Sql* self, const char* user, const char* passwd, const char* host, uint16 port, const char* db) { if( self == NULL ) return SQL_ERROR; StringBuf_Clear(&self->buf); if( !mysql_real_connect(&self->handle, host, user, passwd, db, (unsigned int)port, NULL/*unix_socket*/, 0/*clientflag*/) ) { ShowSQL("%s\n", mysql_error(&self->handle)); return SQL_ERROR; } // Força charset utf8mb4 após conexão Sql_SetEncoding(self, "utf8mb4"); self->keepalive = Sql_P_Keepalive(self); if( self->keepalive == INVALID_TIMER ) { ShowSQL("Failed to establish keepalive for DB connection!\n"); return SQL_ERROR; } return SQL_SUCCESS; } /// Retrieves the timeout of the connection. int Sql_GetTimeout(Sql* self, uint32* out_timeout) { if( self && out_timeout && SQL_SUCCESS == Sql_Query(self, "SHOW VARIABLES LIKE 'wait_timeout'") ) { char* data; size_t len; if( SQL_SUCCESS == Sql_NextRow(self) && SQL_SUCCESS == Sql_GetData(self, 1, &data, &len) ) { *out_timeout = (uint32)strtoul(data, NULL, 10); Sql_FreeResult(self); return SQL_SUCCESS; } Sql_FreeResult(self); } return SQL_ERROR; } /// Retrieves the name of the columns of a table into out_buf, with the separator after each name. int Sql_GetColumnNames(Sql* self, const char* table, char* out_buf, size_t buf_len, char sep) { char* data; size_t len; size_t off = 0; if( self == NULL || SQL_ERROR == Sql_Query(self, "EXPLAIN `%s`", table) ) return SQL_ERROR; out_buf[off] = '\0'; while( SQL_SUCCESS == Sql_NextRow(self) && SQL_SUCCESS == Sql_GetData(self, 0, &data, &len) ) { len = strnlen(data, len); if( off + len + 2 > buf_len ) { ShowDebug("Sql_GetColumns: output buffer is too small\n"); *out_buf = '\0'; return SQL_ERROR; } memcpy(out_buf+off, data, len); off += len; out_buf[off++] = sep; } out_buf[off] = '\0'; Sql_FreeResult(self); return SQL_SUCCESS; } /// Changes the encoding of the connection. int Sql_SetEncoding(Sql* self, const char* encoding) { if( self && Sql_Query(self, "SET NAMES %s", encoding) == 0 ) return SQL_SUCCESS; return SQL_ERROR; } /// Pings the connection. int Sql_Ping(Sql* self) { if( self && mysql_ping(&self->handle) == 0 ) return SQL_SUCCESS; return SQL_ERROR; } /// Wrapper function for Sql_Ping. /// /// @private static TIMER_FUNC(Sql_P_KeepaliveTimer){ Sql* self = (Sql*)data; ShowInfo("Pinging SQL server to keep connection alive...\n"); Sql_Ping(self); return 0; } /// Establishes keepalive (periodic ping) on the connection. /// /// @return the keepalive timer id, or INVALID_TIMER /// @private static int Sql_P_Keepalive(Sql* self) { uint32 timeout, ping_interval; // set a default value first timeout = 28800; // 8 hours // request the timeout value from the mysql server Sql_GetTimeout(self, &timeout); if( timeout < 60 ) timeout = 60; // establish keepalive ping_interval = timeout - 30; // 30-second reserve //add_timer_func_list(Sql_P_KeepaliveTimer, "Sql_P_KeepaliveTimer"); return add_timer_interval(gettick() + ping_interval*1000, Sql_P_KeepaliveTimer, 0, (intptr_t)self, ping_interval*1000); } /// Escapes a string. size_t Sql_EscapeString(Sql* self, char *out_to, const char *from) { if( self ) return (size_t)mysql_real_escape_string(&self->handle, out_to, from, (unsigned long)strlen(from)); else return (size_t)mysql_escape_string(out_to, from, (unsigned long)strlen(from)); } /// Escapes a string. size_t Sql_EscapeStringLen(Sql* self, char *out_to, const char *from, size_t from_len) { if( self ) return (size_t)mysql_real_escape_string(&self->handle, out_to, from, (unsigned long)from_len); else return (size_t)mysql_escape_string(out_to, from, (unsigned long)from_len); } /// Executes a query. int Sql_Query(Sql* self, const char* query, ...) { int res; va_list args; va_start(args, query); res = Sql_QueryV(self, query, args); va_end(args); return res; } /// Executes a query. int Sql_QueryV(Sql* self, const char* query, va_list args) { if( self == NULL ) return SQL_ERROR; Sql_FreeResult(self); StringBuf_Clear(&self->buf); StringBuf_Vprintf(&self->buf, query, args); if( mysql_real_query(&self->handle, StringBuf_Value(&self->buf), (unsigned long)StringBuf_Length(&self->buf)) ) { ShowSQL("DB error - %s\n", mysql_error(&self->handle)); ra_mysql_error_handler(mysql_errno(&self->handle)); return SQL_ERROR; } self->result = mysql_store_result(&self->handle); if( mysql_errno(&self->handle) != 0 ) { ShowSQL("DB error - %s\n", mysql_error(&self->handle)); ra_mysql_error_handler(mysql_errno(&self->handle)); return SQL_ERROR; } return SQL_SUCCESS; } /// Executes a query. int Sql_QueryStr(Sql* self, const char* query) { if( self == NULL ) return SQL_ERROR; Sql_FreeResult(self); StringBuf_Clear(&self->buf); StringBuf_AppendStr(&self->buf, query); if( mysql_real_query(&self->handle, StringBuf_Value(&self->buf), (unsigned long)StringBuf_Length(&self->buf)) ) { ShowSQL("DB error - %s\n", mysql_error(&self->handle)); ra_mysql_error_handler(mysql_errno(&self->handle)); return SQL_ERROR; } self->result = mysql_store_result(&self->handle); if( mysql_errno(&self->handle) != 0 ) { ShowSQL("DB error - %s\n", mysql_error(&self->handle)); ra_mysql_error_handler(mysql_errno(&self->handle)); return SQL_ERROR; } return SQL_SUCCESS; } /// Returns the number of the AUTO_INCREMENT column of the last INSERT/UPDATE query. uint64 Sql_LastInsertId(Sql* self) { if( self ) return (uint64)mysql_insert_id(&self->handle); else return 0; } /// Returns the number of columns in each row of the result. uint32 Sql_NumColumns(Sql* self) { if( self && self->result ) return (uint32)mysql_num_fields(self->result); return 0; } /// Returns the number of rows in the result. uint64 Sql_NumRows(Sql* self) { if( self && self->result ) return (uint64)mysql_num_rows(self->result); return 0; } /// Returns the number of rows affected by the last query uint64 Sql_NumRowsAffected(Sql* self) { if( self ) return (uint64)mysql_affected_rows(&self->handle); return 0; } /// Fetches the next row. int Sql_NextRow(Sql* self) { if( self && self->result ) { self->row = mysql_fetch_row(self->result); if( self->row ) { self->lengths = mysql_fetch_lengths(self->result); return SQL_SUCCESS; } self->lengths = NULL; if( mysql_errno(&self->handle) == 0 ) return SQL_NO_DATA; } return SQL_ERROR; } /// Gets the data of a column. int Sql_GetData(Sql* self, size_t col, char** out_buf, size_t* out_len) { if( self && self->row ) { if( col < Sql_NumColumns(self) ) { if( out_buf ) *out_buf = self->row[col]; if( out_len ) *out_len = (size_t)self->lengths[col]; } else {// out of range - ignore if( out_buf ) *out_buf = NULL; if( out_len ) *out_len = 0; } return SQL_SUCCESS; } return SQL_ERROR; } /// Frees the result of the query. void Sql_FreeResult(Sql* self) { if( self && self->result ) { mysql_free_result(self->result); self->result = NULL; self->row = NULL; self->lengths = NULL; } } /// Shows debug information (last query). void Sql_ShowDebug_(Sql* self, const char* debug_file, const unsigned long debug_line) { if( self == NULL ) ShowDebug("at %s:%lu - self is NULL\n", debug_file, debug_line); else if( StringBuf_Length(&self->buf) > 0 ) ShowDebug("at %s:%lu - %s\n", debug_file, debug_line, StringBuf_Value(&self->buf)); else ShowDebug("at %s:%lu\n", debug_file, debug_line); } /// Frees a Sql handle returned by Sql_Malloc. void Sql_Free(Sql* self) { if( self ) { Sql_FreeResult(self); StringBuf_Destroy(&self->buf); if( self->keepalive != INVALID_TIMER ) delete_timer(self->keepalive, Sql_P_KeepaliveTimer); aFree(self); } } /////////////////////////////////////////////////////////////////////////////// // Prepared Statements /////////////////////////////////////////////////////////////////////////////// /// Returns the mysql integer type for the target size. /// /// @private static enum enum_field_types Sql_P_SizeToMysqlIntType(int sz) { switch( sz ) { case 1: return MYSQL_TYPE_TINY; case 2: return MYSQL_TYPE_SHORT; case 4: return MYSQL_TYPE_LONG; case 8: return MYSQL_TYPE_LONGLONG; default: ShowDebug("SizeToMysqlIntType: unsupported size (%d)\n", sz); return MYSQL_TYPE_NULL; } } /// Binds a parameter/result. /// /// @private static int Sql_P_BindSqlDataType(MYSQL_BIND* bind, enum SqlDataType buffer_type, void* buffer, size_t buffer_len, unsigned long* out_length, int8* out_is_null) { memset(bind, 0, sizeof(MYSQL_BIND)); switch( buffer_type ) { case SQLDT_NULL: bind->buffer_type = MYSQL_TYPE_NULL; buffer_len = 0;// FIXME length = ? [FlavioJS] break; // fixed size case SQLDT_UINT8: bind->is_unsigned = 1; case SQLDT_INT8: bind->buffer_type = MYSQL_TYPE_TINY; buffer_len = 1; break; case SQLDT_UINT16: bind->is_unsigned = 1; case SQLDT_INT16: bind->buffer_type = MYSQL_TYPE_SHORT; buffer_len = 2; break; case SQLDT_UINT32: bind->is_unsigned = 1; case SQLDT_INT32: bind->buffer_type = MYSQL_TYPE_LONG; buffer_len = 4; break; case SQLDT_UINT64: bind->is_unsigned = 1; case SQLDT_INT64: bind->buffer_type = MYSQL_TYPE_LONGLONG; buffer_len = 8; break; // platform dependent size case SQLDT_UCHAR: bind->is_unsigned = 1; case SQLDT_CHAR: bind->buffer_type = Sql_P_SizeToMysqlIntType(sizeof(char)); buffer_len = sizeof(char); break; case SQLDT_USHORT: bind->is_unsigned = 1; case SQLDT_SHORT: bind->buffer_type = Sql_P_SizeToMysqlIntType(sizeof(short)); buffer_len = sizeof(short); break; case SQLDT_UINT: bind->is_unsigned = 1; case SQLDT_INT: bind->buffer_type = Sql_P_SizeToMysqlIntType(sizeof(int)); buffer_len = sizeof(int); break; case SQLDT_ULONG: bind->is_unsigned = 1; case SQLDT_LONG: bind->buffer_type = Sql_P_SizeToMysqlIntType(sizeof(long)); buffer_len = sizeof(long); break; case SQLDT_ULONGLONG: bind->is_unsigned = 1; case SQLDT_LONGLONG: bind->buffer_type = Sql_P_SizeToMysqlIntType(sizeof(int64)); buffer_len = sizeof(int64); break; // floating point case SQLDT_FLOAT: bind->buffer_type = MYSQL_TYPE_FLOAT; buffer_len = 4; break; case SQLDT_DOUBLE: bind->buffer_type = MYSQL_TYPE_DOUBLE; buffer_len = 8; break; // other case SQLDT_STRING: case SQLDT_ENUM: bind->buffer_type = MYSQL_TYPE_STRING; break; case SQLDT_BLOB: bind->buffer_type = MYSQL_TYPE_BLOB; break; default: ShowDebug("Sql_P_BindSqlDataType: unsupported buffer type (%d)\n", buffer_type); return SQL_ERROR; } bind->buffer = buffer; bind->buffer_length = (unsigned long)buffer_len; bind->length = out_length; bind->is_null = (my_bool*)out_is_null; return SQL_SUCCESS; } /// Prints debug information about a field (type and length). /// /// @private static void Sql_P_ShowDebugMysqlFieldInfo(const char* prefix, enum enum_field_types type, int is_unsigned, unsigned long length, const char* length_postfix) { const char* sign = (is_unsigned ? "UNSIGNED " : ""); const char* type_string; switch( type ) { default: ShowDebug("%stype=%s%u, length=%lu\n", prefix, sign, type, length); return; #define SHOW_DEBUG_OF(x) case x: type_string = #x; break SHOW_DEBUG_OF(MYSQL_TYPE_TINY); SHOW_DEBUG_OF(MYSQL_TYPE_SHORT); SHOW_DEBUG_OF(MYSQL_TYPE_LONG); SHOW_DEBUG_OF(MYSQL_TYPE_INT24); SHOW_DEBUG_OF(MYSQL_TYPE_LONGLONG); SHOW_DEBUG_OF(MYSQL_TYPE_DECIMAL); SHOW_DEBUG_OF(MYSQL_TYPE_FLOAT); SHOW_DEBUG_OF(MYSQL_TYPE_DOUBLE); SHOW_DEBUG_OF(MYSQL_TYPE_TIMESTAMP); SHOW_DEBUG_OF(MYSQL_TYPE_DATE); SHOW_DEBUG_OF(MYSQL_TYPE_TIME); SHOW_DEBUG_OF(MYSQL_TYPE_DATETIME); SHOW_DEBUG_OF(MYSQL_TYPE_YEAR); SHOW_DEBUG_OF(MYSQL_TYPE_STRING); SHOW_DEBUG_OF(MYSQL_TYPE_VAR_STRING); SHOW_DEBUG_OF(MYSQL_TYPE_BLOB); SHOW_DEBUG_OF(MYSQL_TYPE_SET); SHOW_DEBUG_OF(MYSQL_TYPE_ENUM); SHOW_DEBUG_OF(MYSQL_TYPE_NULL); #undef SHOW_DEBUG_TYPE_OF } ShowDebug("%stype=%s%s, length=%lu%s\n", prefix, sign, type_string, length, length_postfix); } /// Reports debug information about a truncated column. /// /// @private static void SqlStmt_P_ShowDebugTruncatedColumn(SqlStmt* self, size_t i) { MYSQL_RES* meta; MYSQL_FIELD* field; MYSQL_BIND* column; meta = mysql_stmt_result_metadata(self->stmt); field = mysql_fetch_field_direct(meta, (unsigned int)i); ShowSQL("DB error - data of field '%s' was truncated.\n", field->name); ShowDebug("column - %lu\n", (unsigned long)i); Sql_P_ShowDebugMysqlFieldInfo("data - ", field->type, field->flags&UNSIGNED_FLAG, self->column_lengths[i].length, ""); column = &self->columns[i]; if( column->buffer_type == MYSQL_TYPE_STRING ) Sql_P_ShowDebugMysqlFieldInfo("buffer - ", column->buffer_type, column->is_unsigned, column->buffer_length, "+1(nul-terminator)"); else Sql_P_ShowDebugMysqlFieldInfo("buffer - ", column->buffer_type, column->is_unsigned, column->buffer_length, ""); mysql_free_result(meta); } /// Allocates and initializes a new SqlStmt handle. SqlStmt* SqlStmt_Malloc(Sql* sql) { SqlStmt* self; MYSQL_STMT* stmt; if( sql == NULL ) return NULL; stmt = mysql_stmt_init(&sql->handle); if( stmt == NULL ) { ShowSQL("DB error - %s\n", mysql_error(&sql->handle)); return NULL; } CREATE(self, SqlStmt, 1); StringBuf_Init(&self->buf); self->stmt = stmt; self->params = NULL; self->columns = NULL; self->column_lengths = NULL; self->max_params = 0; self->max_columns = 0; self->bind_params = false; self->bind_columns = false; return self; } /// Prepares the statement. int SqlStmt_Prepare(SqlStmt* self, const char* query, ...) { int res; va_list args; va_start(args, query); res = SqlStmt_PrepareV(self, query, args); va_end(args); return res; } /// Prepares the statement. int SqlStmt_PrepareV(SqlStmt* self, const char* query, va_list args) { if( self == NULL ) return SQL_ERROR; SqlStmt_FreeResult(self); StringBuf_Clear(&self->buf); StringBuf_Vprintf(&self->buf, query, args); if( mysql_stmt_prepare(self->stmt, StringBuf_Value(&self->buf), (unsigned long)StringBuf_Length(&self->buf)) ) { ShowSQL("DB error - %s\n", mysql_stmt_error(self->stmt)); ra_mysql_error_handler(mysql_stmt_errno(self->stmt)); return SQL_ERROR; } self->bind_params = false; return SQL_SUCCESS; } /// Prepares the statement. int SqlStmt_PrepareStr(SqlStmt* self, const char* query) { if( self == NULL ) return SQL_ERROR; SqlStmt_FreeResult(self); StringBuf_Clear(&self->buf); StringBuf_AppendStr(&self->buf, query); if( mysql_stmt_prepare(self->stmt, StringBuf_Value(&self->buf), (unsigned long)StringBuf_Length(&self->buf)) ) { ShowSQL("DB error - %s\n", mysql_stmt_error(self->stmt)); ra_mysql_error_handler(mysql_stmt_errno(self->stmt)); return SQL_ERROR; } self->bind_params = false; return SQL_SUCCESS; } /// Returns the number of parameters in the prepared statement. size_t SqlStmt_NumParams(SqlStmt* self) { if( self ) return (size_t)mysql_stmt_param_count(self->stmt); else return 0; } /// Binds a parameter to a buffer. int SqlStmt_BindParam(SqlStmt* self, size_t idx, enum SqlDataType buffer_type, void* buffer, size_t buffer_len) { if( self == NULL ) return SQL_ERROR; if( !self->bind_params ) {// initialize the bindings size_t i; size_t count; count = SqlStmt_NumParams(self); if( self->max_params < count ) { self->max_params = count; RECREATE(self->params, MYSQL_BIND, count); } memset(self->params, 0, count*sizeof(MYSQL_BIND)); for( i = 0; i < count; ++i ) self->params[i].buffer_type = MYSQL_TYPE_NULL; self->bind_params = true; } if( idx < self->max_params ) return Sql_P_BindSqlDataType(self->params+idx, buffer_type, buffer, buffer_len, NULL, NULL); else return SQL_SUCCESS;// out of range - ignore } /// Executes the prepared statement. int SqlStmt_Execute(SqlStmt* self) { if( self == NULL ) return SQL_ERROR; SqlStmt_FreeResult(self); if( (self->bind_params && mysql_stmt_bind_param(self->stmt, self->params)) || mysql_stmt_execute(self->stmt) ) { ShowSQL("DB error - %s\n", mysql_stmt_error(self->stmt)); ra_mysql_error_handler(mysql_stmt_errno(self->stmt)); return SQL_ERROR; } self->bind_columns = false; if( mysql_stmt_store_result(self->stmt) )// store all the data { ShowSQL("DB error - %s\n", mysql_stmt_error(self->stmt)); ra_mysql_error_handler(mysql_stmt_errno(self->stmt)); return SQL_ERROR; } return SQL_SUCCESS; } /// Returns the number of the AUTO_INCREMENT column of the last INSERT/UPDATE statement. uint64 SqlStmt_LastInsertId(SqlStmt* self) { if( self ) return (uint64)mysql_stmt_insert_id(self->stmt); else return 0; } /// Returns the number of columns in each row of the result. size_t SqlStmt_NumColumns(SqlStmt* self) { if( self ) return (size_t)mysql_stmt_field_count(self->stmt); else return 0; } /// Binds the result of a column to a buffer. int SqlStmt_BindColumn(SqlStmt* self, size_t idx, enum SqlDataType buffer_type, void* buffer, size_t buffer_len, uint32* out_length, int8* out_is_null) { if( self == NULL ) return SQL_ERROR; if( buffer_type == SQLDT_STRING || buffer_type == SQLDT_ENUM ) { if( buffer_len < 1 ) { ShowDebug("SqlStmt_BindColumn: buffer_len(%" PRIuPTR ") is too small, no room for the nul-terminator\n", buffer_len); return SQL_ERROR; } --buffer_len;// nul-terminator } if( !self->bind_columns ) {// initialize the bindings size_t i; size_t cols; cols = SqlStmt_NumColumns(self); if( self->max_columns < cols ) { self->max_columns = cols; RECREATE(self->columns, MYSQL_BIND, cols); RECREATE(self->column_lengths, s_column_length, cols); } memset(self->columns, 0, cols*sizeof(MYSQL_BIND)); memset(self->column_lengths, 0, cols*sizeof(s_column_length)); for( i = 0; i < cols; ++i ) self->columns[i].buffer_type = MYSQL_TYPE_NULL; self->bind_columns = true; } if( idx < self->max_columns ) { self->column_lengths[idx].out_length = out_length; return Sql_P_BindSqlDataType(self->columns+idx, buffer_type, buffer, buffer_len, &self->column_lengths[idx].length, out_is_null); } else { return SQL_SUCCESS;// out of range - ignore } } /// Returns the number of rows in the result. uint64 SqlStmt_NumRows(SqlStmt* self) { if( self ) return (uint64)mysql_stmt_num_rows(self->stmt); else return 0; } /// Fetches the next row. int SqlStmt_NextRow(SqlStmt* self) { int err; size_t i; size_t cols; if( self == NULL ) return SQL_ERROR; // bind columns if( self->bind_columns && mysql_stmt_bind_result(self->stmt, self->columns) ) err = 1;// error binding columns else err = mysql_stmt_fetch(self->stmt);// fetch row // check for errors if( err == MYSQL_NO_DATA ) return SQL_NO_DATA; #if defined(MYSQL_DATA_TRUNCATED) // MySQL 5.0/5.1 defines and returns MYSQL_DATA_TRUNCATED [FlavioJS] if( err == MYSQL_DATA_TRUNCATED ) { my_bool truncated; if( !self->bind_columns ) { ShowSQL("DB error - data truncated (unknown source, columns are not bound)\n"); return SQL_ERROR; } // find truncated column cols = SqlStmt_NumColumns(self); for( i = 0; i < cols; ++i ) { MYSQL_BIND* column = &self->columns[i]; column->error = &truncated; mysql_stmt_fetch_column(self->stmt, column, (unsigned int)i, 0); column->error = NULL; if( truncated ) {// report truncated column SqlStmt_P_ShowDebugTruncatedColumn(self, i); return SQL_ERROR; } } ShowSQL("DB error - data truncated (unknown source)\n"); return SQL_ERROR; } #endif if( err ) { ShowSQL("DB error - %s\n", mysql_stmt_error(self->stmt)); ra_mysql_error_handler(mysql_stmt_errno(self->stmt)); return SQL_ERROR; } // propagate column lengths and clear unused parts of string/enum/blob buffers cols = SqlStmt_NumColumns(self); for( i = 0; i < cols; ++i ) { unsigned long length = self->column_lengths[i].length; MYSQL_BIND* column = &self->columns[i]; #if !defined(MYSQL_DATA_TRUNCATED) // MySQL 4.1/(below?) returns success even if data is truncated, so we test truncation manually [FlavioJS] if( column->buffer_length < length ) {// report truncated column if( column->buffer_type == MYSQL_TYPE_STRING || column->buffer_type == MYSQL_TYPE_BLOB ) {// string/enum/blob column SqlStmt_P_ShowDebugTruncatedColumn(self, i); return SQL_ERROR; } // FIXME numeric types and null [FlavioJS] } #endif if( self->column_lengths[i].out_length ) *self->column_lengths[i].out_length = (uint32)length; if( column->buffer_type == MYSQL_TYPE_STRING ) {// clear unused part of the string/enum buffer (and nul-terminate) memset((char*)column->buffer + length, 0, column->buffer_length - length + 1); } else if( column->buffer_type == MYSQL_TYPE_BLOB && length < column->buffer_length ) {// clear unused part of the blob buffer memset((char*)column->buffer + length, 0, column->buffer_length - length); } } return SQL_SUCCESS; } /// Frees the result of the statement execution. void SqlStmt_FreeResult(SqlStmt* self) { if( self ) mysql_stmt_free_result(self->stmt); } /// Shows debug information (with statement). void SqlStmt_ShowDebug_(SqlStmt* self, const char* debug_file, const unsigned long debug_line) { if( self == NULL ) ShowDebug("at %s:%lu - self is NULL\n", debug_file, debug_line); else if( StringBuf_Length(&self->buf) > 0 ) ShowDebug("at %s:%lu - %s\n", debug_file, debug_line, StringBuf_Value(&self->buf)); else ShowDebug("at %s:%lu\n", debug_file, debug_line); } /// Frees a SqlStmt returned by SqlStmt_Malloc. void SqlStmt_Free(SqlStmt* self) { if( self ) { SqlStmt_FreeResult(self); StringBuf_Destroy(&self->buf); mysql_stmt_close(self->stmt); if( self->params ) aFree(self->params); if( self->columns ) { aFree(self->columns); aFree(self->column_lengths); } aFree(self); } } /// Receives MySQL error codes during runtime (not on first-time-connects). void ra_mysql_error_handler(unsigned int ecode) { switch( ecode ) { case 2003:// Can't connect to MySQL (this error only happens here when failing to reconnect) if( mysql_reconnect_type == 1 ) { static unsigned int retry = 1; if( ++retry > mysql_reconnect_count ) { ShowFatalError("MySQL has been unreachable for too long, %d reconnects were attempted. Shutting Down\n", retry); exit(EXIT_FAILURE); } } break; } } void Sql_inter_server_read(const char* cfgName, bool first) { char line[1024], w1[1024], w2[1024]; FILE* fp; fp = fopen(cfgName, "r"); if(fp == NULL) { if( first ) { ShowFatalError("File not found: %s\n", cfgName); exit(EXIT_FAILURE); } else ShowError("File not found: %s\n", cfgName); return; } while(fgets(line, sizeof(line), fp)) { int i = sscanf(line, "%1023[^:]: %1023[^\r\n]", w1, w2); if(i != 2) continue; if(!strcmpi(w1,"mysql_reconnect_type")) { mysql_reconnect_type = atoi(w2); switch( mysql_reconnect_type ) { case 1: case 2: break; default: ShowError("%s::mysql_reconnect_type is set to %d which is not valid, defaulting to 1...\n", cfgName, mysql_reconnect_type); mysql_reconnect_type = 1; break; } } else if(!strcmpi(w1,"mysql_reconnect_count")) { mysql_reconnect_count = atoi(w2); if( mysql_reconnect_count < 1 ) mysql_reconnect_count = 1; } else if(!strcmpi(w1,"import")) Sql_inter_server_read(w2,false); } fclose(fp); return; } void Sql_Init(void) { Sql_inter_server_read(SQL_CONF_NAME,true); } #ifdef my_bool #undef my_bool #endif Help =[
  2. Provável já ter resolvido, ou desistido. No caso do rAthena, o erro está no comando soundeffectall, *soundeffectall "<effect filename>",<type>{,"<map name>"}{,<x0>,<y0>,<x1>,<y1>}; Segundo o GitHub do rAthena Onde se vê: O certo seria:
  3. Amigo, boa tarde. Sei que já tem tempo, mas peguei seu script que achei bem interessante e dei uma mexida. Vou postar aqui, vai que a galera precise de um UP. Coloquei refine por item especifico como no quadro abaixo: LVL ITEM 1 5 10 50 MATERIAL REFINO DE ATE 0 ARMOR 6225 16259 16261 Carnium Perfeito 10 10 4 WEAPON 6226 16258 16260 Bradium Perfeito 10 10 0 ARMOR 6241 16395 16396 17105 Elunium Perfeito 7 9 4 WEAPON 6240 16393 16394 17104 Oridecon Perfeito 7 9 0 ARMOR 7619 13610 Elunium Enriquecido 5 6 4 WEAPON 7620 13611 Oridecon Enriquecido 5 6 0 ARMOR 985 Elunium Refinado 1 4 4 WEAPON 984 Oridecon Refinado 1 4 LVL é o Weapon Level; ITEM é o Type; 1; 5; 10; 50 são os códigos dos itens onde 1 equivale a 1 unidade e o resto são box's; Material, alto explicativo; De Ate é o nível de refinamento que o item será usado, exemplo: Valk Armor +5 Utilizara 180 x 7619 - Elunium Enriquecido do nível 5 ao 6 e 6 ao 7. Depois 360 x 6241 - Elinium Perfeito do nível 7 ao 10. Tudo é configurável e o que não estava comentado eu comentei. Ahh, sou novo em escrever por aqui, aceito criticas. //==============Made by DoomSlayer============= //Ferreiro Custom - Quanto mais materiais maior //a chance de sucesso! //============================================= //==============Adaptation by JPontes============= //Melhoria no script //Adicionado chance por material especifico, //weapon leave. //http://www.vikingsro.com.br //============================================= prontera,150,180,3 script Blacksmith Custom 63,{ disable_items; mes "^0000FF"+.name$+"^000000"; mes "Eu sou o melhor Ferreiro de Valhalla!"; mes "Eu utilizo matéria-prima para realizar refinamentos em itens."; next; mes "^0000FF"+.name$+"^000000"; mes "Para fazer este serviço, eu preciso de um valor simbólico de "+.price+" Zeny, assim ofereço "+.chance+"% de sucesso no refinamento!"; mes "Caso você tenha os materiais necessarios, podemos chegar em "+(.chance + (.maxmat * .matchance))+"%."; next; mes "^0000FF"+.name$+"^000000"; mes "Cada material, aumentamos em "+.matchance+"% a chance de sucesso!"; mes "Quanto mais materiais você me der, mais chances de sucesso teremos!"; next; if (.break == 1){ mes "^0000FF"+.name$+"^000000"; mes "^996600!^000000^ff0000ATENÇÃO^000000^996600!^000000"; mes "Caso não obtenhamos sucesso, você poderá perder o item!"; mes "Aconselho tirar todas as Card's do equipamento!"; next; } switch(select("^00f000Vamos refinar^000000:Informações:^ff0000Não, obrigado!^000000")){ case 1: mes "^0000FF"+.name$+"^000000"; mes "Qual equipamento que você quer refinar?"; next; goto OnRefine; end; case 2: mes "^0000FF"+.name$+"^000000"; mes "Os itens necessários para o refinamento são:"; for( .@i = 0; .@i < getarraysize(.material); .@i++ ) mes "{"+.material[.@i]+"} - "+.namemat$[.@i]; next; switch(select("Escolher equipamento:Vou buscar os materiais")){ case 1: goto OnRefine; case 2: mes "^0000FF"+.name$+"^000000"; mes "Volte quando precisar de meus serviços!"; close; end; } case 3: mes "^0000FF"+.name$+"^000000"; mes "Volte quando precisar de meus serviços!"; close; end; } OnRefine: setarray .@indices[1], EQI_HEAD_TOP, EQI_ARMOR, EQI_HAND_L, EQI_HAND_R, EQI_GARMENT, EQI_SHOES, EQI_ACC_L, EQI_ACC_R, EQI_HEAD_MID, EQI_HEAD_LOW; for(.@i = 1; .@i<getarraysize(.@indices); ++.@i) { if(getequipisequiped(.@indices[.@i])) { .@menu$ = .@menu$ + F_getpositionname(.@indices[.@i]) + "-[" + getequipname(.@indices[.@i]) + "]"; .@equipped = 1; } .@menu$ = .@menu$ + ":"; } if (.@equipped == 0) { mes "^0000FF"+.name$+"^000000"; mes "Você não está equipando nada!"; close; } set .@part, .@indices[ select(.@menu$) ]; if (!getequipisenableref(.@part)) { mes "^0000FF"+.name$+"^000000"; mes "Este equipamento não pode ser refinado!"; close; } .@equip_id = getequipid(.@part); .@equip_refine = getequiprefinerycnt(.@part); setarray .@card[0], getequipcardid(.@part,0), getequipcardid(.@part,1), getequipcardid(.@part,2), getequipcardid(.@part,3); // +10 não refinar if (.@equip_refine >= 10) { // max refine mes "^0000FF"+.name$+"^000000"; mes "Este equipamento já está +10!"; mes "Escolha outro equipamento:"; next; goto OnRefine; end; // 0 a 4 } else if((.@equip_refine >= 0) && (.@equip_refine <= 4)){ if (getequipweaponlv(.@part) == 0){ set .@matuse,1; } else { set .@matuse,0; } goto OnRefineOk; // 5 a 6 } else if((.@equip_refine >= 5) && (.@equip_refine <= 6)){ if (getequipweaponlv(.@part) == 0){ set .@matuse,3; } else { set .@matuse,2; } goto OnRefineOk; // 7 a 9 } else if((.@equip_refine >= 7) && (.@equip_refine <= 9)){ if (getequipweaponlv(.@part) == 0){ set .@matuse,5; } else { set .@matuse,4; } goto OnRefineOk; // 10 + (tirar os comentarios abaixo caso seja refine > 10 // } else if(.@equip_refine = 9){ // if (getequipweaponlv(.@part) == 0){ // set .@matuse,7; // } else { // set .@matuse,6; // } // goto OnRefineOk; } OnRefineOk: mes "^0000FF"+.name$+"^000000"; mes "Quantos {"+.material[.@matuse]+"} - "+.namemat$[.@matuse]+" Você quer usar?"; mes "Lembrando que cada material sua chance aumenta por "+.matchance+"%."; next; input .@amount; if (.@amount == 0) { mes "^0000FF"+.name$+"^000000"; mes "Nenhum material? Não consigo garantir o sucesso se você não me ajudar também!"; close; end; } if (countitem(.material[.@matuse]) < .@amount){ mes "^0000FF"+.name$+"^000000"; mes "Você não tem essa quantidade de materiais"; close; end; } if (.@amount > .maxmat){ mes "^0000FF"+.name$+"^000000"; mes "Você so pode ultilizar um maximo de "+.maxmat+" materiais!"; close; end; } mes "^0000FF"+.name$+"^000000"; mes "Entao vamos la!"; set .@percent, .@amount + .chance; mes "Você acumulou um percentual de "+.@percent+"%!"; next; delitem .material[.@matuse],.@amount; set .@failchance,rand(1,100); set .@schance, (.chance + (.@amount * .matchance)); if (.@failchance > .@schance){ specialeffect2 EF_SUI_EXPLOSION; if (.break == 1){ failedrefitem .@part; } if (.break == 2){ downrefitem .@part; } mes "^0000FF"+.name$+"^000000"; mes "Não foi desta vez..."; close; end; } successrefitem .@part; mes "^0000FF"+.name$+"^000000"; mes "Muito fácil!"; close; end; OnInit: set .name$,"Ferreiro Viking"; //Nome do NPC set .chance,10; //Chance de refinar 10 = 10% (sem material) set .matchance,1; //Quantos % sobem por material set .maxmat,90; //Maximo de materiais que se pode usar (90 x 1 = 90%) setarray .namemat$, //Lista dos itens utilizados para o refine "Oridecon", "Elunium", "Oridecon Enriquecido", "Elunium Enriquecido", "Oridecon Perfeito", "Elunium Perfeito" // "Bradium Perfeito" // "Carnium Perfeito" ; setarray .material[0], //Lista dos id 984, 985, 7620, 7619, 6240, 6241 // 6226 // 6225 ; set .break,1; //1 - Errar quebra / 2 - Errar desce refinamento / 3 - Nada acontece ao errar set .price,25000; //Preco para refinar end; }
×
×
  • Create New...