Jump to content

Mário.

Member
  • Content count

    82
  • Joined

  • Last visited

  • Days Won

    17
  • Feedback

    N/A

Mário. last won the day on April 10

Mário. had the most liked content!

Community Reputation

92 Neutral

3 Followers

About Mário.

  • Rank
    Member

Recent Profile Visitors

913 profile views
  1. Mário.

    Erro ao compilar source

    error: 'struct TItemPriceInfo' has no member named 'dwCheque' error: 'const struct SItemPriceInfo' has no member named 'dwCheque' common/tables.h Procura por: typedef struct SItemPriceInfo { DWORD dwVnum; ///< ¾ÆÀÌÅÛ vnum DWORD dwPrice; ///< °¡°Ý } TItemPriceInfo; Substitui por: typedef struct SItemPriceInfo { DWORD dwVnum; ///< ¾ÆÀÌÅÛ vnum DWORD dwPrice; ///< °¡°Ý DWORD dwCheque; /// ENABLE_CHEQUE_SYSTEM } TItemPriceInfo; 3688: error: duplicate case value 3570: error: previously used here char.cpp Na linha 3688, existe um case que já foi definido acima na linha 3570: // exemplo: case TLTHINGS: // linha 3570 ação; break; case TLTHINGS: // linha 3688 ação; break; Remove o último case e estará resolvido.
  2. Mário.

    [AJUDA] Sistema Gaya

    1º Tens que fornecer o sistema para estarmos a par de qual o erro, não somos bruxos para saber qual é a linha que está errada. 2º Se isso acontece ao teleportar, significa que sempre que a personagem altera/teleporta, os valores do gaya resetam, por isso vê o que se passa no input_main.cpp, se existe algum ch->SetGaya ou algo do gênero (o meu conhecimento desse sistema é 0, tens que fornecer o sistema no total para conseguirmos ajudar).
  3. Isso é algo bastante relativo, mas antes de começar com algo, deixa-me explicar-te a diferença entre um backdoor e um exploit no cenário do Metin2. Um backdoor dá-se quando um pedaço de código é deixado propositadamente na source para o criador/malfeitor tomar proveito do mesmo Um exploit é quando um pedaço de código está mal feito/otimizado, permitindo que qualquer pessoa possa tomar proveito do mesmo Agora, respondendo a tua dúvida, em termos de backdoor é muito comum estar presente nos cmd_general.cpp | cmd_gm.cpp | cmd.cpp, com comandos como a que tu disseste "/twix /byebye /full_item, etc." MAS não podemos excluir a complexidade da mesma. Ele poderá ter posto, por exemplo, ao iniciar com o nome "ABC", enviar uma mensagem com os dados do servidor, por isso nada melhor que perderes um dia e analisares todos os ficheiros e vê se vês algo de suspeito. OBS: Confirma no cmd.cpp os poderes de certos comandos, poderá existir algum comando como "/full_set /shutdown /n" com GM_PLAYER. O de exploit, toma especialmente atento a funções/comandos que utilizam queries diretamente. Poderão conseguir utilizar comandos como "DROP" para prejudicar o teu servidor.
  4. Mário.

    ERRO NO CLIENTE

    Retire a parte onde diz if (ModoBatalha) bPKMode = PK_MODE_BATALHA; else e diga-me se resolveu. Isso é um novo modo que não está presente no cliente.
  5. Mário.

    ERRO NO CLIENTE

    Muito provavelmente o erro está no source do game. Se nesse mapa não consegues mudar o modo pvp, é porque algo não o permite. Mostra-nos a parte completa disto, que está no char_battle.cpp: void CHARACTER::SetPKMode(BYTE bPKMode) { if (bPKMode >= PK_MODE_MAX_NUM) return; if (m_bPKMode == bPKMode) return; if (bPKMode == PK_MODE_GUILD && !GetGuild()) bPKMode = PK_MODE_FREE; m_bPKMode = bPKMode; UpdatePacket(); sys_log(0, "PK_MODE: %s %d", GetName(), m_bPKMode); } Vê se o teu está desta forma. Se não estiver, utiliza, compila e diz-nos o resultado.
  6. Mário.

    Erro tables crachad Mysql

    Utilize uma das três: mob_proto.sql <- Estrutura oficial datada a 03/02/2018 | Não contêm nenhuma informação [5 kb] mob_proto_.sql <- Estrutura oficial datada a 03/02/2018 | Contém todo o mob_proto oficial [751 kb] mob_proto.txt <- Estrutura oficial em txt datada a 03/02/2018 [352 kb]
  7. Mário.

    File Index / Patchs .epk

    Procura por: PACK * Adiciona depois: metin2_patch_6th_armor pack/ metin2_patch_monster_card pack/ Em primeiro lugar é o nome do ficheiro seguidamente pelo diretório da pasta.
  8. Mário.

    System Team (Source)

    messenger_manager.cpp: void MessengerManager::Login(MessengerManager::keyA account) { if (m_set_loginAccount.find(account) != m_set_loginAccount.end()) return; DBManager::instance().FuncQuery(std::bind1st(std::mem_fun(&MessengerManager::LoadList), this), "SELECT account, companion FROM messenger_list%s WHERE account='%s'", get_table_postfix(), __account); #ifdef ENABLE_MESSENGER_TEAM DBManager::instance().FuncQuery(std::bind1st(std::mem_fun(&MessengerManager::LoadTeamList), this), "SELECT '%s' as account, mName as companion FROM common.gmlist", account.c_str()); #endif m_set_loginAccount.insert(account); } #ifdef ENABLE_MESSENGER_TEAM void MessengerManager::LoadTeamList(SQLMsg * msg) { if (NULL == msg or NULL == msg->Get() or msg->Get()->uiNumRows == 0) return; std::string account; for (uint i = 0; i < msg->Get()->uiNumRows; ++i) { MYSQL_ROW row = mysql_fetch_row(msg->Get()->pSQLResult); if (row[0] && row[1]) { if (account.length() == 0) account = row[0]; m_TeamRelation[row[0]].insert(row[1]); m_InverseTeamRelation[row[1]].insert(row[0]); } } SendTeamList(account); std::set<MessengerManager::keyT>::iterator it; for (it = m_InverseTeamRelation[account].begin(); it != m_InverseTeamRelation[account].end(); ++it) SendTeamLogin(*it, account); } void MessengerManager::SendTeamList(MessengerManager::keyA account) { LPCHARACTER ch = CHARACTER_MANAGER::instance().FindPC(account.c_str()); if (!ch) return; LPDESC d = ch->GetDesc(); if (!d) return; TPacketGCMessenger pack; pack.header = HEADER_GC_MESSENGER; pack.subheader = MESSENGER_SUBHEADER_GC_TEAM_LIST; pack.size = sizeof(TPacketGCMessenger); TPacketGCMessengerTeamListOffline pack_offline; TPacketGCMessengerTeamListOnline pack_online; TEMP_BUFFER buf(128 * 1024); itertype(m_TeamRelation[account]) it = m_TeamRelation[account].begin(), eit = m_TeamRelation[account].end(); while (it != eit) { if (m_set_loginAccount.find(*it) != m_set_loginAccount.end()) { pack_online.connected = 1; pack_online.length = it->size(); buf.write(&pack_online, sizeof(TPacketGCMessengerTeamListOnline)); buf.write(it->c_str(), it->size()); } else { pack_offline.connected = 0; pack_offline.length = it->size(); buf.write(&pack_offline, sizeof(TPacketGCMessengerTeamListOffline)); buf.write(it->c_str(), it->size()); } ++it; } pack.size += buf.size(); d->BufferedPacket(&pack, sizeof(TPacketGCMessenger)); d->Packet(buf.read_peek(), buf.size()); } void MessengerManager::SendTeamLogin(MessengerManager::keyA account, MessengerManager::keyA companion) { LPCHARACTER ch = CHARACTER_MANAGER::instance().FindPC(account.c_str()); LPDESC d = ch ? ch->GetDesc() : NULL; if (!d) return; if (!d->GetCharacter()) return; BYTE bLen = companion.size(); TPacketGCMessenger pack; pack.header = HEADER_GC_MESSENGER; pack.subheader = MESSENGER_SUBHEADER_GC_TEAM_LOGIN; pack.size = sizeof(TPacketGCMessenger) + sizeof(BYTE) + bLen; d->BufferedPacket(&pack, sizeof(TPacketGCMessenger)); d->BufferedPacket(&bLen, sizeof(BYTE)); d->Packet(companion.c_str(), companion.size()); } void MessengerManager::SendTeamLogout(MessengerManager::keyA account, MessengerManager::keyA companion) { if (!companion.size()) return; LPCHARACTER ch = CHARACTER_MANAGER::instance().FindPC(account.c_str()); LPDESC d = ch ? ch->GetDesc() : NULL; if (!d) return; BYTE bLen = companion.size(); TPacketGCMessenger pack; pack.header = HEADER_GC_MESSENGER; pack.subheader = MESSENGER_SUBHEADER_GC_TEAM_LOGOUT; pack.size = sizeof(TPacketGCMessenger) + sizeof(BYTE) + bLen; d->BufferedPacket(&pack, sizeof(TPacketGCMessenger)); d->BufferedPacket(&bLen, sizeof(BYTE)); d->Packet(companion.c_str(), companion.size()); } #endif void MessengerManager::Logout(MessengerManager::keyA account) { if (m_set_loginAccount.find(account) == m_set_loginAccount.end()) return; m_set_loginAccount.erase(account); std::set<MessengerManager::keyT>::iterator it; for (it = m_InverseRelation[account].begin(); it != m_InverseRelation[account].end(); ++it) { SendLogout(*it, account); } std::map<keyT, std::set<keyT> >::iterator it2 = m_Relation.begin(); while (it2 != m_Relation.end()) { it2->second.erase(account); ++it2; } #ifdef ENABLE_MESSENGER_TEAM std::set<MessengerManager::keyT>::iterator it5; for (it5 = m_InverseTeamRelation[account].begin(); it5 != m_InverseTeamRelation[account].end(); ++it5) { SendTeamLogout(*it5, account); } std::map<keyT, std::set<keyT> >::iterator it6 = m_TeamRelation.begin(); while (it6 != m_TeamRelation.end()) { it6->second.erase(account); ++it6; } m_TeamRelation.erase(account); #endif m_Relation.erase(account); //m_map_stMobile.erase(account); }
  9. Mário.

    Resolver Problemas Em Missões Biologo Dos Jogadores

    Quem puder testar que dê feedback pls: questlua_global.cpp: int _set_quest_state_other (lua_State* L) { if (!lua_isstring(L, 1) || !lua_isstring(L, 2) || !lua_isstring(L, 3)) return 0; CQuestManager& q = CQuestManager::instance(); PC* pPC = q.GetCurrentNPC(); QuestState * pqs = q.GetCurrentState(); const string stPlayerName(lua_tostring(L, 1)); if (L!=pqs->co) { luaL_error(L, "running thread != current thread???"); sys_log(0,"running thread != current thread???"); return -1; } if (pPC) { const string stQuestName(lua_tostring(L, 2)); const string stStateName(lua_tostring(L, 3)); if (pPC->GetPlayerName(stPlayerName)) { if ( test_server ) sys_log(0,"set_state %s %s ", stQuestName.c_str(), stStateName.c_str() ); if (pPC->GetCurrentQuestName() == stQuestName) { pqs->st = q.GetQuestStateIndex(pPC->GetCurrentQuestName(), lua_tostring(L, -1)); pPC->SetCurrentQuestStateName(lua_tostring(L,-1)); } else { pPC->SetQuestState(stQuestName, stStateName); } } } return 0; } { "set_quest_state_other", _set_quest_state_other }, questpc.h: // Procurar por: const string & GetCurrentQuestName() const; // Adicionar abaixo: const string & GetPlayerName() const; questluapc.cpp: const string & PC::GetPlayerName() const char * name { LPCHARACTER npc = CHARACTER_MANAGER::instance().FindPC(name); return npc->GetName(); } questmanager.h: // Procurar por: LPCHARACTER m_pCurrentNPCCharacter; // Substituir por: PC* m_pCurrentNPCCharacter; // Procurar por: PC * GetCurrentPC() { return m_pCurrentPC; } // Adicionar abaixo: PC * GetCurrentNPC() { return m_pCurrentNPCCharacter; } A utilização dele é como o @Tierri Lopes disse: set_quest_state_other("Tierri", "quest_test", "run") -- Nome do jogador | quest | state
  10. Mário.

    [Quest][Pedido]Biologo

    https://metin2dev.org/board/index.php?/topic/11941-small-release-blocking-ip-address-to-killings/
  11. Mário.

    Admin Whisper

    Obrigado, fiz a quest à pressa e nem reparei nisso E sim, tens razão, será melhor utilizar um ficheiro externo: when login begin a = io.open(get_locale_base_path().."/admin_whisper.txt", "r") this = a:read() cmdchat(string.format("admin_whisper %s %s",this,this)) end Desta forma ficaria o ficheiro ficaria: mário paci Resultado: O @Marco e o Daryl (GalaxyMT2) deram a ideia da mensagem ser enviada de X a X tempos de acordo com a hora que eles queriam, então para isso é só utilizar esta quest: quest admin_whisper begin state start begin when login begin -- Desta forma, todas as segundas e terças às 15:30, será enviado um PM a cada jogador online durante esse tempo local data = {"Monday 15:30","Tuesday 15:30"} for index, datetime in ipairs(data) do if datetime == os.date("%A %H:%M") then if game.get_event_flag("admin_whisper") == 1 then cmdchat(string.format("admin_whisper %s %s",whisper.admin,whisper.text)) end end end end end end
  12. Mário.

    [Quest][Pedido]Biologo

    Em baixo estão cerca 9 quests totalmente otimizados para droparem itens do biólogo em jogador. Alguns extras: Tem verificação vs IP (Jogadores com o mesmo IP não irão dropar itens); Com um pet, terão mais possibilidade de droparem ou não o item; As quests estão interligadas uma com a outra, ou seja, assim que acabam uma missão a outra é logo ativada (se tiverem o nível requerido); Possibilidade de saberem vários detalhes de cada morte (logs): O jogador, o adversário, em que canal, em qual missão e a hora; Se o jogador matar a mesma pessoa 5x, a mesma é posta a parte para ser analisado pela equipa. Estes dois últimos têm como o nome biólogo e biólogo_farm Se algum jogador aparecer no biólogo_farm é porque o mesmo matou mais que 5x a mesma pessoa. Com o biólogo, analisas se é farm ou não (pelas horas/minutos/segundos) e depois apagas o nome da pessoa nessa tabela, foi desta forma que eu fiz no pvp e correu-me bastante bem. Está tudo identificado de forma a conseguires entender o que cada coisa significa: sistema.biologo.lv75_inicial = 75 -- Nível inicial para começarem a missão sistema.biologo.lv75_item = 30006 -- item que será dropado assim que matarem os jogadores [a base de probabilidade, linha 67] sistema.biologo.lv75_quantidade = 1 -- quantidade do item a ser dado. sistema.biologo.lv75_minquantidade = 1 -- mínimo de quantidade para poderem entregar o item [recomendado 1, visto que poderão entregar sempre, desde que o tenham] sistema.biologo.lv75_maxquantidade = 15 -- quantidade máxima que precisam de ter para aparecer o aviso de onde terão que voltar para o biólogo sistema.biologo.lv75_pet = 34001 -- ID do pet que dará mais % no biólogo sistema.biologo.lv75_percentagem = 20 -- percentagem sem pet sistema.biologo.lv75_percentagempet = 50 -- percentagem se possuirem determinado pet Alguns avisos: É necessário ter pc.get_ip e npc.get_ip implementados; É necessário adicionar dofile(get_locale_base_path().."/quest/sistema.lua") no questlib.lua; É necessário colocar o sistema.lua na pasta /quest. Recomendo apenas a mexeres nas quests principais somente para alterar os bónus sistema biologo.rar
  13. Mário.

    Admin Whisper

    Antes de começar com o tópico, se esperam algo complexo deste sistema, então poderão voltar para trás porque isto foi em apenas 1 hora de trabalho. Têm todo o direito de melhorar isto à vontade. Bem, eu ando a fazer alguns testes no que toca a performance entre quest-client e game-client e sendo sincero, quase ou pouco noto a diferença (já deu para entender que sou fanboy de lua certo?), apenas há 1 ~ 3 comandos extras a serem feitos. O que é este sistema? Isto dá-se como o nome de Admin Whisper (Mensagens de Equipa em português) e tem como objetivo enviar uma mensagem a todos os jogadores assim que entram pela primeira vez no jogo. Para que serve? Tal como disse acima, todos os jogadores (independentemente do canal - ou seja, poderão estar no CH1 como no CH2 -) irão receber sem qualquer tipo de problema ou latência. (Mensagem a ser enviada - No print não tem como ser visível mas ela pisca) (Conteúdo da mensagem) Requisitos: Python LUA Client Procurem (game.py) por: "PlayMusic" : self.__PlayMusic, Em baixo, adicionem: "admin_whisper" : self.AdminWhisper, Procurem por: def __PlayMusic(self, flag, filename): flag = int(flag) if flag: snd.FadeOutAllMusic() musicInfo.SaveLastPlayFieldMusic() snd.FadeInMusic("BGM/" + filename) else: snd.FadeOutAllMusic() musicInfo.LoadLastPlayFieldMusic() snd.FadeInMusic("BGM/" + musicInfo.fieldMusic) Por baixo adicionem: def AdminWhisper(self, admin, text): # Nome a ser chamado txt = str(text) # A mensagem em si show = txt.replace("_", " ") # Os _ são substituidos por espaço name = "|cFFFF8C00|H|h[%s]|h|r" % (admin) # Cor semelhante a de um Game Master + o nome proveniente do servidor chat.AppendWhisper(chat.WHISPER_TYPE_GM, name, show) # É enviado a mensagem com carácter GM self.interface.RecvWhisper(name) # É anúnciado da mesma forma que uma mensagem normal Adicionem isto no questlib.lua: dofile(get_locale_base_path().."/admin_whisper.lua") SERVER Criem no diretório do locale um ficheiro chamado admin_whisper.lua com isto lá dentro: --[[ De forma a que as mensagens tenham espaço uma da outra, é necessário utilizarem o uso da _ de forma a que o client consiga substituir. O motivo deve-se ao facto do comando cmdchat - ou CHAT_TYPE_COMMAND - ignorar tudo o que venha depois de um espaço (corrigem-me se estiver mal), por isso decidi que isto poderia ser a melhor forma disponível para que os espaços sejam visto visualmente. OBS: Repito, se queres algo complexo, podes usar isto como base ou simplesmente não usar, não obrigo ninguém a utiliza-lo. PS: Também poderão mandar mensagem a cada um dos jogadores de acordo com a sua linguagem (se tiverem multilinguagens instalado). ]] whisper = {} -- Abre a clásula para a palavra whisper whisper.admin = "MÁRIO" -- Nome do sistema a aparecer -- Mensagem a ser exibida | Se quiserem enviar mais que uma, poderão faze-lo perfeitamente dando alguns retoques no código whisper.text = "Olá_a_todos,_só_queria_dizer_que_este_´tutorial´_foi_criado_pelo_Mário_por_isso_se_quiserem_meter_os_créditos_quando_forem_meter_em_um_outro_sítio,_metam_os_meus_e_não_os_vossos_^^ " Utilizem a seguinte quest como um teste: quest admin_whisper begin state start begin when login begin if game.get_event_flag("admin_whisper) == 0 then return else cmdchat(string.format("admin_whisper %s %s",whisper.admin,whisper.text)) end end end end /e admin_whisper 1 - O sistema estará ativo e todos irão receber as mensagens /e admin_whisper 0 - O sistema estará desativo e ninguém irá receber as mensagens
  14. Mário.

    [QNA] Proteção anti-hack

    Apoio totalmente a nova filosofia e já tive oportunidade de ver e analisar a mesma em ação. Considero que é mais prático e eficiente tornar o cliente disponível para todos e mudar a estrutura interna de forma a que ir no sentido contrário de módulos pré-definidos pela source (headers, modules, imports, etc.). Um exemplo disso é a forma como o lalaker funciona. Se analisares como ela se comporta e que tipos de headers ela usa (graças a um packet reader) consegue-se descobrir que utiliza o header que se encontra disponível para o ataque (SPACE) = 3. Ora mudando o número, com a opção ProDamage ligado, a personagem acabaria por levar dc pois o objetivo do mesmo é utilização do default. O m2bob funciona de outra forma, excluindo a utilização de headers. De certa forma, concordo e apoio.
  15. Mário.

    Bonus Pvm/Pvp e Faixas

    1. Procura por (game.py): onPressKeyDict[app.DIK_X] = lambda : 2. Comenta/Apaga: #onPressKeyDict[app.DIK_X] = lambda : self.__OpenBonus() <- Isto é um exemplo, não é igual ao que tens 3. Procura por: (uitooltip.py): if isCostumeSash: 4. Substitui por: if itemVnum >= 85001 and itemVnum <= 85024: # São os IDs das faixas, se tens de outra forma, substitui
×

Important Information

By using this site, you agree to our Terms of Use.

Our website is made possible by displaying online advertisements to our visitors.
Please consider supporting us by disabling your ad blocker.
You will be able to see content when you disable your adblocker and enable javascript.