Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation on 02/19/20 in all areas

  1. Hello friends, While I was adjusting my skills and doing some updates to them, I encoutered a funny bug I had never noticed. I asked my friends and tried some servers and they either had this bug or they had it "fixed" already. I didn't try the official but they surely patched it in 17.5NB. You will see that when you use this skill, two things can happen based on your server: Your character will walk toward the ennemy and launch the skill. The skill will hit the target but nothing will happen. No processing, no damage, no aggro, simply nothing. The skill will be effective only at point blank range. Screencap below. You will launch the skill as long as you have an attackable opponent targeted. That's the "fix" I talked about, which is more like a workaroundNB. Preview of the bug: [Hidden Content] (Thanks @Veltor88) This is an easy fix that probably anyone can come up with, but I would like to share it with you, let's make the game better for everyone. Open Server/char_battle.cpp and search for the following case in class CFuncShoot: case SKILL_YONGBI: { m_me->OnMove(true); } break; Delete the case. It simply makes you move to the target, launch the skill and that's it. Probably an unfinished piece of code that made it's way to the final game. Search for (in the same class): case SKILL_TUSOK: case SKILL_BIPABU: case SKILL_NOEJEON: case SKILL_GEOMPUNG: case SKILL_SANGONG: case SKILL_MAHWAN: case SKILL_PABEOB: And extend the check with: case SKILL_YONGBI: //Fix for Shooting Dragon Now your character will walk to the ennemy, launch the skill and deal damages as well as triggering the aggro and stuff like that. NB: The bug highlighted in the screecap was made and reproduced on the latest official client (as of February the 20th). A matching 17.5 skilltable (client->server) was also running at that time. The "work-around" I mentioned is surely happening if you have skill datas prior to the patch 17.5 as it was probably how the skill was back then and how it was intended to work. It might seem odd anyway and you might want to fix it. Also, you may encounter a "double-triggering" bug when launching the skill at point black. For those two cases, I forward you to this great post, giving you a fix. I don't know if I have this bug (and will provide you with all the necessary files if I happen to have it). I didn't do any checks on the clientside as I was simply trusting Ymir and using latest (supposedly working and tested) skill datas both serverside and clientside. Enjoy!
    4 points
  2. A shaman in a sexy outfit xD
    4 points
  3. 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:
    2 points
  4. M2 Download Center Download Here ( Internal ) Hi there devs, I made some new reload commands about 2 weeks ago and published a tutorial about it on our Hungarian forum (you may saw them in the samurai core) and today I had some time to make the translation. What can I reload now? refine_proto (this is the only one which is not mine, its @xP3NG3Rx's, and already public here, but I added it, because I think this package has to contain it ) command: /reload p shop_item table (npc's shops) command: /reload p item_attr && item_attr_rare table; command: /reload p etc_drop_item.txt, mob_drop_item.txt, special_item_group.txt; command: /reload drop group.txt, group_group.txt; command: /reload group regen.txt, npc.txt, boss.txt, stone.txt (only on the current map) command: /reload regen because of the new "reload regen" command, I had to write a new purge command that destroys all mobs, npcs, stones (and so on...) on the current map, so I added a new /p map command to the "/p" commands that are already exists (no, the "/p all" only destroys the mobs on the current sectree (current block)) also I had to create a new command that stops all the regens (and ofc. deletes them from the memory) on the current map, so I added a new "/free_regens" command (because why not ) Its only deletes the loaded regens, and prevents the mobs from respawning (its not necessary to use this before the /reload regen) Known bug Well its not a serious problem, but for some unknown reason, when I'm debugging the core on windows server (no, not debug mode, but vs 13's debugger) and I try to do /reload regen, the core starts to consume ~40% cpu, and doesn't want to do anything (so stops working, but doesn't crash). It has no affect on FreeBSD and release or debug mode (without visual studio's debugger) on windows. game/src cmd.cpp cmd_gm.cpp input_db.cpp shop_manager.cpp refine.cpp char_manager.cpp char_manager.h item_manager.h item_manager_read_tables.cpp mob_manager.h mob_manager.cpp char.cpp sectree_manager.cpp regen.h regen.cpp shop.h shop.cpp db/src ClientManager.cpp And finally let me wish you all good luck for the setup If you have further question(s), remark(s), or anything that you want to ask or suggest, feel free to post it here, or send it in PM. If you get error(s) please upload the affected (and edited) file to [Hidden Content] and link it in your post, to make my work easier and probably I will be able to help you only in one post, so please spare me from asking basic requests like "Could you upload...". Thank you Have a nice day, ~masodikbela
    2 points
  5. M2 Download Center Download Here ( Internal ) Here is the translation of locale_string.txt file in 14 languages Languages: cz de dk en es fr hu it nl pl pt ro ru tr Link: Download
    2 points
  6. This method is good for old compilers, but I would use regex right now, you've an example in a tool what i did some time ago. [Hidden Content] Should look like: [Hidden Content]
    2 points
  7. M2 Download Center Download Here ( Internal ) Hi everyone! So, after serveral days of searching a tool that could change the texture path of a .gr2 file, I found the tool(probably all of you know it, the texture changer by marv). After that I tried to change the texture paths of some gr2 models of a weapon, and guess what, it didn't work. I'm gonna reupload the file, because I didn't seen it on metin2dev, and I'm gonna teach you how to use it. First of all, I don't know about others, but for me it didn't work to change anything with this (I'm running windows 7 x64 bit). Some of guys told me that this "texture changer" works only on windows 7 x86 bit, so I reinstalled my windows(I really needed that tool), of course, it didn't work either way. So, go in Start and search cmd, and run it. After the cmd started you'll see a path right there C:\Users\Name (Instead of Name you'll have your username of computer administrator, or the account you're logged in), now that's the path where we can work with the tool. PAY ATTENTION!!! IF YOU START THE TOOL IN OTHER FOLDER INSTEAD OF C:\Users\Name THE TOOL WILL NOT WORK, AND YOU WILL NOT BE ABLE TO SAVE THE NEW MODEL. Exctract all the files from the archive(I'll post it below), and start Metin2TextureChanger.exe. Now click "Load" to choose a gr2 file you want to change texture path, BUT, the model name can't have spaces in name(devil sword.gr2 for example, it's wrong, the tool won't read it, and you'll not be able to save your new gr2 model), so if you want to change for example devil sword.gr2 you need to rename it into devil_sword.gr2 or devilsword.gr2 or any other name without spaces betwen. Where is "Neuer Texturpfad" we will chose the new path for texture, for example d:\ymir work\test\devil_sword_blue.dds , there you can choose any other path, but you can't modify "d:\ymir work" or you won't be able to see the weapon/armour in-game. Now we save the file wherever we want, it doesn't matter, this way must work for everybody. AGAIN, THIS TOOL WASN'T MADE BY ME. And I made this post because I've searched many days a tool that would work, but neither didn't work, and this tool didn't work for me either just when I used this method. So, this post is for guys who had the same problem like me (they had the tool, but couldn't save the new model) that's why I wanted to help them, and any other people who weren't been able to use it. And about the other tool I've found on this forum, the tool "made" by thunder-core, I didn't find that tool satisfying, it worked, but after the new model was made, I wasn't been able to import it in 3d max, or to convert the model from file format revision 7 to 6. So you were basicaly forced to upgrade your client to granny 2.9, and I found that inconvenient, because, I don't know about others, but I don't use source for binary, and because of that it's imposible to see the model in-game. And of course, the new model you've created, with the tool in attachement, is revision 7, so you need the new granny if you want to see it in-game, but you can use the converter from archive to convert from revision 7, to revision 6 (old), and you'll be able to see it in-game. If you already see it in-game, you don't need to use the converter. If you found this post helpful I'm glad I could help you.
    2 points
  8. M2 Download Center Download Here ( Advance Refine Systems ) Download Here ( Cheque System ) Download Here ( Soul Bind System ) Hello everyone ! I've been away from metin2 for about 6 months and i've get back from less then a month and made thoes systems , i've start selling them but i didn't sell it to anyone and i got bored from metin2 again so i'm going to release it and go off from metin2 for ever . about the Advance Refine System here some info: so download and have fun [Hidden Content]
    1 point
  9. M2 Download Center Download Here ( Internal ) Advanced Regen Editor I have worked in the past week on a new regen tool(made in C#-WPF) to make the life easier for the mappers/server owner between us. It is an advanced regen tool that includes all the basic functions + new ones such as: mob/group file viewer. Importing regen file. Remember information - Remember the last data entered such as direction, respawn time,count etc. Color Character by color(Mob-Red, Stone-Blue, Boss-turquoise, NPC-Belge, Group-Black). Add a character - Left click. Remove a character - right click on a character dot. Load MOB/Group information - select mob_names.txt/group.txt to view information on a data grid(shown on screen shots below). When choosing a group.txt make sure you have type field set on group. Ctrl Z Feature - Reverse action, that means that if you added a character it will be deleted and if you removed a character it will be added back. Separation of exported files - Files will be exported upon the type of the map character, if you had stone,boss and npc character then stone.txt,boss.txt and npc.txt will be generated. If you find any bugs, please reply here with the bug information in specific details. Please Like this thread if you find my tool useful! Ⓒ Metin2 Guild Wars. Version 1.0 Download Link: [Hidden Content] Update 06/10/2017: Zoom in/out feature has been added. View entities seperately feature has been added. Import regen bug has been fixed. Enjoy! Version 1.1 Download Link: [Hidden Content] Virustotal: [Hidden Content] Enjoy!!
    1 point
  10. M2 Download Center Download Here ( Internal ) When a player or monster is poisoned, a poisoning effect will appear in the life bar. The idea belongs to Whistlee from the Turkish forum. However, in Whistlee version this system does not work for monsters and has no connection with the source code, so the effect is visible only to us. I don't know if I can give a specific place where the original comes from, so I won't do it, but I put here github Whistlee's, where you can find the original code. GITHUB: [Hidden Content] Special thanks for helping me with this code for Intern,VegaS™ and HITRON. ////////// CLIENT GAME ////////// SOURCE BIN
    1 point
  11. M2 Download Center Download Here ( Internal ) I think the title should explain all. The system give way to set mob's drops via tables (Database) instead to use mob_drop_item.txt, common_drop_item.txt, drop_item_group.txt which can be buggy (easly, just a wrong space) without trace any error in your game expirience. WARNING : The System doens't disable the txts so you can use the txts and the tables without any problems. I have inserted "/reload d" command to reload the drop tables without restart channels. i will code a small tool in python to convert the txts to tables (i will be added to the repository). The drop chance by default is set to 1/1000 (so in table you should set it to 1000 to give 100% drop chance 'base' , it will change via the ymir's algorithm depend on the levels killer/victim). you can chance this scale to use 100 instead 1000 basically changing in lenght.h the value of DROP_SCALE_TABLE here you can find the repository. MySkype: live:ikarus.developer update: Added a small part to install only if you are using __SEND_TARGET_INFO__ to show the drop in the target board WARNING: i noticed some people think this system is a realtime database reading based system. i want explain it better , to make sure every body know how this system works. This system works using cache, it read the tables once on boot, then the db core setup all core during core boot using cache. Only if you want to reload (refreshing the cache) the db core will read again the tables and will send to every core the "update".
    1 point
  12. M2 Download Center Download Here ( Internal ) Download Here ( GitHub ) /reload c doesn't work properly for client-side. Even if you re-open client. Bug:
    1 point
  13. M2 Download Center Download Here ( Internal ) Hi there. While cleaning out "my closet", I found this thing I developed between 2014-2015 - maybe(?) - for my, at that moment, server. Since it's now closed, and I won't use it, I'm sharing it with you guys. Note: Didn't do the scrollbar, wasn't needed for me, so yeah. Now, let's start with opening your locale_game.txt and adding these lines: QUESTCATEGORY_0 Main Quests QUESTCATEGORY_1 Sub Quests QUESTCATEGORY_2 Collect Quests QUESTCATEGORY_3 Levelup Quests QUESTCATEGORY_4 Scroll Quests QUESTCATEGORY_5 System Quests Alright, now find your characterwindow.py (uiscript?) and you can either comment Quest_Page children or simply remove them all. Moving on to your interfaceModule.py find this line self.BINARY_RecvQuest(index, name, "file", localeInfo.GetLetterImageName()) and replace it with self.wndCharacter.questCategory.RecvQuest(self.BINARY_RecvQuest, index, name) Ok, then we are at the most, let's say, difficult part of this. Open your uiCharacter.py and just as you did in your characterwindow.py, remove or simply comment any single line related to quests. You can just search for these vars: self.questShowingStartIndex self.questScrollBar self.questSlot self.questNameList self.questLastTimeList self.questLastCountList Once you did that, you just: # Find these lines self.soloEmotionSlot = self.GetChild("SoloEmotionSlot") self.dualEmotionSlot = self.GetChild("DualEmotionSlot") self.__SetEmotionSlot() # And add the following import uiQuestCategory self.questCategory = uiQuestCategory.QuestCategoryWindow(self.pageDict["QUEST"]) # Find this def OnUpdate(self): self.__UpdateQuestClock() # Replace it with def OnUpdate(self): self.questCategory.OnUpdate() And we're done with the client-side. I attached some extra elements needed (such as the main python file (uiQuestCategory.py) and some image resources). Remember to edit the path linked to these images in that file. For the server-side... Well, screw it, uploaded it too. Too lazy to write. It has only a new quest function (q.getcurrentquestname()) and a few things to add in your questlib.lua. Btw, not sure if you have it, but if not, just add this extra function in ui.Button() (ui.py - class Button). def SetTextAlignLeft(self, text, height = 4): if not self.ButtonText: textLine = TextLine() textLine.SetParent(self) textLine.SetPosition(27, self.GetHeight()/2) textLine.SetVerticalAlignCenter() textLine.SetHorizontalAlignLeft() textLine.Show() self.ButtonText = textLine #Äù½ºÆ® ¸®½ºÆ® UI¿¡ ¸ÂÃç À§Ä¡ ÀâÀ½ self.ButtonText.SetText(text) self.ButtonText.SetPosition(27, self.GetHeight()/2) self.ButtonText.SetVerticalAlignCenter() self.ButtonText.SetHorizontalAlignLeft() Forgot the source part, fml, here it is. Add it to your questlua_quest.cpp. int quest_get_current_quest_name(lua_State* L) { CQuestManager& q = CQuestManager::instance(); PC* pPC = q.GetCurrentPC(); lua_pushstring(L, pPC->GetCurrentQuestName().c_str()); return 1; } void RegisterQuestFunctionTable() { luaL_reg quest_functions[] = { { "getcurrentquestname", quest_get_current_quest_name}, { NULL, NULL } }; CQuestManager::instance().AddLuaFunctionTable("q", quest_functions); } Now, finally, have fun and bye!
    1 point
  14. M2 Download Center Download Here ( Internal ) Hello, Didn't know whether to place this subject either here or on guides but since I'm gonna not only share the mitigation but also express my conclusion about this issue and further after-effects. Only part of codes are attached below. For methods definitions + headers jump here: [Hidden Content] 1. Vulnerability overview. Any kind of tcp application is required to have a server (anda client). Once a server is launched it's binded to appropriate socket and set on listening for further connections (in a cutoff, navigate here for more precise info) On the other side client is the one which is suppose to connect to server. It does it by connecting to server's socket and start to process a handshake. This is how it works in a big shortcut - or I should rather say, it does work if we deal with normal peer. In case of more-like modern apps the traffic is held by efficient algorithms that can carry even heavy traffic or eventual feeble attack. But since Metin2's core is not a state-of-art app and simply runs on old C style code (libthecore) without a real concurrency support that might dive us into some tricky issues. So let's imagine what happens if someone tries to pull off an attack and flood the server with enormous amount of packets. Since each of connection needs to be validated first, it goes through the handshake. Server catches it through the fdwatch function (jump to io_loop, main.cpp), then if no desc is presented moves it to AcceptDesc where the connection is validated. It is usually allowed unless the peer's ip is not in a banlist. Then desc is created and connection is saved for further handshake response. Sounds reasonable, right? Now imagine when thousands connection are accepted, validated, and expected to send handshake response. Does it still sound so optimistic? Additionally, when a desc is created it does allocated buffer for I/O traffic. Each connection. Each time. Each desc. Now do the math and try to conceive how much of memory is simply wasted. So that's the point we've been heading. That's our vulnerability. And btw, if so many agents are in the queue, do you think anybody will be able to connect your server? 2. Four major problems. Let's start from handshake itself. Imagine that someone approaches you and gives you his hand to shake it. And than second. And then third. Doesn't make sense, does it? Same applies to handshake process. Simply, only one handshake shall be ongoing for the host unless it completes it. So, let's jump to AcceptDesc in desc_manager.cpp and add this little code above: newd = M2_NEW DESC; // Let's check if a handshake from this host is already ongoing if (GetHostHandshake(peer)) { sys_log(0, "Handshake from %s is not permitted!", host); socket_close(desc); return NULL; } So let's consider this as solved for now. Then the second issue. Let's imagine yet another event. Someone shakes your hand but this time completes the handshake. But he does it again. And again. And again. Sounds exhausting? Let's add this 2 conditions below our recent code from above: static const int HOST_CONNECTION_LIMIT = 3; // In case if host completed handshake process let's check if it doesn't reach the limit if (GetHostConnectionCount(peer) >= HOST_CONNECTION_LIMIT) { sys_log(0, "Host %s connection limit has been reached!", host); socket_close(desc); return NULL; } // And block intrusive connections as well if (IsIntrusiveConnection(host)) { sys_log(0, "Host %s is intrusive!", host); socket_close(desc); return NULL; } First if checks if host doesn't reach the handshake limit and if it does - the host is dropped. Second if seeks for intrusive peers. That simply means if one tries to connect again, and again, and again in defined time lapse it probably turns out to be an attacking IP. Let's jump for a moment to desc.cpp, Initialize and add this variable initialization there: tt_creation_time = get_global_time(); Yet another problem solved. Still tho, all this code is considered to work more for authentication than for game's core. Why is so? Imagine a person how is not suppose to have any attention at all - a movie star for example. Usually when one walks on red carpet there are bunch of body guards sealing him/her out from the crowd around. Same should happen to game cores because why one would try to perform a handshake with game if hadn't even logged in? So that's we are going to do, simply whitelist players who were succeeded to perform through the login process and obtained login key. Firstly let's jump back to the desc_manager.cpp and add this little code above our previous alterations: // If it's not an auth server - check for validation first if (!g_bAuthServer) { if (!IsOnHandshakeWhitelist(peer)) { // sys_log(0, "Host %s has not validated through login!", host); socket_close(desc); return NULL; } } Now open input_db.cpp, move to AuthLogin function and add at the end: // Validating handshake TPacketGGHandshakeValidate pack; pack.header = HEADER_GG_HANDSHAKE_VALIDATION; strlcpy(pack.sUserIP, d->GetHostName(), sizeof(pack.sUserIP)); P2P_MANAGER::instance().Send(&pack, sizeof(pack)); And so on repeat it for AuthLoginOpenID if you use it. Now let's jump to input_p2p.cpp, move to Analyze function and after the initial syslog: // Auth server is not allowed for p2p if (g_bAuthServer) { // Clearing buffers for dynamic packets switch (bHeader) { case HEADER_GG_RELAY: { TPacketGGRelay * p = (TPacketGGRelay *) c_pData; if (m_iBufferLeft < sizeof(TPacketGGRelay) + p->lSize) iExtraLen = -1; else iExtraLen = p->lSize; } break; case HEADER_GG_NOTICE: { TPacketGGNotice * p = (TPacketGGNotice *) c_pData; if (m_iBufferLeft < sizeof(TPacketGGNotice) + p->lSize) iExtraLen = -1; else iExtraLen = p->lSize; } break; case HEADER_GG_GUILD: { iExtraLen = m_iBufferLeft - sizeof(TPacketGGGuild); } break; case HEADER_GG_MONARCH_NOTICE: { TPacketGGMonarchNotice * p = (TPacketGGMonarchNotice *) c_pData; if (m_iBufferLeft < p->lSize + sizeof(TPacketGGMonarchNotice)) iExtraLen = -1; else iExtraLen = p->lSize; } break; } return iExtraLen; } Since some of the packets might be dynamic, we need to ensure that data they hold is cleared properly. If you have more dynamic packets binded - add them as above. Move to db.cpp, find function SendLoginPing and replace with following: void DBManager::SendLoginPing(const char * c_pszLogin) { /* TPacketGGLoginPing ptog; ptog.bHeader = HEADER_GG_LOGIN_PING; strlcpy(ptog.szLogin, c_pszLogin, sizeof(ptog.szLogin)); if (!g_pkAuthMasterDesc) // If I am master, broadcast to others { P2P_MANAGER::instance().Send(&ptog, sizeof(TPacketGGLoginPing)); } else // If I am slave send login ping to master { g_pkAuthMasterDesc->Packet(&ptog, sizeof(TPacketGGLoginPing)); } */ } Avoiding clearing billing like that (wtf is that btw, shouldn't be executed at all). Now move to packet_info.cpp and add this code in constructor: Set(HEADER_GG_HANDSHAKE_VALIDATION, sizeof(TPacketGGHandshakeValidate), "HandShakeValidation", false); Jump back to input_p2p.cpp and add this case in Analyze function: case HEADER_GG_HANDSHAKE_VALIDATION: DESC_MANAGER::instance().AddToHandshakeWhiteList((const TPacketGGHandshakeValidate *) c_pData); break; Finally jump to ClientManager.cpp in DB. Find function QUERY_SETUP and if condition with bAuthServer and add there following code: peer->SetChannel(1); Sine P2P communication is allowed only for peers possessing any channel number greater than zero, we set it. Usually this practice should be forbidden but since we restrain the traffic for auth server (with code above) it should be safe. Beware that this might cause first login failed because of packet propagation that can reach the cores after player connects. Voilà, were mostly done with coding! Last but no least, we need to take a brief introduction into kqueue and tedious tour between sockets and kernel vars. Starting with kqueue. I would try to explain this but you better jump to this link. Freebsd documentation always appreciated. Since Metin2 implementation of kqueue wrapper has its size limit you may try to increase it a bit and seek for a feedback. If'd like to do so jump to main.cpp, start function and edit this variable: main_fdw = fdwatch_new(VALUE); Yet keep in mind! Do not try to over-optimize it! Try to experiment, put the different values. If you somehow screw it up it might drag you into the checkpoint issues and eventually crash the whole app. So now a few words about sockets and how the listening process works. When each connection aiming to appropriate port is detected it is dropped into the queue where it's waiting for application to pick it up. So simply we can consider this as a waiting queue like in a grocery store. The point is that this queue has it's limit and once the limit is reached, any new connection is declined at sight. The listening limit for Metin2 core is wrapped into variable called SOMAXCONN. If you dive into C socket documentation you can find something like this: /* *Maximum queue length specifiable by listen /* #define SOMAXCONN 10 As for me it was 128. Since it's a define the value is simply embedded into the app and you cannot manipulate it once a binary is built. So let's change it to let more connection be scheduled. You may ask, why? If player tries to log in it does connect the channel port. If the channel is unavailable you see fadeout and connection is terminated. It happens because there is no place in the queue thus connection is scheduled at all. But be careful! Do not set this value into some high-peak numbers! Be aware that our io_loop function need to iterate through these all events and manage to handle this during the heartbeat session. If you try to over optimize this value you can end up causing lags on the server, internal packets delays and more. In case you'd ask me, value around 1024 is acceptable but still it's better if you take some lecture and experiment a bit. And one more thing, don't forget to set this kernel option on the machine where your server runs: sysctl kern.ipc.soacceptqueue=1024 sysctl kern.ipc.somaxconn=1024 So we are done! Don't forget to add the code from my github repo! Epilogue Metin2's quite an old app and we should not forget about that. The netcode is old, rubbish and cumbersome thus this issue might be only one of many we haven't found just yet. Keep in mind tho that even that mitigation won't protect your server. Actually I doubt that even rewriting the code into more modern shape would do that if you don't get yourselves a good protection. Protection, filters, external firewalls are actually the key especially now when stressers and all this stuff are back and harmful again. Hope that this little thread will help you in your future development. Extra I manage to write a little collector for getting rid of handshakes that never completed this process (outdated). If you'd like to switch it on jump to desc_manager.cpp constructor and add there: CEventFunctionHandler::instance().AddEvent([this](SArgumentSupportImpl *) { desc_manager_garbage_collector_info* info = AllocEventInfo<desc_manager_garbage_collector_info>(); m_pkDescManagerGarbageCollector = event_create(desc_manager_garbage_collector_event, info, PASSES_PER_SEC(1)); }, "DESC_MANAGER_COLLECTOR", 1); Beware that you need this feature: And don't forget to add this to destructor: event_cancel(&m_pkDescManagerGarbageCollector); Regards Btw, credits for @Flourine for flooding my dev server with 20k packets per sec (asked for 2 btw). That helped me to analyze the problem.
    1 point
  15. M2 Download Center Download Here ( Internal ) Hello, Working on some new stuff I found out that current implementation of event looks a bit tricky. Due to this fact I basically deciced to re-implement it in C++11 providing up to date tech. Don`t forget to take a look at this topic before you start: [Hidden Content] So lets begin. Add include into the main.cpp: #ifdef __NEW_EVENT_HANDLER__ #include "EventFunctionHandler.h" #endif And add this into main function before: while (idle()); #ifdef __NEW_EVENT_HANDLER__ CEventFunctionHandler EventFunctionHandler; #endif Now add this at the end of idle: #ifdef __NEW_EVENT_HANDLER__ CEventFunctionHandler::instance().Process(); #endif Now search for: sys_log(0, "<shutdown> Destroying CArenaManager..."); And add before: #ifdef __NEW_EVENT_HANDLER__ sys_log(0, "<shutdown> Destroying CEventFunctionHandler..."); CEventFunctionHandler::instance().Destroy(); #endif Now open service.h and add this define: #define __NEW_EVENT_HANDLER__ That`s all. Now just download attachment and add included files to your source.
    1 point
  16. Hello guys. I'm Narvikz, I've been in the Metin2 scene since forever, actually I feel like I'm kind of the furniture already and unluckily full of dust by now This will actually be one of the slight amount of contributes I've given to metin2dev, I've jumped off ship a while back since this game died but apparently some troll still support it, anyway that's not related to this thread so let's keep it out of here. As there's still demand for some reason so is there a supply of game hacks, it's the basics of games, the more players there are the bigger the market for payhax and so the more profitable they are. I was contacted by a friend of mine (Runah Services) which told me that he wasn't unable to detect m2bob in any way, he also said that there are very few people who are doing it and those who are able to detect were keeping it private, he did not find anyone providing a satisfactory service to protect against these tools. What I have to say about this? You fools, you clueless fools. So, let's face it, you guys just don't have a clue about what you are doing. Right off the bat I could enumerate dozens of ways to systematically detect that m2bob is running on some system and think of its basic architecture. But first, let's talk about its architecture and how we can defeat it. Architecture M2Bob - Patcher.exe: This is the start up process when you first start using M2bob, this will generate a 128-bit Digest (probably md5) for each file that is to be checked on disk, send it through a POST HTML request to an API that will compare the client side files to the server side up-to-date files, if any file's digest is any different it will download the most up to date file using the HTTP protocol and replace it at disk. This patcher will connect to a web server hosted at the subdomain ni220471_1.vweb02.nitrado.net and as you can see in the spoiler, little reservations has Slait as to what's hosted there. Once everything is updated it will open M2Bob.exe which we'll talk about next. M2Bob.exe This file when opened from outside the Program Files will create a randomly named (yet with constant size - 10 characters) folder inside of the Program Files folder of your computer and then another one with the same template. After that it will spawn a copy of itself with a random name (yet same size once again) and do the same for the M2Bob_Dll.dll changing its extension to ".e" instead of "dll". After that it will open that randomly named executable and execute from there. Once you press the button to start the game it will spawn a metin2client instance, it will inject its module into the process memory. After that it doesn't close the open HANDLE to the game which leaves us a HUGE detection vector to take advantage of. M2Bob_Dll.dll This module once injected into metin2client will run a few Signature Scans to find the game's subroutines it needs to call in order to simulate game actions. If you take a look into the module's memory you can see those patterns and its masks quite easily, this uses a standard FindPattern function that's been around since the very start of the cheating scene. It will then automate the actions of the player using complex algorithms which are not relevant for what we care about. Security wise all M2Bob does is hooking Module32Next and whenever at your iteration through the module list you hit the m2bob random named module it jumps it to the next one, successfully hiding its module from the simplest of all module enumeration techniques. Good job Slait, always work for the minimal standards and do not think out of the box The hooking method used is the BIGGEST PILE OF CRAP I'VE EVER SEEN being done on a Windows NT based Operative System This is still a detour with a trampoline hook at function start but instead of replacing the first 5 bytes with a JMP + 32 bit absolute memory address he does THE MOST RETARDED SHIT I'VE SEEN IN A WHILE. Trust me guys, I've seen so much retarded shit lately, but Slait takes the crown on this one, he really deserves it since he's put a lot of effort into this. Instead of copying the first five bytes of this function, replacing it by a simple JMP to a memory region where it has these first five bytes followed by his detour function and then a trampoline JMP back to where it all started, he managed to do a 8 FUCKING BYTE LONG in-line hook, when literally every Windows API function is compatible with Hotpatching (easy first 5 bytes hooks). System Overview The whole system is really weak, it circumvents the protection mechanisms that is supposed to which are a PILE OF CRAP like Hackshield and GameGuard or whatever the fuck GameForge is using nowadays, but it doesn't really think out of the box when it comes to protection and obfuscation. Slait wouldn't stand a chance if GameForge purchased an actual decent service from someone who has a single clue about what they're doing (lol, even fucking Bastian Suter would perform better) instead of this pile of crap. There's no solid DRM and the system is overall really weak and shouldn't take much longer than a few hours to crack to a talented reverse engineer. Detection Vectors Well, I don't even know where to start, the whole system is flawed and weak, there's holes everywhere so I'll enumerate some quick detection vectors I can think off, and yes, I HAVE TESTED MOST OF THOSE AND THEY WORK Method #1 - Hidden Memory Pages (TESTED & WORKING) Iterate through memory pages and using VirtualQuery find those which are 4096 byte long (size of the PE Header) and being used, for those check if you can get a DOS MZ executable signature, and if you do then you most probably have a PE Header memory page. Interpret cast that memory address to NT Header and check the TimeDateStamp and or SizeOfCode or other parameters that are constant (there's tons of them) and allow you to uniquely identify m2bob. Method #2 - Open HANDLEs to game process (TESTED & WORKING) You're gonna have to use the Native API and some Undocumented structures and functions to get this done, it's really easy to do so though, shouldn't take you longer than an hour to being able to enumerate all you need to do this. Calling NtQuerySystemInformation with SystemHandleInformation as first parameter while the return value of this function is different than STATUS_INFO_LENGTH_MISMATCH or STATUS_BUFFER_OVERFLOW you are able to populate a SYSTEM_HANDLE_INFORMATION object which will have the first 4 bytes as the count of SYSTEM_HANDLE objects present in an array that follows it. This list once populated will contain a list that contains all the HANDLEs opened in your environment, this means all the File, Registry Keys, Processes, Threads, etc, HANDLEs will be enumerated and will be in that list. But to know the type of HANDLE you're dealing with you have to first call QueryObject on that HANDLE with ObjectTypeInformation to know more about it. This will get you a UNICODE string that will contain the HANDLE type, you only want the ones that are "Process" so you can filter the irrelevant ones out. Then you can check if the HANDLE is targeting your game's process id (you can get your process id at the PEB of your process), if it is you're gonna want to run some checks on that process to check whether if it's a legit one or a blacklisted one. You can do this by opening a HANDLE to it with OpenProcess and PROCESS_QUERY_LIMITED_INFORMATION as parameter. Then you're gonna want to get the executable path in disk using QueryFullProcessImageName, from there you can just read the first 4096 bytes of that file, cast them to NT Header and do the same checks as mentioned above. Alternatively you could just open the handle with PROCESS_VM_READ privileges, and use ReadProcessMemory to get the PE Header, but PROCESS_QUERY_LIMITED_INFORMATION never fails, even if the process is run as administrator or it is a system process and since m2bob doesn't use any Dynamic Forking technique it is pointless to use anything more than that. Method #3 - Integrity checks at Module32Next (TESTED & WORKING) Okay, this might sound retarded because there's malware that will spread to every process in the target system and hide itself using a user-mode rootkit that might hook Module32Next, thing is, Slait's kind of hooking is so retarded there is no actual way this would raise a false positive. This is his retarded hook: The 1st byte will always be FF, the 2nd will always be 25, the 7th will always be E4 and the 8th stays at a constant F8 as well. Check those and insert a huge dildo in Slait's ass, seriously, isn't that hard really. Do you think that's even hard? Please...... Method #4 - DNS Cache (Untested But Will Work) So, now we're jumping to the shitty methods that are only here to fill the thread just so you can be proven wrong when you say it can't be done. Basically whenever you resolve a domain name a UDP request is sent to your DNS Server asking for the resolution of a certain domain or subdomain, it will answer with some records for that domain, these records contain the IP Address it resolves to, and that IP address will be the one you'll connect using the Internet Protocol version 4. Your operative system will cache those resolutions so that each time you need to have that domain solved it doesn't bother your DNS Server with requests each time and there is a faster resolution, you can use this to beat M2Bob once again. You don't wanna look for m2bob.net since that could flag players that just crawled around that website, but if you flag their patch server subdomain, you can actually accurately flag players that have been using m2bob. Remember ni220471_1.vweb02.nitrado.net? Yup, flag the shit out of it. Method #5 - USN Journal (Untested But Will Work) The USN Journal is a system in the NTFS that keeps track of changes to files in the user's system. It will contain the timestamp of the said change, the file name and the reason for the log. The first two need no explanation, as to the third it could range from Opening the file, deleting, moving, renaming, creating, etc, etc. How's this useful? Remember how opening M2Bob.exe spawns a different executable in the Program Files folder and opens it? Well, you don't access that executable directly, you still open M2Bob.exe, this means that you could just look for entries in the USN Journal in the last 15 minutes or so that contain the name M2Bob.exe and are followed by some program in the Program Files folder a few milliseconds after (or even skip the latter) that has been opened and just kick the player from the game whenever you detect it. Aditional Methods Detection Vectors, detection vectors everywhere, I laugh at all the incompetents that for months tried to do it and failed systematically, you fools, how can you be so clueless? Even though Module32Next is hooked Module32NextW is not, which means that if you use the UNICODE alternative of the kernel32 library you will get unfiltered results - Good fucking job Slait, Incompetence at its fittest (inb4 every incompetent out there edits a public anti cheat source to use Module32NextW LOL) Haven't checked it, but even though Windows API module enumeration modules are hooked to spoof the results, you should be able to use the InInitializationOrderModuleList, InLoadOrderModuleList or the InMemoryOrderModuleList to find its module. Just be h4rdc0r3 and use Syscalls. Since you're incompetent you won't do this, hell you couldn't even get the indexes for your own operative system version let alone do it for 20 different versions per each function you wanna call. Anyway just implement the native API functions without actually calling them, this can be done really easy and WITH LITTLE INLINE ASM CODE using naked hooks, that will make sure that you don't break the stack inside of the function. You can look into this HERE. Your function call will be done within the kernel, meaning that this would bypass any placed hooks by Slait. Why the hell would your metin2 game process own 2 windows bruh? Doesn't make sense to me, just kick them dude. Signature Scans, this is pointless because his system is all flawed but could be a nice backup resort if he ever decides to use his brain. Pretty sure m2bob has some exported shit in their PE Header, just scan for it using the hidden PE Header detection shown above. As I'm really fucking tired already of writing a long ass thread incomparable to anything ever seen before here or anywhere released publicly online I won't even write down any more detection vectors, the system is filled with holes, I think I've proven my point already and it's pointless to keep doing this. This is a rant thread because you guys that own a metin2 server to make a quick buck should be ashamed of how unskilled you actually are, you are complete incompetents that keep leeching public releases and stealing other people's/servers' work, claiming it as your own or often not even mentioning it since people just don't even care any more. You provide public PAID services on an area you don't have a clue about, you're just scamming customers and selling them dreams. It is really frustrating for me since I left the scene when I was still a kid, I barely knew English and I stayed mostly on my local country's forums, my contributes back then were merely in the translation area, I've put a lot of effort into it now that I think about it, after that I limited my contributes to helping people with general Linux/BSD issues, but then it seemed that owning a Metin2 Private Servers built with pieces and pieces of stolen or leaked work was a trend, and I got really really pissed at the whole scene, I just started trolling all the retards asking for assistance with BSD issues that are from 101 classes, obvious errors that even my grandfather could solve and other retarded threads. Have Fun guys, I know most of you won't use this for anything since even being spoonfed all the methods you're so clueless you can't write this down on code, but maybe there's some one out there that will actually use some nice tips like this, and since I gave them to one guy privately on skype I might as well post them publicly for everyone to see. I've been contacted by SandMann016 to work with him, and to be honest it kind of makes me sad that I am releasing this, I never managed to proceed with those plans but still, he seemed to be a decent guy back when I first met him, but oh well, here it is now. /rant
    1 point
  17. @Tatsumaru I really want this costume
    1 point
  18. Rules §2 Topics (2.5) Questions & Answers specific rules Don't modify your thread (or reply to it) to mark it solved, and not explain the solution to the issue. Please use our tag system and vote good/bad answers so everyone can clearly see what matters! Please provide your solution or otherwise you will receive an infraction point. Thank you. Best regards Raylee
    1 point
  19. Hello. I personally think this forum is dying and has been dying for a long time. It lacks the "community" part. Everyone here is either to sell, scam or beg. There are only a few people here left who still bring out new stuff and share ideas which what this should be about...?? I generally reckon this forum need some re-thinking, it's scary how many scammers are active here. As for suggestions. I would suggest to start storing files internally (like epvp does) so we don't have to upload them on external sites. If you go through a lot of the older threads most of the files cannot be downloaded any more due to being deleted. So it gets kind of pointless to have all those threads if most of are missing assets. And I remember we used to have that "Downloads Section" where you could upload your files and do a little write up, but after a while it was gone.
    1 point
  20. v19.6.12 XMas Patch msm files Metin2 Download Includes(latest modified files): New pets New mounts New costumes Locales(protos sunday [15th]) Example pictures:
    1 point
  21. 1 point
  22. Create /share/locale/xx/shop_table_ex.txt example table: Group ShopNPC { #--# NPC Group 1 9001 Shop1 2 9002 Shop2 } Group Shop1 { Vnum 9001 Name A1 CoinType SecondaryCoin Group Items { #--# Vnum Count Price 1 20009 1 20 2 469 1 20 3 39 1 20 } } Group Shop2 { Vnum 9002 Name A2 CoinType Gold Group Items { #--# Vnum Count Price 1 299 1 25000 } } Find in shopEx.cpp:(x2) ITEM_SECONDARY_COIN change whatever you want (need item vnum) Add locale_game.txt: MONETARY_UNIT_JUN SecondCoin Result:
    1 point
  23. You can do this extension very easy. root/game.py # Search for: self.interface = interfaceModule.Interface() # Replace with: self.interface = interfaceModule.Interface(self) root/interfaceModule.py # Search for: def __init__(self): systemSetting.SetInterfaceHandler(self) # Replace with: def __init__(self, wndGame): self.wndGame = wndGame systemSetting.SetInterfaceHandler(self) root/uiInventory.py # PrintButton self.printButton = self.GetChild2("PrintButton") if self.printButton: self.printButton.SetEvent(ui.__mem_func__(self.ClickPrintButton)) def ClickPrintButton(self): wndGame = self.interface.wndGame if wndGame: wndGame.BINARY_SetBigMessage('click_print_button') # Function from game.py
    1 point
  24. Hello again! Im working on new dungeon and its finally done!! Right now im working on monsters and effects. Here are first screens from the dungeon
    1 point
  25. thanks alot, plz upload element_image_client_files.rar
    1 point
  26. There you go, uiCharacter.py and characterwindow.py for you to compare with yours. characterwindow.py uicharacter.py
    1 point
  27. #fixed myself
    0 points
×
×
  • Create New...

Important Information

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