Jump to content

Mário.

Member
  • Content count

    77
  • 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

90 Neutral

3 Followers

About Mário.

  • Rank
    Member

Recent Profile Visitors

849 profile views
  1. 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]
  2. 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.
  3. 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); }
  4. 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
  5. Mário.

    [Quest][Pedido]Biologo

    https://metin2dev.org/board/index.php?/topic/11941-small-release-blocking-ip-address-to-killings/
  6. 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
  7. 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
  8. 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
  9. 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.
  10. 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
  11. Mário.

    System MultiLanguage

    O default encontra-se em inglês de momento. De momento utilizo a opção de reiniciar o cliente por motivos de estética até conseguir ter um código perfeitamente aceitável. - Utilizo somente alguns ficheiros para a parte /locale/country sendo que o resto fica no default que é o pt. A ideia do item_names e de meter nas opções é muito bem vinda mesmo, é algo que irei adaptar para o sistema. O locale_string foi totalmente complicado para mim mas deixo já um obrigado ao @Sil3nce por me ter salvado. Tens razão, a parte da quest não causa problemas nenhuns e torna-se super acessível para futuros usos.
  12. Mário.

    System MultiLanguage

    Estou a pensar em publicar mas não posso garantir.
  13. Mário.

    System MultiLanguage

    Mário* Na verdade não há nenhum problema que tenha a ver com traduções de quest, pela forma que fiz (ou mesmo fazendo do_file pela questlib) não teria qualquer problema no que toca a isso, a aba que te referes é do common.locale mas não é necessário mudar de forma alguma porque poderás meter todas dentro da pasta /portugal (ou o nome qualquer que tenhas) e meteres de forma a que o jogador vá buscar certo .txt, tal como fiz com o mob_names: Português: Inglês:
  14. Mário.

    System MultiLanguage

    O problema é que o VegaS é "internacionalmente" conhecido e interpretam-no como o único capaz de fazer estes tipos de sistemas. Vejo mesmo pessoas que chegam a dizer "nada é igual se fosse o vegas a fazer" o que respeito mas há que ter bom senso para saber que ele não é o único com competências. Longe de mim comparar-me com ele, até porque há sistemas que ele criou e que eu implementei, mas chega de dar dickriding nele. Continuando com o tópico, utilizei um pouco de tudo o que disseram: Criei uma aba na tabela account onde estará a linguagem definida (ideia dada pelo @trample): Por default, todas as contas virão em inglês, sendo que assim que entrarem poderão escolher a linguagem. As quests poderão ser facilmente modificadas pelo translate.lua (ideia dada pelo @AprendizM2): snprintf(translateFileName, sizeof(translateFileName), "%s/translate_%s.lua", LocaleService_GetBasePath().c_str(), Language_GetBasePath().c_str()); Invés de fazer do_file na questlib, preferi fazer pela source criando um diretório para as linguagens: Language_GetBasePath Com novas funções como pc.get_lang() que busca qual é a linguagem que temos inserido na base de dados, poderemos utilizar algo como isto: quest language begin state start begin when login begin syschat(system[pc.get_lang].testing) end end end system = {} system["pt"].testing = "Olá" system["en"].testing = "Hi" Esta forma de fazer é bastante simples e penso que deva de estar público em algum lugar. Estou a trabalhar para deteção de IP utilizando o GeoLite2++ (ideia dada pelo @Tierri Lopes) void CInputLogin::LoginByKey(LPDESC d, const char * data) { TPacketCGLogin2 * pinfo = (TPacketCGLogin2 *) data; char login[LOGIN_MAX_LEN + 1]; trim_and_lower(pinfo->login, login, sizeof(login)); GeoLite2PP:DB db("/opt/stuff/GeoLite2-City.mmdb") std:string ip = db.get_field(d->GetHostName(), GeoLite2PP::VCStr {"country", "names", "geral"}); sys_log(0, "Country: %s", ip); // Just a test to see the output const char * country = { "Portugal", "England", "Romenia", "Spanish", "Turkey", "Germany" }; ... } Ainda não está concluído, é apenas para terem uma ideia de como será feito a deteção (podem utilizar que não me importo). Estou a pensar em como devo de fazer a identificação para o locale_string.txt, penso que serei capaz de remodelar por completo a forma como ela é estruturada e ser chamada como um ficheiro de lua (exemplo): %s ±ºÁÖ Èĺ¸¿¡¼­ »èÁ¦ÇÏ¿´½À´Ï´Ù = "%s foi excluido como Candidato da Monarquia."
  15. (O título está inglês para chamar mais atenção) Ontem vi-me a falar sozinho na shoutbox e hoje cheguei a seguinte conclusão. Ultimamente tenho andado um pouco viciado em PHP & HTML e graças a isso, decidi meter na cabeça criar um sistema completo de multilinguagens em: Site; Client; Serverside. No site está otimizado e bem estruturado mas no client e no serverside não estão bem exatamente da forma como eu quero e daí pedir-vos sugestões. Esta é a forma como eu tenho feito: PHP: $details = ip_details($real_ip); $country = $details->country; $current_country = array( 'PT' => 'pt', 'BR' => 'pt', 'ES' => 'es', 'DE' => 'ge', 'GB' => 'en', 'US' => 'en', 'RO' => 'ro', 'TR' => 'tr', // Ficará para depois ); Python: # Add after: if app.ENABLE_LSM2_MULTI_LANGUAGE: self.text = ConnectingDialog() self.text.SetText(localeInfo.CLIENT_RESTART) self.text.Close() # This was made in order to make some changes/upgrades in the system. You can simple edit if you want. self.flag = { 'LANG' : ( "pt", "en", "ro", "es", "de", "tr", ) } # This means: # pt: 0 # en: 1 # ... self.exe = "metin2client.exe" # Change the name for your metin2client.exe # If you use .bin, just change it to the directory of the patcher (ex: patcher.exe) # Search for: def __ExitGame(self): app.Exit() # Add after: if app.ENABLE_LSM2_MULTI_LANGUAGE: # I made this way because of the timer (It's kinda of stupid but I will change it on the next update) # Probably this is not the best code, but it works - not really an expert in python Tenho feito de forma a ser por tutorial pois estou a pensar em lançar o mesmo quando acabar. Um print de como está no login: O pedido agora é: Como devo de fazer o sistema? Por identificação de IP ou por algo como mudança de linguagem presente por quest (sou bastante fã de LUA rs)? Pedi já opiniões externas e debateram-se dizendo que se for IP acabará por a desvantagem de (por exemplo) ser impossível um português morar no estrangeiro e querer jogar na língua materna e é por essa razão que estou mais inclinado para fazer por quest (a minha ideia seria criar uma função como ch->GetLang que pudesse indicar a que linguagem ele tem de forma a poder ser mudado o locale_string/translate.lua/oxquiz.lua/. Obrigado desde já pela atenção
×

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.