Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation on 05/03/24 in all areas

  1. M2 Download Center Download Here ( Internal 2.9 ) Download Here ( Last Release ) This is an archiver I've created, and it looks quite stable so far. The PackMakerLite (PML) supports type 0-1-2-3-4-5-6. As a summarize, the metin2 types are handled like this: Type 0 - only storage (no encryption/compression; it can be read fully from the .epk) Type 1 - compressed - lzo(file) Type 2 - compressed and encrypted - xtea(lzo(file)) Type 3 - encrypted with Panama - you must save an .iv key server-side in the panama/ folder. (content readable only after auth phase) The official used it only for patch2. Type 4 - encrypted with a mix of ciphers (cshybridcrypt) - you must save a .dat key server-side in the package/ folder. (content readable only after auth phase) Practically all the metin2_patch files. Type 5 - like type 4, but a server-side map/<map_name> is also provided. (content readable only after accessing the <map_name> map as a player) The official used it only for the catacomb data. Type 6 - compressed and encrypted - xtea(snappy(file)) Usage: Its settings (xtea keys, extensions, pack types to use) can be changed inside PackMakerLite.json: You can actually integrate the tool in the menu context (running the .reg files) for packing folders and unpacking .eix files: Remove "--nolog" from the .bat files if you want to see the logs again. Command-line options get overwritten by JSON config options. Last but not least: since the client handles all the filenames in lowercase, this tools automatically converts them as well. Thanks also to: blackdragonx61 / Mali - type4-5 extract code / type 6 compress code metin2team - type6 extract code By martysama0134
    3 points
  2. Download Updated at 2023.08.05. Alternative download links: Client & Serverfiles + VDI + Extension Pack [40250] Reference Serverfile + Client + Src [15 Available Languages] My goal was to make a reference r40250 serverfile as official as possible compared to what GF had back when their files got leaked in early 2014. No new systems added, only bug fixes. While I spent several hours testing, there may still be bugs. Please report bugs to me so I can fix them in the future, I want to make this project as bug free as possible. Available languages: EN/DE/HU/FR/CZ/DK/ES/GR/IT/NL/PL/PT/RO/RU/TR Please read Languages.txt to learn how to change the default EN language. SSH for VM: root/123456789 MySQL: root/123456789 Ingame: admin/123456789 Aliases and it's commands: start cd /usr/metin2/server && sh start.sh close cd /usr/metin2/server && sh close.sh clean cd /usr/metin2/server && sh clean.sh backup cd /usr/metin2/server && sh backup.sh questcompile cd /usr/metin2/server/share/locale/english/quest && python2.7 make.py dbclean cd /usr/metin2/src/server/db/src && gmake clean dbdep cd /usr/metin2/src/server/db/src && gmake dep dbcompile cd /usr/metin2/src/server/db/src && gmake -j9 gameclean cd /usr/metin2/src/server/game/src && gmake clean gamedep cd /usr/metin2/src/server/game/src && gmake dep gamecompile cd /usr/metin2/src/server/game/src && gmake -j9 Please read Changelog.txt to find more about the changes I made. Special thanks to: @Mali for the clean and updated client & server src files. @Sanchez for the 2014 base client. @Veltor88 for the translate.lua pack. @Fazer for the locale_string pack I made a little video about installing the serverfile (vm) and changing the language: PS: I know it's pretty late in 2021 but better than ever Sincerely, TMP4
    2 points
  3. Hello guys, Since most people still use Notepad++, it will be useful to just a few people only. So, if you just start the VSCode and edit files, it'll f.cked your korean text. (LC_TEXT) (For me, it did) You should go to Preferences - Settings - Search for "encoding" and change the "UTF8" to "ISO 8859-1" (And disable auto guess encoding if it's enabled)
    2 points
  4. Download VDI ( FULLY UPDATED ) Alternative download links → SRC TAR (OUTDATED) or Client VS22 Source or CLIENT TMP4 BASE - Fully updated Updates List : #define ENABLE_AUTODETECT_INTERNAL_IP #define ENABLE_PROXY_IP #define ENABLE_PORT_SECURITY #define _IMPROVED_PACKET_ENCRYPTION_ // ��Ŷ ��ȣȭ ���� #define ENABLE_RING_OF_SECRETS #define __SKILL_COLOR_SYSTEM__ // Skill color system //#define __AUCTION__ #define __PET_SYSTEM__ #define __UDP_BLOCK__ #define ENABLE_ANTI_EXP #define BL_PARTY_POSITION #define __SEND_TARGET_INFO__ #define ENABLE_SEND_TARGET_INFO_EXTENDED #define ENABLE_WHISPER_RENEWAL #define ENABLE_DUEL_EFFECT #define BL_AUTOMATIC_OXEVENT #define ENABLE_EMOJI_SYSTEM #define __BL_ENABLE_PICKUP_ITEM_EFFECT__ #define ENABLE_PM_IN_GLOBAL_CHAT #define ENABLE_GLOBAL_CHAT #define __BL_KILL_BAR__ GAMEPLAY READY. Run & Enjoy DISCORD SERVER ( FOR QUESTIONS & IMPROVEMENTS ) Discord
    2 points
  5. M2 Download Center Download Here ( Internal ) Hi everyone, As title say, this is a wiki system but, InGame . This system was made by Kori . When i download it, the system had a bug on item bar, so, i've removed it . Screen of system: The system is open by pressing a key ( choosed for you ) . How to ? Well, 1º - Unpack your root . 2º- Search for archive game.py 3º- Open it and add: import uiwiki 4º - Search for: def __init__(self, stream): and add: self.wiki = uiwiki.AgeofPlatonWiki() 5º - Search for: onPressKeyDict[app.DIK_F5] and next add: onPressKeyDict[app.DIK_F9] = lambda : self.__OnWiki() Note: in here: [app.DIK_F9], F9 will be the key would you need to press to can view the system . You can change it , like you want. 6º - In the end of all ( game.py ) add this: def __OnWiki(self): if self.wiki.IsShow(): self.wiki.Hide() else: self.wiki.Show() 7º - Download the archive, add it to root, and pack it again . Download: Link Here Password: www.metin2dev.org Have fun ! Kind Regards, Grave
    2 points
  6. Hi, By pressing SHIFT + RIGHT CLICK on the items eligible for sale, an interface will appear showing you how much money you will receive and how many items you have selected. The selected items will have a special icon indicating that they have been selected. More information can be found in the README. [Hidden Content] [Hidden Content]
    2 points
  7. M2 Download Center Download Here ( Internal ) [Hidden Content]- Images & Video: Some Informations From Black: If you have a problem, you can send me a private message. You know me, I reply to all private messages
    2 points
  8. Download Other Mirros Download Here (GitHub) Download Here (Mega) Ship Defense is a dungeon accessible only in groups (minimum 2 players, maximum 8) in which players set sail for the new continent defending the ship’s mast from increasingly stronger and more numerous monsters until they defeat all three heads of the Hydra boss. Once the mission is complete, the participants will receive some rewards (determined by chance). Information Demonstration
    2 points
  9. Hello community, I have received several messages asking for a patcher that will update files, no matter how small the change, and that will not alert to viruses. I will share with you for free the solution I use in my projects. VirusTotal [Hidden Content] Preview Step by Step [Hidden Content] Thanks to @ martysama0134 for some files.
    2 points
  10. Hello Guys, today I bring you a simple CMS for your metin2 server. User features: Register Login Player and Guild ranking Downloads Change email Change password Warehouse password Character password Unbugg character Recover account password Admin features: Add post Edit post Delete post Ban user permanent Ban user for days Unbann user Add coins to players Remove coins from players Some others things: Enable/Disable Lycan in Ranking (disabled by default) Enable and set max accounts per email (disabled by default) Enable/disable register Block user login on site if banned option to change website language easily Send emails with SMTP(PHPMailer) and more... Its made with slim framework v2 and raintpl, supports PHP 7.0.0+ All changes can be made in 'vendor/init.php'. Required PHP Modules: session json pdo pdo_mysql filter sockets - optional If you use apache its necessary to activate mod_rewrite for friendly url or you get a 404 error. (for others web servers you can check slim framework documentation to fix possible errors) For localhost tests: I've found in levmud website a link for localhost tests, it contains some modifications to not call google recaptcha and some small changes in index.php Direct link: [Hidden Content] (outdated) Production link: [Hidden Content] (v1.2.1) Demo: [Hidden Content] Backup: Metin2 Download Demo user: admin | password: !Admin1! You can change server responses to english in init.php (SERVER_LANG, 'en') but all HTML files are in portuguese. Its free to use, share and modify. I'm not the owner. Hope its useful for someone Update - new version! ## [1.2.1] - 2022-03-01 ### Changed - Account creation and Login moved to individual pages. - Improved 'TopClass' ranking. ### Added - New option 'ENABLE_CAPTCHA' in /vendor/init.php. (set to false for localhost tests) ### Fixed - Fixed error when trying to login with BLOCK_LOGIN_SITE_USER_BAN enabled. - Fixed the possibility to access "deleted" posts.
    2 points
  11. I noticed one bug with specular, probably every server has it, simply ymir bug. I've never played much metin but now it happened to me on the server so I searched searched but couldn't find anything then a guy named @rid gave me a fix no problem without paying and even wrote me that I can post it on the forum so here you are. [Hidden Content] Thanks @rid for share his fix.
    2 points
  12. M2 Download Center Download Here ( Internal ) Hello community, With the changes of the game, the items and mobs are now managed through a txt. And as there are problems in generating this txt and to manage the same, I decided I wanted to continue to manage the items and mobs by the database, since it is much easier to make changes and filter searches. Say this way will have 4 tables (item_proto, item_proto_WORK, mob_proto and mob_proto_WORK). The _WORK tables are where we do our updates, is basically just duplicate the original, the other 2 remaining are those that will be updated automatically by the game to read the txt generated by this converter. In my case, I have the file in the share / server conf folder (same folder as the item_proto.txt, item_names.txt, mob_proto.txt and mob_names.txt). Here is the conversion script (cproto.php): <?php /** * Item_proto and mob_proto converter * * */ // MySQL/DB Configuration $config["mysql_host"] = "192.168.5.100"; $config["mysql_user"] = "root"; $config["mysql_pass"] = ""; $config["player_db"] = "player"; $config["item_proto_work"] = "item_proto_WORK"; // Tabela de trabalho $config["mob_proto_work"] = "mob_proto_WORK"; // Tabela de trabalho // Output Configuration $config["prefix_output"] = ""; // Este prefixo é para debug apenas. Exemplo: metin2_ => metin2_item_proto.txt $config["item_output"] = array("{$config["prefix_output"]}item_names.txt", "{$config["prefix_output"]}item_proto.txt", "{$config["prefix_output"]}item_proto_test.txt"); $config["mob_output"] = array("{$config["prefix_output"]}mob_names.txt", "{$config["prefix_output"]}mob_proto.txt", "{$config["prefix_output"]}mob_proto_test.txt"); class Proto{ private static $dbCon = false; public static $targets = ""; public static function start(){ if(self::getTargets()){ self::convertTargets(); } } private static function output($string, $color, $restoreColor = true, $breakline = true){ switch($color){ case "red": $initColor = "033[31m"; break; case "green": $initColor = "033[32m"; break; default: $initColor = "033[0m"; } $out = $initColor.$string; if($restoreColor){ $out .= "033[0m"; } if($breakline){ $out .= "n"; } echo $out; } private static function write($file, $lines){ $fo = fopen($file, "w"); fwrite($fo, $lines); fclose($fo); } private static function connect(){ global $config; if(!self::$dbCon){ $c = @mysql_connect($config["mysql_host"], $config["mysql_user"], $config["mysql_pass"]) or die(self::output("Erro #1: Ocorreu um erro ao ligar à base de dados.", "red")); if($c){ self::$dbCon = true; self::output("Ligação à base de dados com sucesso.", "green"); } } } private static function getTargets(){ global $config; if($_SERVER["argc"] > 1){ $tmp = array(); foreach($_SERVER["argv"] as $k => $v){ if($v == "all"){ $tmp[] = $v; break; } if($v == "item" || $v == "mob"){ $tmp[] = $v; } } if(in_array("all", $tmp)){ self::$targets = "all"; }elseif(in_array("item", $tmp) && in_array("mob", $tmp)){ self::$targets = "all"; }else{ if(in_array("item", $tmp)){ self::$targets = "item"; } if(in_array("mob", $tmp)){ self::$targets = "mob"; } } if(in_array("all", $tmp) || in_array("item", $tmp) || in_array("mob", $tmp)){ return true; }else{ self::output("Erro #3: Argumento inválido.", "red"); } }else{ self::output("Erro #2: Precisas de especificar pelo menos um argumento.", "red"); } self::output("Item/Mob proto Converter", "green"); self::output("", "green"); self::output("Utilização: sh cproto.sh [args...]", "green"); self::output("Argumentos possíveis:", "green"); self::output(" item Converte apenas o {$config["item_proto_work"]}", "green"); self::output(" mob Converte apenas o {$config["mob_proto_work"]}", "green"); self::output(" all Converte tanto o item_proto como o mob_proto", "green"); return false; } private static function convertNumToString($target, $value){ $item_type = array(0=>"ITEM_NONE", 1=>"ITEM_WEAPON", 2=>"ITEM_ARMOR", 3=>"ITEM_USE", 4=>"ITEM_AUTOUSE", 5=>"ITEM_MATERIAL", 6=>"ITEM_SPECIAL", 7=>"ITEM_TOOL", 8=>"ITEM_LOTTERY", 9=>"ITEM_ELK", 10=>"ITEM_METIN", 11=>"ITEM_CONTAINER", 12=>"ITEM_FISH", 13=>"ITEM_ROD", 14=>"ITEM_RESOURCE", 15=>"ITEM_CAMPFIRE", 16=>"ITEM_UNIQUE", 17=>"ITEM_SKILLBOOK", 18=>"ITEM_QUEST", 19=>"ITEM_POLYMORPH", 20=>"ITEM_TREASURE_BOX", 21=>"ITEM_TREASURE_KEY", 22=>"ITEM_SKILLFORGET", 23=>"ITEM_GIFTBOX", 24=>"ITEM_PICK", 25=>"ITEM_HAIR", 26=>"ITEM_TOTEM", 27=>"ITEM_BLEND", 28=>"ITEM_COSTUME"); $item_limit = array(0=>"LIMIT_NONE", 1=>"LEVEL", 2=>"STR", 3=>"DEX", 4=>"INT", 5=>"CON", 6=>"PC_BANG", 7=>"REAL_TIME", 8=>"REAL_TIME_FIRST_USE", 9=>"TIMER_BASED_ON_WEAR"); $item_apply = array(0=>"APPLY_NONE", 1=>"APPLY_MAX_HP", 2=>"APPLY_MAX_SP", 3=>"APPLY_CON", 4=>"APPLY_INT", 5=>"APPLY_STR", 6=>"APPLY_DEX", 7=>"APPLY_ATT_SPEED", 8=>"APPLY_MOV_SPEED", 9=>"APPLY_CAST_SPEED", 10=>"APPLY_HP_REGEN", 11=>"APPLY_SP_REGEN", 12=>"APPLY_POISON_PCT", 13=>"APPLY_STUN_PCT", 14=>"APPLY_SLOW_PCT", 15=>"APPLY_CRITICAL_PCT", 16=>"APPLY_PENETRATE_PCT", 17=>"APPLY_ATTBONUS_HUMAN", 18=>"APPLY_ATTBONUS_ANIMAL", 19=>"APPLY_ATTBONUS_ORC", 20=>"APPLY_ATTBONUS_MILGYO", 21=>"APPLY_ATTBONUS_UNDEAD", 22=>"APPLY_ATTBONUS_DEVIL", 23=>"APPLY_STEAL_HP", 24=>"APPLY_STEAL_SP", 25=>"APPLY_MANA_BURN_PCT", 26=>"APPLY_DAMAGE_SP_RECOVER", 27=>"APPLY_BLOCK", 28=>"APPLY_DODGE", 29=>"APPLY_RESIST_SWORD", 30=>"APPLY_RESIST_TWOHAND", 31=>"APPLY_RESIST_DAGGER", 32=>"APPLY_RESIST_BELL", 33=>"APPLY_RESIST_FAN", 34=>"APPLY_RESIST_BOW", 35=>"APPLY_RESIST_FIRE", 36=>"APPLY_RESIST_ELEC", 37=>"APPLY_RESIST_MAGIC", 38=>"APPLY_RESIST_WIND", 39=>"APPLY_REFLECT_MELEE", 40=>"APPLY_REFLECT_CURSE", 41=>"APPLY_POISON_REDUCE", 42=>"APPLY_KILL_SP_RECOVER", 43=>"APPLY_EXP_DOUBLE_BONUS", 44=>"APPLY_GOLD_DOUBLE_BONUS", 45=>"APPLY_ITEM_DROP_BONUS", 46=>"APPLY_POTION_BONUS", 47=>"APPLY_KILL_HP_RECOVER", 48=>"APPLY_IMMUNE_STUN", 49=>"APPLY_IMMUNE_SLOW", 50=>"APPLY_IMMUNE_FALL", 51=>"APPLY_SKILL", 52=>"APPLY_BOW_DISTANCE", 53=>"APPLY_ATT_GRADE_BONUS", 54=>"APPLY_DEF_GRADE_BONUS", 55=>"APPLY_MAGIC_ATT_GRADE", 56=>"APPLY_MAGIC_DEF_GRADE", 57=>"APPLY_CURSE_PCT", 58=>"APPLY_MAX_STAMINA", 59=>"APPLY_ATTBONUS_WARRIOR", 60=>"APPLY_ATTBONUS_ASSASSIN", 61=>"APPLY_ATTBONUS_SURA", 62=>"APPLY_ATTBONUS_SHAMAN", 63=>"APPLY_ATTBONUS_MONSTER", 64=>"APPLY_MALL_ATTBONUS", 65=>"APPLY_MALL_DEFBONUS", 66=>"APPLY_MALL_EXPBONUS", 67=>"APPLY_MALL_ITEMBONUS", 68=>"APPLY_MALL_GOLDBONUS", 69=>"APPLY_MAX_HP_PCT", 70=>"APPLY_MAX_SP_PCT", 71=>"APPLY_SKILL_DAMAGE_BONUS", 72=>"APPLY_NORMAL_HIT_DAMAGE_BONUS", 73=>"APPLY_SKILL_DEFEND_BONUS", 74=>"APPLY_NORMAL_HIT_DEFEND_BONUS", 75=>"APPLY_PC_BANG_EXP_BONUS", 76=>"APPLY_PC_BANG_DROP_BONUS", 77=>"APPLY_EXTRACT_HP_PCT", 78=>"APPLY_RESIST_WARRIOR", 79=>"APPLY_RESIST_ASSASSIN", 80=>"APPLY_RESIST_SURA", 81=>"APPLY_RESIST_SHAMAN", 82=>"APPLY_ENERGY", 83=>"APPLY_DEF_GRADE", 84=>"APPLY_COSTUME_ATTR_BONUS", 85=>"APPLY_MAGIC_ATTBONUS_PER", 86=>"APPLY_MELEE_MAGIC_ATTBONUS_PER"); $mob_rank = array(0=>"PAWN", 1=>"S_PAWN", 2=>"KNIGHT", 3=>"S_KNIGHT", 4=>"BOSS", 5=>"KING"); $mob_type = array(0=>"MONSTER", 1=>"NPC", 2=>"STONE", 3=>"WARP", 4=>"DOOR", 5=>"BUILDING", 7=>"POLYMORPH_PC", 8=>"HORSE", 9=>"GOTO"); $mob_battletype = array(0=>"MELEE", 1=>"RANGE", 2=>"MAGIC", 3=>"SPECIAL", 4=>"POWER", 5=>"TANKER"); switch($target){ case "item_type": $target = $item_type; break; case "item_limit": $target = $item_limit; break; case "item_apply": $target = $item_apply; break; case "mob_rank": $target = $mob_rank; break; case "mob_type": $target = $mob_type; break; case "mob_battletype": $target = $mob_battletype; break; default: $target = ""; } return $target[$value]; } private static function getItemSubtype($type, $subtype){ if($type == 1){ if($subtype == 0){ return ""WEAPON_SWORD""; } elseif($subtype == 1){ return ""WEAPON_DAGGER""; } elseif($subtype == 2){ return ""WEAPON_BOW""; } elseif($subtype == 3){ return ""WEAPON_TWO_HANDED""; } elseif($subtype == 4){ return ""WEAPON_BELL""; } elseif($subtype == 5){ return ""WEAPON_FAN""; } elseif($subtype == 6){ return ""WEAPON_ARROW""; } elseif($subtype == 7){ return ""WEAPON_MOUNT_SPEAR""; } elseif($subtype == 8){ return ""WEAPON_NUM_TYPES""; } }elseif($type == 2){ if($subtype == 0){ return ""ARMOR_BODY""; } elseif($subtype == 1){ return ""ARMOR_HEAD""; } elseif($subtype == 2){ return ""ARMOR_SHIELD""; } elseif($subtype == 3){ return ""ARMOR_WRIST""; } elseif($subtype == 4){ return ""ARMOR_FOOTS""; } elseif($subtype == 5){ return ""ARMOR_NECK""; } elseif($subtype == 6){ return ""ARMOR_EAR""; } elseif($subtype == 7){ return ""ARMOR_NUM_TYPES""; } }elseif($type == 3){ if($subtype == 0){ return ""USE_POTION""; } elseif($subtype == 1){ return ""USE_TALISMAN""; } elseif($subtype == 2){ return ""USE_TUNING""; } elseif($subtype == 3){ return ""USE_MOVE""; } elseif($subtype == 4){ return ""USE_TREASURE_BOX""; } elseif($subtype == 5){ return ""USE_MONEYBAG""; } elseif($subtype == 6){ return ""USE_BAIT""; } elseif($subtype == 7){ return ""USE_ABILITY_UP""; } elseif($subtype == 8){ return ""USE_AFFECT""; } elseif($subtype == 9){ return ""USE_CREATE_STONE""; } elseif($subtype == 10){ return ""USE_SPECIAL""; } elseif($subtype == 11){ return ""USE_POTION_NODELAY""; } elseif($subtype == 12){ return ""USE_CLEAR""; } elseif($subtype == 13){ return ""USE_INVISIBILITY""; } elseif($subtype == 14){ return ""USE_DETACHMENT""; } elseif($subtype == 15){ return ""USE_BUCKET""; } elseif($subtype == 17){ return ""USE_CLEAN_SOCKET""; } elseif($subtype == 18){ return ""USE_CHANGE_ATTRIBUTE""; } elseif($subtype == 19){ return ""USE_ADD_ATTRIBUTE""; } elseif($subtype == 20){ return ""USE_ADD_ACCESSORY_SOCKET""; } elseif($subtype == 21){ return ""USE_PUT_INTO_ACCESSORY_SOCKET""; } elseif($subtype == 22){ return ""USE_ADD_ATTRIBUTE2""; } elseif($subtype == 23){ return ""USE_RECIPE""; } elseif($subtype == 24){ return ""USE_CHANGE_ATTRIBUTE2""; } elseif($subtype == 25){ return ""USE_BIND""; } elseif($subtype == 26){ return ""USE_UNBIND""; } elseif($subtype == 29){ return ""AUTOUSE_BOMB""; } elseif($subtype == 30){ return ""AUTOUSE_GOLD""; } }elseif($type == 5){ if($subtype == 0){ return ""MATERIAL_LEATHER""; } elseif($subtype == 1){ return ""MATERIAL_BLOOD""; } elseif($subtype == 2){ return ""MATERIAL_ROOT""; } elseif($subtype == 3){ return ""MATERIAL_NEEDLE""; } elseif($subtype == 4){ return ""MATERIAL_JEWEL""; } }elseif($type == 6){ if($subtype == 0){ return ""SPECIAL_MAP""; } if($subtype == 1){ return ""SPECIAL_KEY""; } if($subtype == 2){ return ""SPECIAL_DOC""; } if($subtype == 3){ return ""SPECIAL_SPIRIT""; } if($subtype == 4){ return ""SPECIAL_MAP""; } }elseif($type == 7){ if($subtype == 0){ return ""TOOL_FISHING_ROD""; } }elseif($type == 8){ if($subtype == 0){ return ""LOTTERY_TICKET""; } elseif($subtype == 1){ return ""LOTTERY_INSTANT""; } }elseif($type == 10){ if($subtype == 0){ return ""METIN_NORMAL""; } elseif($subtype == 1){ return ""METIN_GOLD""; } }elseif($type == 12){ if($subtype == 0){ return ""FISH_ALIVE""; } elseif($subtype == 1){ return ""FISH_DEAD""; } }elseif($type == 14){ if($subtype == 0){ return ""RESOURCE_FISHBONE""; } elseif($subtype == 1){ return ""RESOURCE_WATERSTONEPIECE""; } elseif($subtype == 2){ return ""RESOURCE_WATERSTONE""; } elseif($subtype == 3){ return ""RESOURCE_BLOOD_PEARL""; } elseif($subtype == 4){ return ""RESOURCE_BLUE_PEARL""; } elseif($subtype == 5){ return ""RESOURCE_WHITE_PEARL""; } elseif($subtype == 6){ return ""RESOURCE_BUCKET""; } elseif($subtype == 7){ return ""RESOURCE_CRYSTAL""; } elseif($subtype == 8){ return ""RESOURCE_GEM""; } elseif($subtype == 9){ return ""RESOURCE_STONE""; } elseif($subtype == 10){ return ""RESOURCE_METIN""; } elseif($subtype == 11){ return ""RESOURCE_ORE""; } }elseif($type == 16){ if($subtype == 0){ return ""UNIQUE_NONE""; } elseif($subtype == 2){ return ""UNIQUE_SPECIAL_RIDE""; } elseif($subtype == 3){ return ""UNIQUE_3""; } elseif($subtype == 4){ return ""UNIQUE_4""; } elseif($subtype == 5){ return ""UNIQUE_5""; } elseif($subtype == 6){ return ""UNIQUE_6""; } elseif($subtype == 7){ return ""UNIQUE_7""; } elseif($subtype == 8){ return ""UNIQUE_8""; } elseif($subtype == 9){ return ""UNIQUE_9""; } elseif($subtype == 10){ return ""USE_SPECIAL""; } }elseif($type == 28){ if($subtype == 0){ return ""COSTUME_BODY""; } elseif($subtype == 1){ return ""COSTUME_HAIR""; } } return 0; } private static function getFlags($flag, $method){ $antiflags = array(0=>"NONE", 1=>"ANTI_FEMALE", 2=>"ANTI_MALE", 4=>"ANTI_MUSA", 8=>"ANTI_ASSASSIN", 16=>"ANTI_SURA", 32=>"ANTI_MUDANG", 64=>"ANTI_GET", 128=>"ANTI_DROP", 256=>"ANTI_SELL", 512=>"ANTI_EMPIRE_A", 1024=>"ANTI_EMPIRE_B", 2048=>"ANTI_EMPIRE_C", 4096=>"ANTI_SAVE", 8192=>"ANTI_GIVE", 16384=>"ANTI_PKDROP", 32768=>"ANTI_STACK", 65536=>"ANTI_MYSHOP", 131072=>"ANTI_SAFEBOX"); $flags = array(0=>"NONE", 1=>"ITEM_TUNABLE", 2=>"ITEM_SAVE", 4=>"ITEM_STACKABLE", 8=>"COUNT_PER_1GOLD", 16=>"ITEM_SLOW_QUERY", 32=>"ITEM_UNIQUE", 64=>"ITEM_MAKECOUNT", 128=>"ITEM_IRREMOVABLE", 256=>"CONFIRM_WHEN_USE", 512=>"QUEST_USE", 1024=>"QUEST_USE_MULTIPLE", 2048=>"QUEST_GIVE", 4096=>"ITEM_QUEST", 8192=>"LOG", 16384=>"STACKABLE", 32768=>"32768", 65536=>"REFINEABLE", 131072=>"131072", 262144=>"ITEM_APPLICABLE"); $wearflags = array(0=>"NONE", 1=>"WEAR_BODY", 2=>"WEAR_HEAD", 4=>"WEAR_FOOTS", 8=>"WEAR_WRIST", 16=>"WEAR_WEAPON", 32=>"WEAR_NECK", 64=>"WEAR_EAR", 128=>"WEAR_SHIELD", 256=>"WEAR_UNIQUE", 512=>"WEAR_ARROW", 1024=>"WEAR_HAIR", 2048=>"WEAR_ABILITY"); switch($method){ case "af": $target = $antiflags; break; case "f": $target = $flags; break; case "wf": $target = $wearflags; break; default: $target = ""; } $str = """; for($i=17;$i>=0;$i--){ $pow = pow(2, $i); if($pow < $flag){ $str = " | ".$target[$pow].$str; $flag = $flag-$pow; }elseif($pow == $flag){ return """.$target[$pow].$str; } } return ""NONE""; } private static function convertTargets(){ global $config; self::connect(); self::output("Item/Mob proto Converter", "green"); self::output("", "green"); if(self::$targets == "all" || self::$targets == "item"){ self::output("A converter {$config["item_proto_work"]}...", "green"); $write = array("", "", ""); $write[0] .= "VNUM LOCALE_NAMEn"; $write[1] .= ""Vnum" "Name" "Type" "SubType" "Size" "AntiFlags" "Flags" "WearFlags" "ImmuneFlags" "Gold" "ShopBuyPrice" "RefinedVnum" "RefineSet" "AlterToMagicItemPercent" "LimitType0" "LimitValue0" "LimitType1" "LimitValue1" "ApplyType0" "ApplyValue0" "ApplyType1" "ApplyValue1" "ApplyType2" "ApplyValue2" "Value0" "Value1" "Value2" "Value3" "Value4" "Value5" "Specular" "GainSocketPercent" "AddonType"n"; $write[2] .= ""Vnum" "Name" "Type" "SubType" "Size" "AntiFlags" "Flags" "WearFlags" "ImmuneFlags" "Gold" "ShopBuyPrice" "RefinedVnum" "RefineSet" "AlterToMagicItemPercent" "LimitType0" "LimitValue0" "LimitType1" "LimitValue1" "ApplyType0" "ApplyValue0" "ApplyType1" "ApplyValue1" "ApplyType2" "ApplyValue2" "Value0" "Value1" "Value2" "Value3" "Value4" "Value5" "Specular" "GainSocketPercent" "AddonType"n"; $query = mysql_query("SELECT * FROM {$config["player_db"]}.{$config["item_proto_work"]} ORDER BY vnum ASC"); while($fetch = mysql_fetch_assoc($query)){ $type = self::convertNumToString("item_type", $fetch["type"]); $subtype = self::getItemSubtype($fetch["type"], $fetch["subtype"]); $antiflag = self::getFlags($fetch["antiflag"], "af"); $flag = self::getFlags($fetch["flag"], "f"); $wearflag = self::getFlags($fetch["wearflag"], "wf"); $immuneflag = (empty($fetch["immuneflag"])) ? ""NONE"" : ""{$fetch["immuneflag"]}""; $limittype0 = self::convertNumToString("item_limit", $fetch["limittype0"]); $limittype1 = self::convertNumToString("item_limit", $fetch["limittype1"]); $applytype0 = self::convertNumToString("item_apply", $fetch["applytype0"]); $applytype1 = self::convertNumToString("item_apply", $fetch["applytype1"]); $applytype2 = self::convertNumToString("item_apply", $fetch["applytype2"]); $write[0] .= "{$fetch["vnum"]} {$fetch["locale_name"]}n"; $write[1] .= "{$fetch["vnum"]} "{$fetch["name"]}" "{$type}" {$subtype} {$fetch["size"]} {$antiflag} {$flag} {$wearflag} {$immuneflag} {$fetch["gold"]} {$fetch["shop_buy_price"]} {$fetch["refined_vnum"]} {$fetch["refine_set"]} {$fetch["magic_pct"]} "{$limittype0}" {$fetch["limitvalue0"]} "{$limittype1}" {$fetch["limitvalue1"]} "{$applytype0}" {$fetch["applyvalue0"]} "{$applytype1}" {$fetch["applyvalue1"]} "{$applytype2}" {$fetch["applyvalue2"]} {$fetch["value0"]} {$fetch["value1"]} {$fetch["value2"]} {$fetch["value3"]} {$fetch["value4"]} {$fetch["value5"]} {$fetch["specular"]} {$fetch["socket_pct"]} {$fetch["addon_type"]}n"; $write[2] .= "{$fetch["vnum"]} "{$fetch["name"]}" "{$type}" {$subtype} {$fetch["size"]} {$antiflag} {$flag} {$wearflag} {$immuneflag} {$fetch["gold"]} {$fetch["shop_buy_price"]} {$fetch["refined_vnum"]} {$fetch["refine_set"]} {$fetch["magic_pct"]} "{$limittype0}" {$fetch["limitvalue0"]} "{$limittype1}" {$fetch["limitvalue1"]} "{$applytype0}" {$fetch["applyvalue0"]} "{$applytype1}" {$fetch["applyvalue1"]} "{$applytype2}" {$fetch["applyvalue2"]} {$fetch["value0"]} {$fetch["value1"]} {$fetch["value2"]} {$fetch["value3"]} {$fetch["value4"]} {$fetch["value5"]} {$fetch["specular"]} {$fetch["socket_pct"]} {$fetch["addon_type"]}n"; } for($i=0;$i<2;$i++){ self::output(" -> A escrever {$config["item_output"][$i]}...", "green"); self::write($config["item_output"][$i], $write[$i]); } self::output("{$config["item_proto_work"]} convertido com sucesso!", "green"); } if(self::$targets == "all" || self::$targets == "mob"){ self::output("A converter {$config["mob_proto_work"]}...", "green"); $write = array("", "", ""); $write[0] .= "VNUM LOCALE_NAMEn"; $write[1] .= ""Vnum" "Name" "Rank" "Type" "BattleType" "Level" "Size" "AiFlags" "MountCapacity" "RaceFlags" "ImmuneFlags" "Empire" "Folder" "OnClick" "St" "Dx" "Ht" "Iq" "MinDamage" "MaxDamage" "MaxHp" "RegenCycle" "RegenPercent" "MinGold" "MaxGold" "Exp" "Def" "AttackSpeed" "MoveSpeed" "AggressiveHpPct" "AggressiveSight" "AttackRange" "DropItemGroup" "ResurrectionVnum" "EnchantCurse" "EnchantSlow" "EnchantPoison" "EnchantStun" "EnchantCritical" "EnchantPenetrate" "ResistSword" "ResistTwoHanded" "ResistDagger" "ResistBell" "ResistFan" "ResistBow" "ResistFire" "ResistElect" "ResistMagic" "ResistWind" "ResistPoison" "DamMultiply" "SummonVnum" "DrainSp" "MobColor" "PolymorphItem" "SkillLevel0" "SkillVnum0" "SkillLevel1" "SkillVnum1" "SkillLevel2" "SkillVnum2" "SkillLevel3" "SkillVnum3" "SkillLevel4" "SkillVnum4" "SpBerserk" "SpStoneskin" "SpGodspeed" "SpDeathblow" "SpRevive"n"; $write[2] .= ""Vnum" "Name" "Rank" "Type" "BattleType" "Level" "Size" "AiFlags" "MountCapacity" "RaceFlags" "ImmuneFlags" "Empire" "Folder" "OnClick" "St" "Dx" "Ht" "Iq" "MinDamage" "MaxDamage" "MaxHp" "RegenCycle" "RegenPercent" "MinGold" "MaxGold" "Exp" "Def" "AttackSpeed" "MoveSpeed" "AggressiveHpPct" "AggressiveSight" "AttackRange" "DropItemGroup" "ResurrectionVnum" "EnchantCurse" "EnchantSlow" "EnchantPoison" "EnchantStun" "EnchantCritical" "EnchantPenetrate" "ResistSword" "ResistTwoHanded" "ResistDagger" "ResistBell" "ResistFan" "ResistBow" "ResistFire" "ResistElect" "ResistMagic" "ResistWind" "ResistPoison" "DamMultiply" "SummonVnum" "DrainSp" "MobColor" "PolymorphItem" "SkillLevel0" "SkillVnum0" "SkillLevel1" "SkillVnum1" "SkillLevel2" "SkillVnum2" "SkillLevel3" "SkillVnum3" "SkillLevel4" "SkillVnum4" "SpBerserk" "SpStoneskin" "SpGodspeed" "SpDeathblow" "SpRevive"n"; $query = mysql_query("SELECT * FROM {$config["player_db"]}.{$config["mob_proto_work"]} ORDER BY vnum ASC"); while($fetch = mysql_fetch_assoc($query)){ $rank = self::convertNumToString("mob_rank", $fetch["rank"]); $type = self::convertNumToString("mob_type", $fetch["type"]); $battletype = self::convertNumToString("mob_battletype", $fetch["battle_type"]); $ai_flag = (empty($fetch["ai_flag"])) ? "" : ""{$fetch["ai_flag"]}""; $setRaceFlag = (empty($fetch["setRaceFlag"])) ? "" : ""{$fetch["setRaceFlag"]}""; $setImmuneFlag = (empty($fetch["setImmuneFlag"])) ? "" : ""{$fetch["setImmuneFlag"]}""; $mob_color = (empty($fetch["mob_color"])) ? "0" : "{$fetch["mob_color"]}"; $write[0] .= "{$fetch["vnum"]} {$fetch["locale_name"]}n"; $write[1] .= "{$fetch["vnum"]} "{$fetch["name"]}" "{$rank}" "{$type}" "{$battletype}" {$fetch["level"]} {$fetch["size"]} {$ai_flag} {$fetch["mount_capacity"]} {$setRaceFlag} {$setImmuneFlag} {$fetch["empire"]} "{$fetch["folder"]}" {$fetch["on_click"]} {$fetch["st"]} {$fetch["dx"]} {$fetch["ht"]} {$fetch["iq"]} {$fetch["damage_min"]} {$fetch["damage_max"]} {$fetch["max_hp"]} {$fetch["regen_cycle"]} {$fetch["regen_percent"]} {$fetch["gold_min"]} {$fetch["gold_max"]} {$fetch["exp"]} {$fetch["def"]} {$fetch["attack_speed"]} {$fetch["move_speed"]} {$fetch["aggressive_hp_pct"]} {$fetch["aggressive_sight"]} {$fetch["attack_range"]} {$fetch["drop_item"]} {$fetch["resurrection_vnum"]} {$fetch["enchant_curse"]} {$fetch["enchant_slow"]} {$fetch["enchant_poison"]} {$fetch["enchant_stun"]} {$fetch["enchant_critical"]} {$fetch["enchant_penetrate"]} {$fetch["resist_sword"]} {$fetch["resist_twohand"]} {$fetch["resist_dagger"]} {$fetch["resist_bell"]} {$fetch["resist_fan"]} {$fetch["resist_bow"]} {$fetch["resist_fire"]} {$fetch["resist_elect"]} {$fetch["resist_magic"]} {$fetch["resist_wind"]} {$fetch["resist_poison"]} {$fetch["dam_multiply"]} {$fetch["summon"]} {$fetch["drain_sp"]} {$mob_color} {$fetch["polymorph_item"]} {$fetch["skill_level0"]} {$fetch["skill_vnum0"]} {$fetch["skill_level1"]} {$fetch["skill_vnum1"]} {$fetch["skill_level2"]} {$fetch["skill_vnum2"]} {$fetch["skill_level3"]} {$fetch["skill_vnum3"]} {$fetch["skill_level4"]} {$fetch["skill_vnum4"]} {$fetch["sp_berserk"]} {$fetch["sp_stoneskin"]} {$fetch["sp_godspeed"]} {$fetch["sp_deathblow"]} {$fetch["sp_revive"]}n"; $write[2] .= "{$fetch["vnum"]} "{$fetch["name"]}" "{$rank}" "{$type}" "{$battletype}" {$fetch["level"]} {$fetch["size"]} {$ai_flag} {$fetch["mount_capacity"]} {$setRaceFlag} {$setImmuneFlag} {$fetch["empire"]} "{$fetch["folder"]}" {$fetch["on_click"]} {$fetch["st"]} {$fetch["dx"]} {$fetch["ht"]} {$fetch["iq"]} {$fetch["damage_min"]} {$fetch["damage_max"]} {$fetch["max_hp"]} {$fetch["regen_cycle"]} {$fetch["regen_percent"]} {$fetch["gold_min"]} {$fetch["gold_max"]} {$fetch["exp"]} {$fetch["def"]} {$fetch["attack_speed"]} {$fetch["move_speed"]} {$fetch["aggressive_hp_pct"]} {$fetch["aggressive_sight"]} {$fetch["attack_range"]} {$fetch["drop_item"]} {$fetch["resurrection_vnum"]} {$fetch["enchant_curse"]} {$fetch["enchant_slow"]} {$fetch["enchant_poison"]} {$fetch["enchant_stun"]} {$fetch["enchant_critical"]} {$fetch["enchant_penetrate"]} {$fetch["resist_sword"]} {$fetch["resist_twohand"]} {$fetch["resist_dagger"]} {$fetch["resist_bell"]} {$fetch["resist_fan"]} {$fetch["resist_bow"]} {$fetch["resist_fire"]} {$fetch["resist_elect"]} {$fetch["resist_magic"]} {$fetch["resist_wind"]} {$fetch["resist_poison"]} {$fetch["dam_multiply"]} {$fetch["summon"]} {$fetch["drain_sp"]} {$mob_color} {$fetch["polymorph_item"]} {$fetch["skill_level0"]} {$fetch["skill_vnum0"]} {$fetch["skill_level1"]} {$fetch["skill_vnum1"]} {$fetch["skill_level2"]} {$fetch["skill_vnum2"]} {$fetch["skill_level3"]} {$fetch["skill_vnum3"]} {$fetch["skill_level4"]} {$fetch["skill_vnum4"]} {$fetch["sp_berserk"]} {$fetch["sp_stoneskin"]} {$fetch["sp_godspeed"]} {$fetch["sp_deathblow"]} {$fetch["sp_revive"]}n"; } for($i=0;$i<2;$i++){ self::output(" -> A escrever {$config["mob_output"][$i]}...", "green"); self::write($config["mob_output"][$i], $write[$i]); } self::output("{$config["mob_proto_work"]} convertido com sucesso!", "green"); } } } Proto::start(); ?> cproto.sh ROOT=$PWD cd $ROOT/share/conf && php -a cproto.php $1 $2 Commands: sh cproto.sh mob sh cproto.sh item sh cproto.sh all If you have any item / wrong mob, might give you problems when you start the game, however it is a good way to know they have something wrong in your item / mob proto and correct. The most common errors are the sets of types / subtypes and limits of items.
    2 points
  13. M2 Download Center Download Here ( Internal ) VegaS 2016 Characteristics: Description: It's a teleport ring quest You do the settings here: And on each error message you have a "Go back" button: Link download: [Hidden Content] How to use: Just make the configs and translations and you're done Another picture: Example of map1 configs:
    2 points
  14. M2 Download Center Download Here ( Internal ) Scan: [Hidden Content] Download: [Hidden Content] May this will help for someone understand (why is useless) how hackshield works and how to run it in metin2.
    2 points
  15. M2 Download Center Download Here ( Internal ) Download Here ( Latest Version ) This WE is a version compiled directly by me which includes infinite fixes and features. It's certain that you won't longer use the worldeditor_en! To make it simple, I wrote all the details about this feature and the common WE inside the relative config file: (called WorldEditorRemix.ini) ; Info: ; -) 100% translated ; -) granny2.11 ; -) F6 as Insert alternative ; -) many default features not present inside the worldeditor_en (probably, that binary was taken out from an SVN long time ago and resource hacked) such as Ins for all regions and skyboxes ; -) WASD UPLEFTDOWNRIGHT to move around (+asynchronous diagonally movements) ; -) UP-LEFT-DOWN-RIGHT to move around*10 (+asynchronous diagonally movements) ; -) config file for few things ; Output options by default ; few others such as default WASD movement ; whether or not Insert should let you go where you were before the press ; no MAI dump when saving atlas ; whether or not DevIL should compress and remove alpha from minimap.dds ; whether or not loading .mdatr building heights ; default textureset when creating maps ; overlapped tabs ; other stuff ; -) several bugfixes ; default title app name ; attempting to write to an empty textureset name when creating new maps ; ViewRadius doubled every load&save ; shadowmap.dds creation ; assert when saving atlas ; crash when adjusting height ; many buffer under/overflows ; *.mdc collision data saving (for game_test) ; not checking output options when loading maps ; water brush waterid bug (the id was increased until 256 each time the function was called; now it's based on the water height just like it should be) ; init texture map reload map crash and last 2px always blank ; square shape even for up/down height brushes ; add textureset texture button (+multiselection) ; remove textureset texture feature (just selecting a texture from the list and pressing DELETE) ; creation of empty textureset with index -1 (changed to 0) ; change baseposition button ; misspelled stuff ; skybox bottom image (nb: you also need a fixed launcher for this) ; removed boring CTRL requirement (to move the camera) when editing daylight/attr ; fixed refresh texture imagebox onKey pressing the down/up keys (like when onClicking them) ; fixed TextureSet file creation if not existing ; fixed new wolfman motion event handling ; fixed crash when editing animation attack bones and 00010.gr2 was missing ; fixed locale/ymir/mob_proto load (it autodetects the most common structures) and <map>/regen.txt load/save ; fixed ./group.txt load ; fixed load/save/edit <map>/regen.txt (very nice for "m" regens, untested for "g") ; load from PACK is available if pack/property is present! Be sure pack/Index exists! ; fixed multi-object selection crash ; fixed crash when previewing a missing texture ; fixed not clearing of old environment (e.g. skybox) when switching maps ; fixed not creating property folders in root tree (object tab) ; fixed object attachment in Model Tab ; fixed newly particles names in Effect Tab ; fixed crash when saving a .mse script with no mesh model ; fixed crash when inserting a lower gradient ; -) created new TextureSet field when creating new maps ; -) created new Change/Delete Texture buttons when double-clicking a texture ; -) created Background Music playback and Shadow Recalculate buttons ; -) created water height "set 0z", "+1z", "-1z" buttons ; -) server_attr generator ; -) every crash will generate a logs/WorldEditorRemix_{target}_{date}.dmp file useful for debugging ; -) implemented a "water path" mapsettings option (the launcher requires additional code) ; -) implemented a "wind strength" msenv option (the launcher requires additional code) ; -) the "encrypt data" feature does nothing (unimplemented) ; Note: ; 0) there are no regressions in this version! a bug here means it'd also be present in older WE versions too! ; 1) the shadow output option is tricky: when UpdateUI is called, shadows are hidden although the check is pressed (i implemented the shadow recalculate function for that) #fixed since v11 ; 2) the bgm player requires /miles and the fadein/out doesn't work until you load the map ; 3) the adjusting height button works only if mdatr height is detected ; 4) the Debug version is laggy when working on maps such as n_flame_dungeon and n_ice_dungeon (by default, because SphereRadius are intensively checked in SphereLib\spherepack.h) ; 5) if you load a map, the script panels (where you load .msa et similia) will have the camera perspective a little fucked up (0z instead of -32767z or 0x 0y -163,94z) ; 6) few tree objects are not movable and/or highlightable after placed on the ground and their selection is invisible (you can still delete 'em) ; trick: draw a square selecting a normal building and 'em, then move the building and you'll see all of 'em will be moved! ; 7) the server_attr generator will clean all the unused flags! attr[idx]&=~0xFFFFFFF8; ; 8) you can read files from pack/Index 'n stuff but be aware that Property will not be considered! #fixed since v15 ; 9) the MonsterAreaInfo features are laggy and buggy as fuck ; 10) even though you can select many textures at once (using ctrl+click on textureset list; for brushing or initializing a base texture), you can't delete more than one at the same time ; 11) the .mdatr height is tricky; if you move a building, the height will not be refreshed until you put a new building or whatever you want to trigger the update event ; 12) by default, the worldeditor tries to render only the first 8 terrain textures of a 32x32px region (nb: a 1x1 map is a 256x256 px region) ; 13) the minimap rendering cannot catch the buildings/trees inside the first 2x2 regions due a ymir cache fault and you need to set the camera to "see" them ; 14) when the textureset, environment, etc load fails, the old filename still remains loaded ; 15) the attr flag "3" (three) has no implementation, so don't use it! ; 16) load from PACK doesn't load texturesets from files for first (if they are already in pack/), and the object placer's object list will remain empty because it takes the list from property/ (and not from pack/property) ; 17) to save the regen.txt you press CTRL+S ; 18) if you enable the wireframe (f4) when on Attr Tab, you see the terrain all white ; 19) the water brush disappears when the camera renders the waterwheel small/big effect ; 20) the monster area info goes under ground if you're outside the relative sectree ; 21) the full skybox may be displayed only after the top picture has been added (if the other textures have already been inserted) ; 22) the slider in the Attr Tab is something like "16 photoshop layers" in which you can split your attrs; not so helpful and quite confusing sometimes ; 23) the fixed model - object attachment attaches static objects (hairs'skeleton will not mirror the playing animation) ; 24) in environment tab, if you insert lower gradients, you may end up with an out of range crash #fixed since v30 ; 25) brushes working out-of-screen/map-range may affect random terrain places ; TODO: ; A) look at more than 8 textures for region -> DONE ; B) create a shortcut to fix the #5 note -> DONE ; C) disable the radius <= GetRadius()+0.0001f check to fix the #4 note -> REJECTED ; the worldeditor_en calls this assert and, if ignored, the lag ceases to exist (this will not occur in source version) ; at least, if the release version is not a problem for you, use that in those few cases when .mse are abused and try to kill the debug one ; D) translation in more languages other than english -> REJECTED ; english should be enough! ; E) alternative path for d: -> REJECTED ; you can mount d as a subpath of c like this: ; subst d: "c:\mt2stuff" ; F) need to fix note #19 #25 -> TODO [shortcuts] ; ### SHORTCUTS ; # ESC(ape) Clean cursor ; # Canc(el|Delete) Delete stuff such as selected buildings ; # Ctrl+S Save map ; # Ins(ert) or F6 Save shadowmap|minimap.dds ; # F3 BoundGrid Show/Hide ; # F4 Render UI Show/Hide ; # F11 WireFrame Show/Hide ; # R Reload Texture ; # Z and X Decrease/Increase Texture Splat by 0.1 ; # CapsLock Show GaussianCubic effect if shadows are displayed ; # L-Shift+1-6 Show TextureCountThreshold flags (&2-7) as colors on the ground ; # L-Shift+8 Set Max Showable texture to 8 (de-fix note 12) ; # L-Shift+0 Set Max Showable texture to 255 (fix note 12) ; # H Refresh MDATR Heights (useful when you move an object) (fix note 11) ; # Y Set Perspective as default (fix note 5) ; # T Set the Camera to catch all the object on the screen (w/a note 13) then you'll be ready to press Insert/F6 ; # DO NOT HAVE AN OBJECT SELECTED WHEN USING THOSE SHORTCUTS (MW1-7) ; # MouseWheel+1 move cursor x rotation ; # MouseWheel+2 move cursor y rotation ; # MouseWheel+3 move cursor z rotation ; # MouseWheel+4 move cursor height base (1x) ; # MouseWheel+5 move cursor height base (0.5x) ; # MouseWheel+6 move cursor height base (0.05x) ; # MouseWheel+7 move cursor ambience scale (1x) ; # MouseWheel+Q move selected object height base (1x) ; # MouseWheel+9 move selected object x position (1x) (+asyncronous) ; # MouseWheel+0 move selected object y position (1x) (+asyncronous) ; # MW+RSHIFT+9|0 as above but *10x (+asyncronous) ; # MW+RCONTROL+9|0 as above but *100x (+asyncronous) ; # MouseLeft Insert Objects ; # MouseRight Move camera (it could require CTRL too) ; # SPACE Start move/selected animation in Object/Effect/Fly CB ; # ESC Stop animation in Effect/Fly CB [config] ; ### CONFIG OPTIONS VIEW_CHAR_OUTPUT_BY_DEFAULT = 1 VIEW_SHADOW_OUTPUT_BY_DEFAULT = 1 VIEW_WATER_OUTPUT_BY_DEFAULT = 1 ; WINDOW_HEIGHT_SIZE = 1080 ; WINDOW_WIDTH_SIZE = 1920 WINDOW_FOV_SIZE = 45 ; #100 = 1px (minimal px movement when pressing WASD) WASD_MINIMAL_MOVE = 100 ; came back from where you were before pressing Insert/F6 NO_GOTO_AFTER_INSERT = 1 ; disable MAI dumps when saving atlas and/or pressing Insert/F6 NOMAI_ATLAS_DUMP = 1 ; disable minimap.dds alpha saving and enable compression NOMINIMAP_RAWALPHA = 1 ; enable .mdatr height collision loading when moving on buildings or adjusting terrain DETECT_MDATR_HEIGHT = 1 ; disable fog when loading maps NOFOG_ONMAPLOAD = 1 ; refresh all checkbox configurations when loading maps 'n stuff REFRESHALL_ONUPDATEUI = 0 ; set a default mapname prefix when creating new maps ("" to disable) NEW_MAP_MAPNAME_PREFIX = "metin2_map_" ; display a default textureset when creating new maps ("" to disable) ; note: it loads the filepath if exists, otherwise it will create an empty textureset file NEWMAP_TEXTURESETLOADPATH = "textureset\metin2_a1.txt" ; create a default textureset as "textureset/{mapname}.txt" ; note: this option is not considered if NEWMAP_TEXTURESETLOADPATH is not empty. [before v24] ; note: this option is not considered if the TextureSet path input is not empty when creating a new map [since v24] NEWMAP_TEXTURESETSAVEASMAPNAME = 1 ; remove the weird attr flags from the generated server_attr SERVERATTR_REMOVE_WEIRD_FLAGS = 1 ; show diffuse lighting to object VIEW_OBJECT_LIGHTING = 1 ; path of mob_proto used for regen MOB_PROTO_PATH = "locale/ymir/mob_proto" ; select monster area info checkbox at startup VIEW_MONSTER_AREA_INFO = 0 ; brush cursor / object selection color RGB float between 0.0 to 1.0 (default: green -> 0 1 0) RENDER_CURSOR_COLOR_R = 0.0 RENDER_CURSOR_COLOR_G = 1.0 RENDER_CURSOR_COLOR_B = 0.0 Download: [Hidden Content] How To Map: This release will not cover this part. Look at CryPrime`s tutorials to understand how to do it. About the ServerAttr Generator: (since v14) This is a beta function but it should work fine. I tested it on gm_guild_build (1x1), metin2_map_a1 (4x5), metin2_map_trent (2x2), metin2_n_snowm_01 (6x6) and the result was the same as the blackyuko map editor. (I use a different lzo version and I clean deprecated and useless flags, so the size is different from this last one but the "final image" will be the same; using game_test to fix his server_attr will let mine and his perfectly equal byte per byte) I also give you the source code of my server_attr generator function. CLICK A server_attr file is based on all the attr.atr files merged into a one raw RGBA image and each one scaled from 256x256 to 512x512. After that, the image will be splitted into sectors of 128x128 px and each one compressed using lzo compression. The server_attr header is composed by the size of the map*4. (e.g. a 4x4 will have a 16x16 size with 256 sectors inside) (gj ymir CLICK) An uncompressed server_attr sector is just like this: CLICK (the sub 4 byte header is the size returned by the LzoCompress which indicates how much the compressed sector data are large) Each attr.atr is just like this: CLICK (the header is composed of 6 byte in total: 3 WORDs respectively for version, width and height; they are always 2634, 1, 1 so don't bother about it) A single attr.atr scaled from 256x256 to 512x512 will be just like this: CLICK You can use the game_test (from source) to perform few tasks like: Create a server_attr from a .mcd file (I won't suggest it) a <collision data filename> <map directory> Regenerate an old server_attr to server_attr.new using the current lzo compression and cleaning useless flag CLICK c <filename> Other stuff such as b to create a character instance or q to quit About the SkyBox Bottom pic fix: (since v21) Both metin2launch.exe and worldeditor.exe should be edited to see the bottom pic of the skybox. Ymir messed up the code wrongly flipping the bottom image. Open ./Srcs/Client/EterLib/SkyBox.cpp and replace: ////// Face 5: BOTTOM v3QuadPoints[0] = D3DXVECTOR3(1.0f, -1.0f, -1.0f); v3QuadPoints[1] = D3DXVECTOR3(1.0f, 1.0f, -1.0f); v3QuadPoints[2] = D3DXVECTOR3(-1.0f, -1.0f, -1.0f); v3QuadPoints[3] = D3DXVECTOR3(-1.0f, 1.0f, -1.0f); with: ////// Face 5: BOTTOM v3QuadPoints[0] = D3DXVECTOR3(1.0f, 1.0f, -1.0f); v3QuadPoints[1] = D3DXVECTOR3(1.0f, -1.0f, -1.0f); v3QuadPoints[2] = D3DXVECTOR3(-1.0f, 1.0f, -1.0f); v3QuadPoints[3] = D3DXVECTOR3(-1.0f, -1.0f, -1.0f); then recompile. Credits:
    1 point
  16. Download Alternative download links → Mega or Github Hello everyone , i am happy to announce you the release of a simple project that creates a random daily quest , with values you choose to give on MAX_HP etc . Resets on daily basis
    1 point
  17. Download Alternative download links → G-Drive Hello! I was searching for it back in the days but i never found it, so i share it with you. Gif about it:
    1 point
  18. Download Center Github or M2DL Heyo, this is something i did a while ago, perhaps it will be of use for some. [Hidden Content]
    1 point
  19. Hello, my name is Blazer, today I'm sharing with you a SuperPack of Weapons and Items, including exclusive weapons from MuOnline, League of legends and others like M16, Kitchen Pot, I hope you like it and enjoy it a lot, the pack is ready just play inside the item.eix epk and place the item list and item proto that I already made available in the download. VirusTotal > [Hidden Content] Download > [Hidden Content] M2DL > [Hidden Content] Soon I posted another pack with + 200 armors !
    1 point
  20. M2 Download Center Download Here ( Internal ) Hi here's my collection of 2010-11 weapons+it's icons dl: [Hidden Content] vt: [Hidden Content] PS: you can make your own item_list parts *-*
    1 point
  21. Download Metin2 Download or Mega and VirusTotal Maybe you will like to change the classic portal with this : This is the model without animation, i will make an update with animation next days.
    1 point
  22. 1 point
  23. Hello community, The values associated with movespeed are BYTE (255) by default, in this short guide I'll teach you how to change them to short (65535). Step by Step [Hidden Content]
    1 point
  24. Download Metin2 Download Hey, I will keep this short and simple. I had been playing around in the last days with exporting GR2 to a format that you can use in other software. Everything I found did not include skeleton / animation export. You can do stuff like this with it: [Hidden Content] Usage: Just drag and drop all gr2 files you want to export as an fbx file. Keep follwing in mind: Animations need a skeleton, always include one, if you are after the animation just put the lvl 1 armor of the class or the base model of the monster into it If you are selecting multiple files to drag on it select them with CTRL and select the file with the skeleton last This was basically created as POC, no fancy quality of life here Trees and collision files are not supported If you put the Textures to the correct D:\ymir work path they will be converted to PNG and put into the working folder too Credit for the base library that does most of the heavy lifting goes to: [Hidden Content] Download [Hidden Content]
    1 point
  25. Hello community, I decided to create a mini function in python for my server that adds the information if the player can drop or not on mobs and stones. [Hidden Content]
    1 point
  26. Emoji in textline broken Fixed [Hidden Content]
    1 point
  27. M2 Download Center Download Here ( Internal ) Hi, I want to share a new "advanced" texture for manu today. I'm not a developer, I just changed the texture and I believe it's nice because I wanted to.
    1 point
  28. M2 Download Center Download Here ( Internal ) V4 (ZED) V3 (MALI61) (MAX 2) V2 (KEN) V1 (KORAY)
    1 point
  29. M2 Download Center Download Here ( Internal ) Hi everyone, In this thread I will explain all console commands in the client: exit - Force close the client mvol - Change the music volume between 0 - 10 svol - Change the sound volume between 0 - 10 snds - Change the volume of the interactive sounds (mobs, hit etc...) between 0 - 200 asnds - Change the volume of the ambience between 0 - 200 mspd - Change the moving speed between 0 - 1100 pwd - Show the current folder path (D:ymir work) ls - Show the folders in D:ymir work shadow - Change the shadow level between 0 - 5 splat - Set the rendering distance between the character and the ambience 0 - ∞ distance - Change the view distance between 0 - 4 bgloading - This function is disabled in the binary! transtree - Enable or disable the transparency of the trees 0 - 1 cd - CD to directory, like in bat files (cd ..) up - Go up in the folder structure (D:ymir work) lsd - List all directories on the partition lsf - List all files on the partition lse - Show the path of the effects (D:ymir workeffect) collision - highlight the objects, monsters, npcs, players 0 - 1 colli - Equal with the collision function without argument, turn on/off the highlighting disconnect - Unfinished function! autorot - Set the rotation moving speed of the camera while pressing the A/D keys 0 - ∞ pickc - Show char informations, isRegistered, isAlive, isDead infoc - Information of another thing, usage: infoc <VID> regchre - Register new effect on the char, usage: regchre <effectType> and <effectFilename> setchra - Set character effect, usage: setchra <effectType> <Visibility 0 or 1> emoticon - Set emotion effect over the character, usage: emotion <number of the emoticon> perfinfo - Show performance informations (?) reload_locale - Reload the locale re - Reload uiGuild and uiInventory cooltime - Disable or enable the skills cooltime hidecursor - Hide the cursor showcursor - Show the cursor warp - Warp to x-y position web - Pop out a web browser hideui - Hide the user interface showui - Show the user interface setcspd - Change the camera moving speed 0 - ∞ savecmr - Export the current camera settings to the client folder, usage: savecmr <filename> loadcmr - Import camera settings, usage: loadcmr <filename in the client folder> setdefcmr - Set to default the camera settings setsight - Change the sight 0 - 100 setcombotype - Set the level of the combo, the server will kick you after few seconds because of combo hack check trans - Change the empire language converting, you can understand all empires without a ring 0 - 1 Rendering options: setrmadd setrmmod setrmaddrgb setrmmodrgb setspec restorerm If you have any question or suggestion please just reply to this topic. Kind Regards, Sanchez
    1 point
  30. M2 Download Center Download Here ( Internal ) Hi there Devs, I have published a tutorial yesterday on a Hungarian forum, and I decided to share it here, too. So... I chose int type for the level variables (originally its unsigned char) because: its more than enough maximum level 2147483647 the damage done by the characters (and much more thing) is calculated via they levels, and the type of this variables is int This is why I recommend to use int type game/src char.cpp Search this: void CHARACTER::SetLevel(BYTE level) Then replace to this: void CHARACTER::SetLevel(int level) char.h Search this: void SetLevel(BYTE level); Then replace to this: void SetLevel(int level); Then search: BYTE level; (its under this: typedef struct character_point) And replace to this: int level; party.cpp Search this one: void CParty::P2PSetMemberLevel(DWORD pid, BYTE level) Then replace to this: void CParty::P2PSetMemberLevel(DWORD pid, int level) Then replace this: BYTE CParty::GetMemberMaxLevel() { BYTE bMax = 0; To this: int CParty::GetMemberMaxLevel() { int bMax = 0; Find this one: BYTE CParty::GetMemberMinLevel() { BYTE bMin = PLAYER_MAX_LEVEL_CONST; And replace to this: int CParty::GetMemberMinLevel() { int bMin = PLAYER_MAX_LEVEL_CONST; And then this: void CParty::RequestSetMemberLevel(DWORD pid, BYTE level) To this: void CParty::RequestSetMemberLevel(DWORD pid, int level) party.h Search this: BYTE bLevel; (its under typedef struct SMember) And replace to this: int bLevel; Then this ones: BYTE GetMemberMaxLevel(); BYTE GetMemberMinLevel(); To this: int GetMemberMaxLevel(); int GetMemberMinLevel(); And these: void RequestSetMemberLevel(DWORD pid, BYTE level); void P2PSetMemberLevel(DWORD pid, BYTE level); To: void RequestSetMemberLevel(DWORD pid, int level); void P2PSetMemberLevel(DWORD pid, int level); char_battle.cpp Find: struct FPartyTotaler { int total; And replace to: struct FPartyTotaler { long total; And this: struct FPartyDistributor { int total; LPCHARACTER c; int x, y; DWORD _iExp; int m_iMode; int m_iMemberCount; FPartyDistributor(LPCHARACTER center, int member_count, int total, DWORD iExp, int iMode) To this: struct FPartyDistributor { long total; LPCHARACTER c; int x, y; DWORD _iExp; int m_iMode; int m_iMemberCount; FPartyDistributor(LPCHARACTER center, int member_count, long total, DWORD iExp, int iMode) config.h Find this: extern BYTE PK_PROTECT_LEVEL; And replace to this: extern int PK_PROTECT_LEVEL; locale_service.cpp Change: BYTE PK_PROTECT_LEVEL To this: int PK_PROTECT_LEVEL constants.cpp Well, here you should decide how much is the maximum level you want. You should fill these tables with as much records, as the maximum level. (e.g if you want to have maximum level 300, you need to put 300 records to these tables) const DWORD exp_table_euckr[PLAYER_EXP_TABLE_MAX + 1] const DWORD exp_table_common[PLAYER_EXP_TABLE_MAX + 1] const DWORD exp_table_newcibn[PLAYER_EXP_TABLE_MAX + 1 ] const DWORD party_exp_distribute_table[PLAYER_MAX_LEVEL_CONST + 1] const int aiExpLossPercents[PLAYER_EXP_TABLE_MAX + 1] log.h Edit this: void LoginLog(bool isLogin, DWORD dwAccountID, DWORD dwPID, BYTE bLevel, BYTE bJob, DWORD dwPlayTime); To this: void LoginLog(bool isLogin, DWORD dwAccountID, DWORD dwPID, int bLevel, BYTE bJob, DWORD dwPlayTime); log.cpp Replace this: void LogManager::LoginLog(bool isLogin, DWORD dwAccountID, DWORD dwPID, BYTE bLevel, BYTE bJob, DWORD dwPlayTime) To this: void LogManager::LoginLog(bool isLogin, DWORD dwAccountID, DWORD dwPID, int bLevel, BYTE bJob, DWORD dwPlayTime) guild.h Replace this: typedef struct SGuildMemberPacketData { DWORD pid; BYTE grade; BYTE is_general; BYTE job; BYTE level; DWORD offer; BYTE name_flag; char name[CHARACTER_NAME_MAX_LEN+1]; } TGuildMemberPacketData; To this: typedef struct SGuildMemberPacketData { DWORD pid; BYTE byGrade; BYTE byIsGeneral; BYTE byJob; int byLevel; DWORD dwOffer; BYTE byNameFlag; } TGuildMemberPacketData; Then this: void ChangeMemberData(DWORD pid, DWORD offer, BYTE level, BYTE grade); To this: void ChangeMemberData(DWORD pid, DWORD offer, int level, BYTE grade); Then SGuildMember(DWORD pid, BYTE grade, BYTE is_general, BYTE job, BYTE level, DWORD offer_exp, char* name); To this: SGuildMember(DWORD pid, BYTE grade, BYTE is_general, BYTE job, int level, DWORD offer_exp, char* name); And this: DWORD pid; // player Ĺ×ŔĚşíŔÇ id; primary key BYTE grade; // ±ćµĺ»óŔÇ ÇĂ·ąŔĚľîŔÇ °č±Ţ 1 to 15 (1ŔĚ ÂŻ) BYTE is_general; BYTE job; BYTE level; DWORD offer_exp; // °řÇĺÇŃ °ćÇčġ BYTE _dummy; To this: DWORD pid; // player Ĺ×ŔĚşíŔÇ id; primary key BYTE grade; // ±ćµĺ»óŔÇ ÇĂ·ąŔĚľîŔÇ °č±Ţ 1 to 15 (1ŔĚ ÂŻ) BYTE is_general; BYTE job; int level; DWORD offer_exp; // °řÇĺÇŃ °ćÇčġ BYTE _dummy; And then this: void LevelChange(DWORD pid, BYTE level); To this: void LevelChange(DWORD pid, int level); guild.cpp Find this: BYTE level = (BYTE)strtoul(row[4], (char**) NULL, 10); Replace to this: int level = (int)strtoul(row[4], (char**) NULL, 10); Then this: sys_log(0, "GUILD: AddMember PID %u, grade %u, job %u, level %u, offer %u, name %s ptr %p", To this: sys_log(0, "GUILD: AddMember PID %u, grade %u, job %u, level %d, offer %u, name %s ptr %p", Then replace the whole function: void CGuild::ChangeMemberData(DWORD pid, DWORD offer, BYTE level, BYTE grade) To this: void CGuild::ChangeMemberData(DWORD pid, DWORD offer, int level, BYTE grade) { TGuildMemberContainer::iterator cit = m_member.find(pid); if (cit == m_member.end()) return; cit->second.offer_exp = offer; cit->second.level = level; cit->second.grade = grade; cit->second._dummy = 0; TPacketGCGuild pack; TGuildMemberPacketData mbData; pack.header = HEADER_GC_GUILD; pack.subheader = GUILD_SUBHEADER_GC_LIST; pack.size = sizeof(TPacketGCGuild); pack.size += sizeof(TGuildMemberPacketData); for (TGuildMemberOnlineContainer::iterator it = m_memberOnline.begin(); it != m_memberOnline.end(); ++it) { LPDESC d = (*it)->GetDesc(); if (d) { TEMP_BUFFER buf; buf.write(&pack, sizeof(pack)); mbData.byNameFlag = 0; mbData.byGrade = cit->second.grade; mbData.byIsGeneral = cit->second.is_general; mbData.byJob = cit->second.job; mbData.byLevel = cit->second.level; mbData.dwOffer = cit->second.offer_exp; mbData.pid = cit->second.pid; buf.write(&mbData, sizeof(TGuildMemberPacketData)); d->Packet(buf.read_peek(), buf.size()); } } } And replace this function too: void CGuild::LevelChange(DWORD pid, BYTE level) To this: void CGuild::LevelChange(DWORD pid, int level) { TGuildMemberContainer::iterator cit = m_member.find(pid); if (cit == m_member.end()) return; cit->second.level = level; TPacketGuildChangeMemberData gd_guild; gd_guild.guild_id = GetID(); gd_guild.pid = pid; gd_guild.offer = cit->second.offer_exp; gd_guild.grade = cit->second.grade; gd_guild.level = level; db_clientdesc->DBPacket(HEADER_GD_GUILD_CHANGE_MEMBER_DATA, 0, &gd_guild, sizeof(gd_guild)); TPacketGCGuild pack; TGuildMemberPacketData mbData; pack.header = HEADER_GC_GUILD; pack.subheader = GUILD_SUBHEADER_GC_LIST; pack.size = sizeof(TPacketGCGuild); pack.size += sizeof(TGuildMemberPacketData); cit->second._dummy = 0; for (TGuildMemberOnlineContainer::iterator it = m_memberOnline.begin(); it != m_memberOnline.end(); ++it) { LPDESC d = (*it)->GetDesc(); if (d) { TEMP_BUFFER buf; buf.write(&pack, sizeof(pack)); mbData.byNameFlag = 0; mbData.byGrade = cit->second.grade; mbData.byIsGeneral = cit->second.is_general; mbData.byJob = cit->second.job; mbData.byLevel = cit->second.level; mbData.dwOffer = cit->second.offer_exp; mbData.pid = cit->second.pid; buf.write(&mbData, sizeof(TGuildMemberPacketData)); d->Packet(buf.read_peek(), buf.size()); } } } Then this function: bool CGuild::OfferExp(LPCHARACTER ch, int amount) To this: bool CGuild::OfferExp(LPCHARACTER ch, int amount) { TGuildMemberContainer::iterator cit = m_member.find(ch->GetPlayerID()); if (cit == m_member.end()) return false; if (m_data.exp+amount < m_data.exp) return false; if (amount < 0) return false; if (ch->GetExp() < (DWORD) amount) { ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<±ćµĺ> Á¦°řÇĎ°íŔÚ ÇĎ´Â °ćÇčġ°ˇ ł˛Ŕş °ćÇčġş¸´Ů ¸ą˝Ŕ´Ď´Ů.")); return false; } if (ch->GetExp() - (DWORD) amount > ch->GetExp()) { sys_err("Wrong guild offer amount %d by %s[%u]", amount, ch->GetName(), ch->GetPlayerID()); return false; } ch->PointChange(POINT_EXP, -amount); TPacketGuildExpUpdate guild_exp; guild_exp.guild_id = GetID(); guild_exp.amount = amount / 100; db_clientdesc->DBPacket(HEADER_GD_GUILD_EXP_UPDATE, 0, &guild_exp, sizeof(guild_exp)); GuildPointChange(POINT_EXP, amount / 100, true); cit->second.offer_exp += amount / 100; cit->second._dummy = 0; TPacketGCGuild pack; TGuildMemberPacketData mbData; pack.header = HEADER_GC_GUILD; pack.subheader = GUILD_SUBHEADER_GC_LIST; pack.size = sizeof(TPacketGCGuild); pack.size += sizeof(TGuildMemberPacketData); for (TGuildMemberOnlineContainer::iterator it = m_memberOnline.begin(); it != m_memberOnline.end(); ++it) { LPDESC d = (*it)->GetDesc(); if (d) { TEMP_BUFFER buf; buf.write(&pack, sizeof(pack)); mbData.byNameFlag = 0; mbData.byGrade = cit->second.grade; mbData.byIsGeneral = cit->second.is_general; mbData.byJob = cit->second.job; mbData.byLevel = cit->second.level; mbData.dwOffer = cit->second.offer_exp; mbData.pid = cit->second.pid; buf.write(&mbData, sizeof(TGuildMemberPacketData)); d->Packet(buf.read_peek(), buf.size()); } } SaveMember(ch->GetPlayerID()); TPacketGuildChangeMemberData gd_guild; gd_guild.guild_id = GetID(); gd_guild.pid = ch->GetPlayerID(); gd_guild.offer = cit->second.offer_exp; gd_guild.level = ch->GetLevel(); gd_guild.grade = cit->second.grade; db_clientdesc->DBPacket(HEADER_GD_GUILD_CHANGE_MEMBER_DATA, 0, &gd_guild, sizeof(gd_guild)); return true; } And this function: void CGuild::SendListPacket(LPCHARACTER ch) To this: void CGuild::SendListPacket(LPCHARACTER ch) { /* List Packet Header Count (byte) [ ... name_flag 1 - Ŕ̸§Ŕ» ş¸ł»´ŔłÄ ľČş¸ł»´ŔłÄ name CHARACTER_NAME_MAX_LEN+1 ] * Count */ LPDESC d; if (!(d=ch->GetDesc())) return; TPacketGCGuild pack; pack.header = HEADER_GC_GUILD; pack.size = sizeof(TPacketGCGuild); pack.subheader = GUILD_SUBHEADER_GC_LIST; pack.size += sizeof(TGuildMemberPacketData) * m_member.size(); pack.size += (CHARACTER_NAME_MAX_LEN + 1) * m_member.size(); TEMP_BUFFER buf; TGuildMemberPacketData mbData; buf.write(&pack,sizeof(pack)); char c[CHARACTER_NAME_MAX_LEN+1]; for (TGuildMemberContainer::iterator it = m_member.begin(); it != m_member.end(); ++it) { it->second._dummy = 1; mbData.byNameFlag = 1; mbData.byGrade = it->second.grade; mbData.byIsGeneral = it->second.is_general; mbData.byJob = it->second.job; mbData.byLevel = it->second.level; mbData.dwOffer = it->second.offer_exp; mbData.pid = it->second.pid; buf.write(&mbData, sizeof(TGuildMemberPacketData)); strlcpy(c, it->second.name.c_str(), MIN(sizeof(c), it->second.name.length() + 1)); buf.write(c, CHARACTER_NAME_MAX_LEN+1 ); if ( test_server ) sys_log(0 ,"name %s job %d ", it->second.name.c_str(), it->second.job ); } d->Packet(buf.read_peek(), buf.size()); for (TGuildMemberOnlineContainer::iterator it = m_memberOnline.begin(); it != m_memberOnline.end(); ++it) { SendLoginPacket(ch, *it); } for (TGuildMemberP2POnlineContainer::iterator it = m_memberP2POnline.begin(); it != m_memberP2POnline.end(); ++it) { SendLoginPacket(ch, *it); } } Then this function: void CGuild::SendListOneToAll(DWORD pid) To this: void CGuild::SendListOneToAll(DWORD pid) { TPacketGCGuild pack; pack.header = HEADER_GC_GUILD; pack.size = sizeof(TPacketGCGuild); pack.subheader = GUILD_SUBHEADER_GC_LIST; pack.size += sizeof(TGuildMemberPacketData); TGuildMemberPacketData mbData; char c[CHARACTER_NAME_MAX_LEN+1]; memset(c, 0, sizeof(c)); TGuildMemberContainer::iterator cit = m_member.find(pid); if (cit == m_member.end()) return; for (TGuildMemberOnlineContainer::iterator it = m_memberOnline.begin(); it!= m_memberOnline.end(); ++it) { LPDESC d = (*it)->GetDesc(); if (!d) continue; TEMP_BUFFER buf; buf.write(&pack, sizeof(pack)); cit->second._dummy = 1; mbData.byNameFlag = 1; mbData.byGrade = cit->second.grade; mbData.byIsGeneral = cit->second.is_general; mbData.byJob = cit->second.job; mbData.byLevel = cit->second.level; mbData.dwOffer = cit->second.offer_exp; mbData.pid = cit->second.pid; //buf.write(&(cit->second), sizeof(DWORD) * 3 +1); buf.write(&mbData, sizeof(TGuildMemberPacketData)); buf.write(cit->second.name.c_str(), cit->second.name.length()); buf.write(c, CHARACTER_NAME_MAX_LEN + 1 - cit->second.name.length()); d->Packet(buf.read_peek(), buf.size()); } } Then find this: SGuildMember::SGuildMember(DWORD pid, BYTE grade, BYTE is_general, BYTE job, BYTE level, DWORD offer_exp, char* name) And replace to this: SGuildMember::SGuildMember(DWORD pid, BYTE grade, BYTE is_general, BYTE job, int level, DWORD offer_exp, char* name) common tables.h Find this: BYTE byLevel; Replace to this: int byLevel; Then this: BYTE level; To this: int level; And this: BYTE level; To this: int level; Then this: BYTE bLevel; (under typedef struct SPacketPartySetMemberLevel) To this: int bLevel; And then this: BYTE bLevel; (under typedef struct SPacketDGGuildMember) To this: int bLevel; lenght.h Then here set the maximum level: PLAYER_EXP_TABLE_MAX = 120, PLAYER_MAX_LEVEL_CONST = 120, db/src ClientManager.h Find this: struct TPartyInfo { BYTE bRole; BYTE bLevel; Replace to this: struct TPartyInfo { BYTE bRole; int bLevel; ClientManager.cpp Search this: pkPeer->Encode(&it_member->second.bLevel, sizeof(BYTE)); (its in the void CClientManager::SendPartyOnSetup(CPeer* pkPeer) function) and replace with this: pkPeer->Encode(&it_member->second.bLevel, sizeof(int)); ClientManagerPlayer.cpp Find this: "PLAYER_DELETE FAILED LEVEL %u >= DELETE LIMIT %d" Then replace to this: "PLAYER_DELETE FAILED LEVEL %d >= DELETE LIMIT %d" And find this: "PLAYER_DELETE FAILED LEVEL %u >= DELETE LIMIT %d" You will find it 2 times, replace both to this: "PLAYER_DELETE FAILED LEVEL %d >= DELETE LIMIT %d" client packet.h Find this: BYTE byLevel; Then replace to this: int byLevel; And this: BYTE byLevel; To this: int byLevel; PythonGuild.h Find this: BYTE byLevel; And replace to this: int byLevel; And finally, edit the level colum in the player table in the player database. Set its type from tinyint to smallint (or int, it depends how high is the maximum level) and expand its size to 3 (or higher). And then, here you are I also made a video while I made this, if you have free 42 minute, maybe worth to watch it (if you do, you are my guest for a beer (or something liquid :D)) [Hidden Content] If you have question(s)/problem(s)/remark(s), feel free to post it here, or send me a PM. Have a nice day, ~masodikbela
    1 point
  31. You too? You want to create a server for our favorite MMORPG?! You will be able to make your dream come true ! This guide is exclusively compatible with Metin2 Project. Are you ready? Gooo! Install the Virtual Machine Spoiler Prerequisites Download and install the latest version of VirtualBox Download the latest version of the Metin2 Project Virtual Machine Storage: 25GB RAM: 2GB Introduction VirtualBox is virtualization software. A Metin2 Server runs mostly on an operating system called FreeBSD. It's therefore necessary to virtualize a second computer within yours to operate your Metin2 Project Server. It's the virtualization of a second operating system that consumes resources in processor, RAM and storage on the host system, your computer. If you are using a dedicated server, you will install FreeBSD as the main operating system without using Windows! The Metin2 Project Virtual Machine is ready to use, it's already preconfigured to be usable, even for a neophyte! Ready? Gooo! You need to open the « OVA » file by clicking on it, like to open your favorite software. The extension is recognized automatically by Windows and is associated with VirtualBox. You must click on the button « IMPORT » and let VirtualBox work, it imports your Metin2 Project Virtual Machine for your greatest happiness ! It has successfully imported your Metin2 Project Virtual Machine! Congratulations ! Configure the Virtual Machine Spoiler Introduction By default, your Metin2 Project Virtual Machine is partitioned into a local network within your computer. This manipulation consists of making your router and your virtual machine communicate and allowing it access to the Internet network. Ready? Gooo! You must click on the name of your virtual machine then click on « CONFIGURATION ». A part that is very important, this is where you give your virtual machine the power to connect to the world and control all of us ! Click on « NETWORK » and choose « BRIDGED ADAPTER » then select the primary network card that your computer uses, « WIFI » or « ETHERNET ». You also have the possibility to modify the various parameters of your virtual machine, such as the RAM, the power of the processor... Click the « OK » to save the changes. Manage the Virtual Machine Spoiler Introduction It's important to know how to manage a virtual machine, starting it and shutting it down are actions that you are likely to perform regularly when managing your Metin2 Project Server. Ready? Gooo! All you have to do is start your Metin2 Project Virtual Machine ! For that, it's very simple you have to right click on the name of your virtual machine and it will offer you several choices including: « START » or « CLOSE » when you want to turn it off. When it has finished starting, you must have this on your screen, you must identify yourself using the identifiers that are available on the topic where you downloaded Metin2 Project, when entering the password it will not be displayed no, this is absolutely normal. So here you have the main interface between your computer and your virtual machine, it's a bit like your second screen! It must imperatively remain open otherwise it would turn off your computer . Trick It's possible to restart your Metin2 Project Virtual Machine using a command! When you are connected and identified on the VirtualBox interface or using PuTTY, all you have to do is enter the following command then validate with the « ENTER »key on your keyboard: reboot Retrieve the IP Address Spoiler Introduction An IP address is like your postal address, if we don't know it, we can't know where you are. An IP address represents the postal address, the location of your Metin2 Project Virtual Machine on your network. Ready? Gooo! You will retrieve the address of your virtual machine, it has an address, a home and it does not pay rent! This address, which is exclusively numeric is the IP address, it's specific to each computer, whether physical or virtual. You will be able to connect to the various tools to manage your Metin2 Project private server but also to connect to the game! For that, it's very simple you have to enter the following command in the VirtualBox interface: ifconfig In our example, the IP address of the virtual machine is: « 192.168.0.21 ». Use PuTTY Spoiler Prerequisites Download the latest version of PuTTY Introduction PuTTY is an SSH client, it allows you to connect to your FreeBSD Server in SSH. It's more or less similar to a remote control software like AnyDesk or TeamViewer except that it's used in command line! This saves you the uncomfortable interface of VirtualBox. PuTTY being much more ergonomic for copying and pasting commands... Ready? Gooo! Enter the IP address in the field: Host Name (or IP address) Enter the SSH port in the field: Port (Default: 22) Enter a name you want in the field: Saved Sessions Click on the « SAVE » button to save the connection parameters You must double click on the registered server of your choice to initiate a connection. PuTTY will ask you for the username and password of your FreeBSD user, this corresponds to the credentials used on your VirtualBox interface. It may also ask you to confirm the connection to the SSH Server and indicate a security problem, don't panic and click on « YES ». Use EterNexus Spoiler Prerequisites Download the latest version of EterNexus Download the Metin2 Project Client Introduction EterNexus is a software which will allow you to decompress and compress the « EIX » and « EPK » archives of the « PACK » folder of your Metin2 Project Client, these archives contain absolutely all the game data, images, texts, models, textures... Ready? Gooo! You have to extract the files from EterNexus and move them to the « PACK » directory of your Metin2 Project Client. You will find a folder with the same name of the archive that you unzipped in the directory where the archive is located. To unzip an archive: EterNexus will recreate a new archive with the same name of the folder and in the same location where the same directory is located. To compress an archive: Configure the Metin2 Project Client Spoiler Prerequisites Download and install the latest version of Notepad++ Download and install the latest version of WinRAR Introduction It's necessary to link your Metin2 Project Client to your Metin2 Project Server, for this we will enter the IP address of your server within the game client configuration. Ready? Gooo! You must first extract the Metin2 Project Client archive. In order to configure your Metin2 Project Client and link it to your Metin2 Project Virtual Machine, you must configure the IP address within your Metin2 Project Client. You must extract the archive « ROOT » and you will find a multitude of files there, the one that interests us is « SERVERINFO.PY », it contains all the information about your server, the IP address, the name, the port of access... At the beginning of this file, there is a list of sample servers to guide you through the changes. At the beginning of the file you must find the following block: SRV_LOCALHOST = { 'name':'LOCALHOST', 'host':'127.0.0.1', 'auth':11002, 'c1':13001, 'ids':'10', } You need to modify the line similar to: 'host':'XXX.XXX.XXX.XXX', You must replace « XXX.XXX.XXX.XXX » by the IP address of your Metin2 Project Virtual Machine then save the changes. After that, you simply need to compress the « ROOT » archive. This means that when you run the Metin2 Project Client, you will need to select the « LOCALHOST » server. Use Navicat Spoiler Prerequisites Download and install the latest version of Navicat Introduction Navicat is a graphical database management and development software suite, it will allow you to manage your databases and the data stored in them. Navicat is not limited to MySQL, it's also able to connect to other SQL Servers such as PostgreSQL, Oracle, SQLite, MariaDB... As part of Metin2 Project, we use MySQL, the database records and stores all data relating to your Metin2 Project Server, accounts, characters, inventories, state of quests... Ready? Gooo! To start the configuration of Navicat, you must click on « CONNECTION » then choose « MYSQL », MySQL is the engine of our database used in Metin2 Project. Logins are available on the topic where you have downloaded Metin2 Project. Enter the name you want in the field: Connection Name Enter the IP address in the field: Host Enter the MySQL port in the field: Port (Default: 3306) Enter the username of a public account in the field: User Name Enter the password associated with your user in the field: Password Check the box: Save password In order to ensure that the connection is established, you can click on the button: « TEST CONNECTION » if you have the message below, everything is good! It only remains to confirm by clicking twice on the buttons: « OK ». To connect to a MySQL Server, you must double click on the name of the previously added server. In the left part of Navicat, to see all the data of your Metin2 Project Server you must click on « TABLES ». To open a data table, also double click on it. Create an Account on Metin2 Project Spoiler Prerequisites Encrypt password Ready? Gooo! Creating an account on your Metin2 Project Server is easy, for that we will use Navicat to connect to the MySQL Server. We are going to modify the « ACCOUNT » table, it's located in the « ACCOUNT » database. To manually add an account from Navicat, you must click on the « + » at the bottom left and fill in the boxes, these fields are the most important, everything else is optional and will be filled in automatically with the default settings: ID: Do not fill, it fills automatically LOGIN: The username of the account we use to connect to the game client PASSWORD: This is the password, which you must first encrypt SOCIAL_ID: This is the code for deleting a character EMAIL: This is the email address of the account CREATE_TIME: Account creation date STATUS: Account status, « OK » or « BLOCK » if he should be banned SECURITYCODE: ? AVAILDT: ? MILEAGE: DC CASH: MD GOLD_EXPIRE: Double Drop Chance for Items SILVER_EXPIRE: 50% More experience SAFEBOX_EXPIRE: More storage space in the Warehouse AUTOLOOT_EXPIRE: A Hand that Automatically Picks Up Yangs FISH_MIND_EXPIRE: The chance of catching a Fish increases MARRIAGE_FAST_EXPIRE: Love points increase faster MONEY_DROP_RATE_EXPIRE: Double Chance of Yang Drop LAST_PLAY: Last login date This ensures that your passwords are not in the clear in your database, a measure of security and confidentiality. Finish by pressing the « ENTREE » key on your keyboard to confirm and save. Assign « GM » permissions Spoiler Introduction Adding permissions to a user involves a lot of responsibility, for this we will use Navicat to connect to the MySQL Server. We are going to modify the « GMLIST » table, it's located in the « COMMON » database. To manually add an account from Navicat, you must click on the « + » at the bottom left and fill in the boxes: MID: Do not fill, it fills automatically MACCOUNT: The account ID the one to use to connect with the game client MNAME: This is the name of the character, it must be strictly identical, if it's not yet existing, it does not matter, the important thing here is to choose a name that will be that of your character MCONTACTIP: The box is empty by default, however some explanations: this allows the rights to be assigned to an account according to the player's IP address, this prevents someone from connecting to the account to take advantage of the accesses, to be avoided if the player to a dynamic IP address MSERVERIP: The box is on « ALL » by default, however some explanations: this is in the case where you have several Metin2 servers running on the same FreeBSD Server, this allows you to assign access to a particular server, it requires adding the server IP in the « GMHOST » table MAUTHORITY: This is the level of access rights in play, you can check the access level of an order from the sources of Metin2 GOD: Limited access HIGH_WIZARD: Limited access WIZARD: Limited access LOW_BIZARD: Limited access IMPLEMENTOR: Full access Finish by pressing the « ENTREE » key on your keyboard to confirm and save. You have defined the accesses, you must reload them, two solutions: You have an account with an already existing GM character, you must write this in-game command and disconnect / reconnect the concerned account: « /RELOAD A ». You don't have any GM characters, you have to stop and restart the Metin2 Project Server with the Metin2 Project Shell Manager. At this stage, the server has not started, the next start of the Metin2 Project Server will suffice to update your character's accesses. Use WinSCP Spoiler Prerequisites Download and install the latest version of WinSCP Introduction WinSCP is a graphical SFTP client for Windows. It uses SSH and is open source. The purpose of this program is to enable secure copying of files between a local computer and a remote computer. You will use it to transfer files to it. With WinSCP you will be able to explore the content of your Metin2 Project Virtual Machine as if you were on your computer with Windows and its file explorer. You will find there the files of the FreeBSD operating system, the programs which have been installed, but also, most importantly, the files of our Metin2 Project Server. Ready? Gooo! When you open the program for the first time, it automatically offers you the connection manager: Enter the IP address in the field: Host name Enter the SSH port in the port number: Port number (Default: 22) Enter Username: root: in the field: Username Enter the password for: root: in the field: Password Click on the button: Save... Enter the name you want in the field: Save session as Check the box: Save password (not recommended) Click on the button: OK To initiate the connection, you must double click on the server you have registered. WinSCP will automatically connect with the username and password that have been registered. It may also ask you to confirm the connection to the SFTP Server and announce a security issue, don't panic, click « YES ». Start the Metin2 Project Server Spoiler Prerequisites Using Metin2 Project Shell Manager Introduction Metin2 Project comes with a powerful program, Metin2 Project Shell Manager. It allows you to manage your Metin2 Project Server with ease! Ready? Gooo! To invoke it, you need to run this command on PuTTY: cd /usr/m2_project && sh m2sh.sh You have a multitude of options available to you that allow you to manage Metin2 Project as simply as possible. Each time you run the above command, you must choose one of these options by entering it and then validating it with the « ENTER » key on your keyboard. Enter: 103 Ready? Gooo! Spoiler Introduction It's time for you to materialize in the virtual and wonderful world of Metin2 Project ! Enjoy the great and beautiful Metin2 Project adventure... Made With and
    1 point
  32. Download Center Minimap & Heightmap Converter So, i've been developing something, and i needed the minimaps and heightmap from metin2, and i was using the Map Converter tool that can be found here in the forum, but taking a screenshot of that tool (since it doesn't allow to export heightmap, only minimap), isn't the best of ways, so i made my own tool to do that, this took me a while, since i'm not a very experienced programmer... The tool is very simple to use (i believe), just move the whole map folder to where the python file is, and run the script and follow the instructions, it will also go with 2 maps already done, the final image will have the same name as the map folder name. Idk if anyone has done this, that release to the public the source code (Map converter tool creator didn't release source code i think), so if anyone needs the code or the tool, can use without any trouble, since this is also a backup for me, so i dont lose the tool xD It uses the python 3.10.5, and some libraries, so you will need to install them: PIL (pillow) Torchvision Numpy (i think this one already comes with python, not sure) OpenCV It's just .py files that you can look through the code, but either way, here's virus total scan of the .rar files [Hidden Content] [Hidden Content] The folders are only that big (8.31mb and 11.42mb) because both have 2 full map's folders on them, and one of them uses normal png, and the other uses 8bit png (that's why the 3.11mb difference) I did separate because idk, that's how i made them, and i guess i'm too lazy to combine them together lol Heightmap: [Hidden Content] Minimap: [Hidden Content]
    1 point
  33. everyone shares a code , here is official reversed code for pets and shops: [Hidden Content]
    1 point
  34. Download VirusTotal → Link Hello, as you know, many people have had difficulties because of "Sequence", which is one of the most disgusting codes of Metin2. Not many people use it, so I removed it completely. Finally, I share with you what needs to be done. So what do we gain by removing it? In fact, systems that should work correctly most of the time give errors due to the sequence. That's why things get more difficult. Even when there is no error, it creates a problem as if there is an error. They won't be anymore. After removing the sequence and if it's not your fault, these problems will no longer exist and you will never get a syserr like this: Process: SEQUENCE 74309000 mismatch 0x72 != 0x0 header 55 SYSERR: Nov 17 07:52:57 :: Process: SEQUENCE 65febc00 mismatch 0xe2 != 0xe header 57 SYSERR: Nov 17 07:52:57 :: Process: SEQUENCE_LOG [Nick]------------- [007 : 0x72] [007 : 0xf7] [007 : 0x6f] NOTE: Do not confuse this syserr with UNKNOWN PACKET HEADER error. Sorry for bad english. Source: me
    1 point
  35. M2 Download Center Download Here ( Internal ) Daily Event Winter will come in days so what do you think about daily(or in chosen day) event with Grinch?. Before Grinch spawn game will send 4 notices about time of spawn. After kill daily boss(Grinch in package with map) game will send announcement with info about player who made last hit and kill Grinch. Every participants on this map after kill Grinch will get VIP bonuses for chosen time. Every settings like spawn time, announcement time are easy configurable. If you want fix small bug with displaying time please change this line like bellow: change: ["ANNOUCEMENT_LINE_3"] = "TODAY! About %d:%d he will be on Daily Boss Map."; for: ["ANNOUCEMENT_LINE_3"] = "TODAY! About %02d:%02d he will be on Daily Boss Map."; Announcement and spawn conf: Time in quest dialogs are imported directly from settings in game. If you will set this event only in one day of week then Quest Scroll will hidden in other days. You can simple disable VIP bonuses if you want only drop reward. If you want it only in one day then simply change const value and choose own day. Download & Scan [Hidden Content] [Hidden Content]
    1 point
  36. M2 Download Center Download Here ( Internal ) Hello community. i had some free time so and i did this. is not something special but someone might want to use it. Download: Mega You put your database information on include/dbconfig. You put your client download link on index.php variable: $DownloadLink IF something not work good just report it here and i will fix it.
    1 point
  37. Download By Aslan I think the GIF is self-explanatory. Adding new changelogs is kept as simple as possible, is loaded from the locale/xx/ as txt and is therefore multilang-capable. Habs made it so that if the patchnote.txt is missing in the respective locale folder, he then reads it from the English, so always have one in the English locale inside or just adjust it in the Python file.
    1 point
  38. M2 Download Center Download Here ( Internal ) Hello, As said in the title, here are the Granny 2.11.8 Exporters for 3ds Max 2018. I'm still trying to find for Maya, but for the time being I only have this. Download: [Hidden Content] VirusTotal: [Hidden Content] The installation is really obvious as of I won't give any support, it's just drag and drop in the installation folder. I'll also don't provide any 3ds Max 2018 download link, as it's still available on Autodesk website, just buy it, use education account or crack it. This might also not be very useful for some 3D Artists since it needs the client to also have Granny 2.11.8 (normal clients use 2.4 and almost everyone already use 2.9, to upgrade to 2.11.8 is just upgrade the lib, header file and dll). Credits: Found it on some Arabic forum non-metin2 related.
    1 point
  39. M2 Download Center Download Here ( Internal ) Download And bell fan, more
    1 point
  40. Download Metin2 Download or Mega VirusTotal Link
    1 point
  41. 1 point
  42. M2 Download Center Download Here ( Internal ) Download
    1 point
  43. M2 Download Center Download Here ( Internal ) Download Password: fuckspanishdev Hi guys, what happen to me in these days i was thinking to post a one of exclusive design that was made for my server in 2018 so i never used it i hope it would help. Important: is just a PSD file not a code if someone like to code it would be great Preview: Download Link
    1 point
  44. M2 Download Center Download Here ( Internal ) This is my first new map i have created. You can use it as Trademap. Free feel to use. Important Please do not release this without my permissions elsewhere as it's only for metin2dev!
    1 point
  45. M2 Download Center Download Here ( Internal ) Hello togehter, today i want to share a small, but in my opinion, usefull security upgrade for your player password-hashes. The current default hash, which is used by the most of you (some exeptions might be out there) is the MD5 Hash. This hash might be not the best choice for hashing passwords in this modern days. This is why i thought about something to change there. And my solution for this is Argon2. This Method had won the Password Hashing Competition and this is why i had choosen this over bcrypt or scrypt. This tutorial isn't a 100% beginner firendly guide! Just follow my instructions if you got a little bit of c++ knowledge and know how to work with the source! Create the libargon2 Change the hash inner the game-core source (DEFAULT PASSWORD() MYSQL FUNC TUTORIAL) For now you just need to edit the account.account table and set the size for the password to 128 (Why 128? Db.h EArgon2::HASH_LENGTH = 64. 64 * 2 = 128) And you need to replace your hashes with the argon2 once. For this follow the link to the generation: [Hidden Content] Example config for the tutorial setup: Have fun
    1 point
  46. As the title says, here's the simple method how you can skip the video without waiting until is finished, like official did long time ago. Here're the constants value for virtual-key codes (hexadecimal values), right now these are by default: VK_LBUTTON 0x01 - Left mouse button VK_ESCAPE 0x1B - ESC key VK_SPACE 0x20 - SPACEBAR Srcs/Client/UserInterface/Locale_inc.h Srcs/Client/UserInterface/MovieMan.cpp [Hidden Content]
    1 point
  47. M2 Download Center Download Here ( Internal )
    1 point
  48. Put these two file on your extern/include/boost folder: [Hidden Content]
    1 point
  49. M2 Download Center Download Here ( Internal ) Hey Guys I want to share a site for SOMetin2 server edit while you were online. Download: Click Credits: * NyBu (Flying Men Development) * Ayaka * Wered $$ Sorry for my bad English. Kings Regards Wered $$.-
    1 point
  50. Updated on github with the 40k functions as well. (and also others used by me) [Hidden Content] Note: Also added some dumplist examples.
    1 point
×
×
  • 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.