Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation on 12/26/18 in all areas

  1. You can do something like that. root/localeInfo.py Add at end of line: import requests def GetLanguage(locale_region_default = 'en'): language = locale_region_default try: request = requests.get('[Hidden Content]', params=None) if request.status_code is 200: for locale_region, country_code_tuple in LOCALE_REGION_DICT.iteritems(): if request.json().get('countryCode').lower() in country_code_tuple: language = locale_region return language except requests.exceptions.ConnectionError: return language # Initialized just one time LANGUAGE = GetLanguage() How to use it: import localeInfo print localeInfo.LANGUAGE
    2 points
  2. M2 Download Center Download Here ( Internal ) Hi m2dev, I release my modifications of game core. 0x01.) Here are "some" new questfunctions to you ^^ If either of them is already public I'm sorry but these works perfectly. A short list of them: * Item module: - get_flag | Return: Integer | Args: None - get_wearflag | Return: Integer | Args: None - get_antiflag | Return: Integer | Args: None - has_antiflag | Return: Boolean | Args: int Antiflag - get_refine_set | Return: Integer | Args: None - get_limit | Return: Table1 | Args: byte LimitIndex[0..1] - get_apply | Return: Table1 | Args: byte ApplyIndex[0..2] - get_applies | Return: Table2 | Args: None - get_refine_materials | Return: Table3 | Args: None - get_addon_type | Return: Integer | Args: None - dec | Return: Nil | Args: None or byte Count - inc | Return: Nil | Args: None or byte Count - add_attribute | Return: Boolean | Args: None - get_attribute | Return: Table1 | Args: byte AttrIndex[0..4] - set_attribute | Return: Boolean | Args: byte AttrIndex[0..4], byte AttrType[1..94], short AttrValue[-32768..32767] - change_attribute | Return: Boolean | Args: None - add_rare_attribute | Return: Boolean | Args: None - get_rare_attribute | Return: Table1 | Args: byte AttrIndex[0..1] - set_rare_attribute | Return: Boolean | Args: byte AttrIndex[0..1], byte AttrType[1..94], short AttrValue[-32768..32767] - change_rare_attribute | Return: Boolean | Args: None - equip | Return: Boolean | Args: byte EquipCell[0..32] - set_count | Return: Nil | Args: byte/short Count(short with increased item stack number) Returning item table-structures: Table1 = { -- Type, Value 1, 2000 } Table2 = { -- [idx] = {Type, Value} -- Triton sword+9: [0] = { 7, 30 }, [1] = { 22, 12 }, [2] = { 17, 12 } } Table3 = { -- Poison sword+8(refineSet:27): material_count = 2, materials = { -- { Vnum, Count } { 30091, 2 }, { 27994, 1 } }, cost = 150000, prob = 10, } * NPC module: - get_level | Return: Integer | Args: None - get_name | Return: String | Args: None - get_type | Return: Byte | Args: None - get_rank | Return: Byte | Args: None - is_metin | Return: Boolean | Args: None - is_boss | Return: Boolean | Args: None - show_effect_on_target | Return: Boolean | Args: string EffectRealPath - get_ip | Return: String | Args: None - get_client_version | Return: String | Args: None - get_job | Return: Byte | Args: None - get_pid | Return: Integer | Args: None - get_exp | Return: Long | Args: None * PC module: - get_mount_vnum | Return: Integer | Args: None - get_point | Return: Integer | Args: byte PointNumber - get_real_point | Return: Integer | Args: byte PointNumber - show_effect | Return: Boolean | Args: string EffectRealPath - disconnect_with_delay | Return: Nil | Args: int Delay - get_max_level | Return: Integer | Args: None - get_ip | Return: String | Args: None - get_client_version | Return: String | Args: None - kill | Return: Nil | Args: None * Game module: - drop_item_and_select | Return: Nil | Args: int Vnum, byte/short Count=1, bool HasOwnership=false, short OwnershipTime=180 Example call: game.drop_item_and_select(19, 1, true, 30); item.set_attribute(0, apply.CRITICAL_PCT, 10) * Pet module: - is_mine | Return: Boolean | Args: None * Global: - purge_vid | Return: Nil | Args: int Vid Here are the codes: questlua_item.cpp questlua_npc.cpp questlua_pc.cpp questlua_game.cpp questlua_pet.cpp questlua_global.cpp 0x02.) Two GM commands: - "/kill_all" -> Kill all players inside your view-range/horizon - "/drop_item" -> Drop an item from arg1, or drop all items from range(arg1, arg2) Commands: Clientside version of kill_all: 0x03.) refine_proto reloading without server restart. Extend your "/reload Proto" command with the refine_proto reloading with this code parts: - Open your db/src/ClientManager.cpp file and replace your "void CClientManager::QUERY_RELOAD_PROTO()" function to this: void CClientManager::QUERY_RELOAD_PROTO() { if (!InitializeTables()) { sys_err("QUERY_RELOAD_PROTO: cannot load tables"); return; } for (TPeerList::iterator i = m_peerList.begin(); i != m_peerList.end(); ++i) { CPeer * tmp = *i; if (!tmp->GetChannel()) continue; tmp->EncodeHeader(HEADER_DG_RELOAD_PROTO, 0, sizeof(WORD) + sizeof(TSkillTable) * m_vec_skillTable.size() + sizeof(WORD) + sizeof(TBanwordTable) * m_vec_banwordTable.size() + sizeof(WORD) + sizeof(TItemTable) * m_vec_itemTable.size() + sizeof(WORD) + sizeof(TMobTable) * m_vec_mobTable.size() + sizeof(WORD) + sizeof(TRefineTable) * m_iRefineTableSize); tmp->EncodeWORD(m_vec_skillTable.size()); tmp->Encode(&m_vec_skillTable[0], sizeof(TSkillTable) * m_vec_skillTable.size()); tmp->EncodeWORD(m_vec_banwordTable.size()); tmp->Encode(&m_vec_banwordTable[0], sizeof(TBanwordTable) * m_vec_banwordTable.size()); tmp->EncodeWORD(m_vec_itemTable.size()); tmp->Encode(&m_vec_itemTable[0], sizeof(TItemTable) * m_vec_itemTable.size()); tmp->EncodeWORD(m_vec_mobTable.size()); tmp->Encode(&m_vec_mobTable[0], sizeof(TMobTable) * m_vec_mobTable.size()); tmp->EncodeWORD(m_iRefineTableSize); tmp->Encode(m_pRefineTable, sizeof(TRefineTable) * m_iRefineTableSize); } } - Then open game/src/refine.cpp and replace this function: "bool CRefineManager::Initialize(TRefineTable * table, int size)" to this: bool CRefineManager::Initialize(TRefineTable * table, int size) { if (!m_map_RefineRecipe.empty()) m_map_RefineRecipe.clear(); for (int i = 0; i < size; ++i, ++table) { sys_log(0, "REFINE %d prob %d cost %d", table->id, table->prob, table->cost); m_map_RefineRecipe.insert(std::make_pair(table->id, *table)); } sys_log(0, "REFINE: COUNT %d", m_map_RefineRecipe.size()); return true; } - If you are done with these, open game/src/input_db.cpp and extend this event "void CInputDB::ReloadProto(const char * c_pData)" with this: /* * REFINE */ wSize = decode_2bytes(c_pData); c_pData += 2; sys_log(0, "RELOAD: REFINE: %d", wSize); if (wSize) { CRefineManager::instance().Initialize((TRefineTable *) c_pData, wSize); c_pData += wSize * sizeof(TRefineTable); } - Done. 0x04.) kill quest trigger fix (when kill / when race.kill) With this change you can use every kill methods with mobs and players and runs by once per kills. Examples: when 101.kill begin -> Works when you are killing Wild dogs. when kill begin -> Works with mobs and players too. when kill with npc.is_pc() begin -> Works with players only. when kill with npc.is_pc() == false begin -> Works with monsters only. when kill with npc.get_race() == 102 begin -> Works when you hunt Wolf. I tested with these codes: when kill begin if npc.is_pc() then chat("kill pc") end if npc.get_race() > 100 then chat("kill by race: "..tostring(npc.race)) end end when kill with npc.is_pc() begin chat("kill with npc.is_pc") end when kill with npc.get_race() == 102 begin chat("kill with npc.get_race 102") end when 101.kill begin chat("101.kill") end Follow these steps to fix it: - Open game/src/questmanager.h and search for this: "void Kill(unsigned int pc, unsigned int npc);" replace to: "void Kill(unsigned int pc, unsigned int npc, unsigned int pc2 = 0);" - Save&Close, open game/src/questmanager.cpp and search this function: "void CQuestManager::Kill(unsigned int pc, unsigned int npc)" - and replace to this: void CQuestManager::Kill(unsigned int pc, unsigned int npc, unsigned int pc2) { //m_CurrentNPCRace = npc; PC * pPC; sys_log(0, "CQuestManager::Kill QUEST_KILL_EVENT (pc=%d, npc=%d, pc2=%d)", pc, npc, pc2); if ((pPC = GetPC(pc))) { if (!CheckQuestLoaded(pPC)) return; /* [hyo] ¸÷ kill˝Ă Áßşą Ä«żîĆĂ ŔĚ˝´ °ü·ĂÇŃ ĽöÁ¤»çÇ× quest scriptżˇ when 171.kill begin ... µîŔÇ ÄÚµĺ·Î ŔÎÇĎż© ˝şĹ©¸łĆ®°ˇ Ăł¸®µÇľú´ő¶óµµ ąŮ·Î returnÇĎÁö ľĘ°í ´Ů¸Ą °Ë»çµµ ĽöÇŕÇϵµ·Ď şŻ°ćÇÔ. (2011/07/21) */ // call script if (npc > 0 && pc2 == 0) m_mapNPC[npc].OnKill(*pPC); LPCHARACTER ch = GetCurrentCharacterPtr(); LPPARTY pParty = ch->GetParty(); LPCHARACTER leader = pParty ? pParty->GetLeaderCharacter() : ch; if (leader) { m_pCurrentPartyMember = ch; if (m_mapNPC[npc].OnPartyKill(*GetPC(leader->GetPlayerID()))) return; pPC = GetPC(pc); } LPCHARACTER victim = CHARACTER_MANAGER::instance().FindByPID(pc2); if (victim && victim->IsPC() && m_mapNPC[QUEST_NO_NPC].OnKill(*pPC)) return; else if (m_mapNPC[QUEST_NO_NPC].OnKill(*pPC)) return; if (leader) { m_pCurrentPartyMember = ch; m_mapNPC[QUEST_NO_NPC].OnPartyKill(*GetPC(leader->GetPlayerID())); } } else sys_err("QUEST: no such pc id : %d", pc); } - Save&Close, open game/src/char_battle.cpp and search this call: "quest::CQuestManager::instance().Kill(pkKiller->GetPlayerID(), quest::QUEST_NO_NPC)" - and replace to this: "quest::CQuestManager::instance().Kill(pkKiller->GetPlayerID(), quest::QUEST_NO_NPC, GetPlayerID());" - Done. 0x05.) ImmuneBug fix. I know there are some fixes but this is a working solution.. Everything inside two functions into item.cpp file by names: "CItem::EquipTo" and "CItem::Unequip". Every two functions are containing this sh*!&t: DWORD dwImmuneFlag = 0; for (int i = 0; i < WEAR_MAX_NUM; ++i) if (m_pOwner->GetWear(i)) SET_BIT(dwImmuneFlag, m_pOwner->GetWear(i)->m_pProto->dwImmuneFlag); m_pOwner->SetImmuneFlag(dwImmuneFlag); Hm, you have to replace those to this: DWORD dwImmuneFlag = 0; LPITEM item = NULL; for (int i = 0; i < WEAR_MAX_NUM; ++i) { if (item=m_pOwner->GetWear(i)) { if (item->GetImmuneFlag() != 0) SET_BIT(dwImmuneFlag, item->GetImmuneFlag()); if (item->GetAttributeCount() > 0) { if (item->HasAttr(APPLY_IMMUNE_STUN)) SET_BIT(dwImmuneFlag, IMMUNE_STUN); if (item->HasAttr(APPLY_IMMUNE_SLOW)) SET_BIT(dwImmuneFlag, IMMUNE_SLOW); if (item->HasAttr(APPLY_IMMUNE_FALL)) SET_BIT(dwImmuneFlag, IMMUNE_FALL); } } } m_pOwner->SetImmuneFlag(dwImmuneFlag); - Done. 0x06.) Finished uiQuest.py selection by keyboard-usage with "Next" and "Prev" buttons. Test-example: when 9010.chat."TEST selection pages" begin local sTab = { "01","02","03","04","05","06","07","08","09","10", "11","12","13","14","15","16","17","18","19","20", "Exit"--to make exit by Escape key } local s=select_table(sTab) if s==table.getn(sTab) then return end chat("You'r choice: sTab["..tostring(s).."] -> "..sTab[s]) end Here you can download the full uiquest.py file from my client: Download 0x07.) Little SQL-Script: SELECT log.log.time AS "When", player.player.`name` AS Who, log.log.how AS WhatDid, log.log.what AS ItemID, log.log.vnum AS ItemVnum, player.item_proto.locale_name AS ItemName, player.item.count AS Count, player.item.Socket0, player.item.Socket1, player.item.Socket2, player.item.AttrType0, player.item.AttrValue0, player.item.AttrType1, player.item.AttrValue1, player.item.AttrType2, player.item.AttrValue2, player.item.AttrType3, player.item.AttrValue3, player.item.AttrType4, player.item.AttrValue4, player.item.AttrType5, player.item.AttrValue5, player.item.AttrType6, player.item.AttrValue6 FROM log.log INNER JOIN player.player ON log.log.who = player.player.id INNER JOIN player.item ON log.log.what = player.item.id INNER JOIN player.item_proto ON log.log.vnum = player.item_proto.vnum WHERE log.how in ("EXCHANGE_GIVE", "EXCHANGE_TAKE", "DROP", "SAFEBOX PUT", "SAFEBOX GET", "DEAD_DROP") AND player.`name` = "Xeriesey"; * You have to give a name where you can see Xeriesey ^-^ Result of query: I hope you like it. If you have any questions or find an error/mistake, just post a message into this thread and I will try to make answer when I'll be online. ps.: Sorry for my bad English. "(" + "c" + ")" == © -> F**k Changelog: - 2014.09.22. 16:29 / 04:29 PM ~ Added forgotten include to questlua_npc.cpp. - 2014.09.22. 16:48 / 04:48 PM ~ Added more forgotten things :S - 2014.09.27. 13:08 / 01:08 PM ~ SQL syntax fix With Regards, P3NG3R
    1 point
  3. In item_manager_read_tables.cpp search for: bool ITEM_MANAGER::ReadSpecialDropItemFile(const char * c_pszFileName) Inside find this, it may not be same as yours: else { CSpecialItemGroup * pkGroup = M2_NEW CSpecialItemGroup(iVnum, type); for (int k = 1; k < 256; ++k) { char buf[4]; snprintf(buf, sizeof(buf), "%d", k); if (loader.GetTokenVector(buf, &pTok)) { const std::string& name = pTok->at(0); DWORD dwVnum = 0; if (!GetVnumByOriginalName(name.c_str(), dwVnum)) { if (name == "exp") { dwVnum = CSpecialItemGroup::EXP; } else if (name == "mob") { dwVnum = CSpecialItemGroup::MOB; } else if (name == "slow") { dwVnum = CSpecialItemGroup::SLOW; } else if (name == "drain_hp") { dwVnum = CSpecialItemGroup::DRAIN_HP; } else if (name == "poison") { dwVnum = CSpecialItemGroup::POISON; } else if (name == "bleed") { dwVnum = CSpecialItemGroup::BLEED; } else if (name == "group") { dwVnum = CSpecialItemGroup::MOB_GROUP; } else { str_to_number(dwVnum, name.c_str()); if (!ITEM_MANAGER::instance().GetTable(dwVnum)) { sys_err("ReadSpecialDropItemFile : there is no item %s : node %s", name.c_str(), stName.c_str()); M2_DELETE(pkGroup); return false; } } } And add this below <if (name == "exp")> else if (name == "yang") { dwVnum = CSpecialItemGroup::GOLD; } I just tested it so it should work fine :=)
    1 point
  4. That is a strange woodcutter with a pickaxe
    1 point
  5. 1 point
  6. Replace those Chinese characters with 'exp'. if (name == "경험치" || name == "exp") { dwVnum = CSpecialItemGroup::EXP; }
    1 point
  7. Bad code I think it's better with gm table and a new colum with numbers. 1 = cannot use the function 2 = can spawn x and y 3 can use full
    1 point
  8. Just compile the Preprocessor and use it And for texture modification for example RebaseTextureFiles is intended to change the filestrings reported for textures from absolute paths (used by Max and Maya), to paths relative to the root of your game data directory, the character file itself, or any other root you want to specify. preprocessor RebaseTextureFiles file.gr2 -output file_relative.gr2 -basepath c:/game/data/root For modifying textures the granny preprocessor provides Renames granny_file_info members specified by "-rename Name[idx]" preprocessor RenameElement base.gr2 -output base.gr2 -rename textures[0] -newname "d:/ymir work/npc_mount/new_texture_name.dds" Would change texture index 0 to d:/ymir work/npc_mount/new_texture_name.dds You can event automate most of this process just by creating a batch file the processor takes and executes on the given file BonesPerMesh -bonelimit 100 CleanMaterials VertexCacheOptimize PlatformConvert -pointer 32 -endian little Compress With just this and Granny 2.11 you have a good amount of performance gain in metin2 for example This little script for example takes an directory collects all gr2 files and applies a file called dx9.ppb to the collected files from __future__ import print_function import fnmatch import os import subprocess import sys #[Hidden Content] def query_yes_no(question, default="yes"): """Ask a yes/no question via raw_input() and return their answer. "question" is a string that is presented to the user. "default" is the presumed answer if the user just hits <Enter>. It must be "yes" (the default), "no" or None (meaning an answer is required of the user). The "answer" return value is True for "yes" or False for "no". """ valid = {"yes": True, "y": True, "ye": True, "no": False, "n": False} if default is None: prompt = " [y/n] " elif default == "yes": prompt = " [Y/n] " elif default == "no": prompt = " [y/N] " else: raise ValueError("invalid default answer: '%s'" % default) while True: sys.stdout.write(question + prompt) choice = raw_input().lower() if default is not None and choice == '': return valid[default] elif choice in valid: return valid[choice] else: sys.stdout.write("Please respond with 'yes' or 'no' " "(or 'y' or 'n').\n") # Print iterations progress #[Hidden Content] def printProgressBar(iteration, total, prefix = '', suffix = '', decimals = 1, length = 100, fill = '#'): """ Call in a loop to create terminal progress bar @params: iteration - Required : current iteration (Int) total - Required : total iterations (Int) prefix - Optional : prefix string (Str) suffix - Optional : suffix string (Str) decimals - Optional : positive number of decimals in percent complete (Int) length - Optional : character length of bar (Int) fill - Optional : bar fill character (Str) """ percent = ("{0:." + str(decimals) + "f}").format(100 * (iteration / float(total))) filledLength = int(length * iteration // total) bar = fill * filledLength + '-' * (length - filledLength) print('\r%s |%s| %s%% %s' % (prefix, bar, percent, suffix), end = '\r') # Print New Line on Complete if iteration == total: print() print("ATTENTION! This script should only be executed in single folders") print("as it always changes the granny files recursively. We do") print("not want that data bloat in our git repository") print("") accepted = query_yes_no("Are you sure you want to execute the updater?") if not accepted: sys.exit() path = raw_input("Enter the path that you want to convert:") if path == ".": accepted = query_yes_no("Do you know that . is everything?") if not accepted: sys.exit() matches = [] for root, dirnames, filenames in os.walk("source/" + path): for filename in fnmatch.filter(filenames, '*.gr2'): matches.append(os.path.join(root, filename)) total = len(matches) if total <= 0: print("No gr2 file found in path: " + path) sys.exit() printProgressBar(0, total, prefix = 'Progress:', suffix = 'Complete', length = 50) for i, match in enumerate(matches): printProgressBar(i, total, prefix = 'Progress:', suffix = 'Complete', length = 50) subprocess.call(['preprocessor.exe', 'RunBatch', '-batch', 'dx9.ppb', match]) print("Done")
    1 point
  9. Contact ? Koray ? Skype or Discord i buy system premium , no this free. Skype : carpe.diem285 Discord : CarpeDiem#6969
    0 points
×
×
  • Create New...

Important Information

Terms of Use / Privacy Policy / Guidelines / We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.