Popular Content

Showing most liked content since 04/29/2017 in all areas

  1. 54 likes
    Hi, In this thread I'm going to show you how to make a game-client or client-game communication with packets, instead of using the old quest-client, client-quest communication. Lets start with the game-client, in this example I will send 1 variable to the client. First start with the HEADER, open your binary source and navigate to UserInterface/Packet.h. Now you will see many headers, create a new one, but search for an empty number. I will use 57, because its not used. GC means it's used for Game -> Client packet, it's just a prefix. HEADER_GC_METIN2DEV Now add the structure for the packet, this is most important part. Structure is the "body" of the packet, it contains the HEADER as BYTE and the other optional variables. As I said I just want to send one int type to the client, so add it. typedef struct command_metin2dev_packet { BYTE bHeader; int M2int; } TPacketGCMetin2Dev; Now navigate to UserInterface/PythonNetworkStream.cpp and add your header to the CMainPacketHeaderMap class. The first parameter of the Set is the HEADER, second is the size of the structure. We will use just static size packets in this tutorial, but the third argument can be dynamic size too. Set(HEADER_GC_METIN2DEV, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCMetin2Dev), STATIC_SIZE_PACKET)); Now navigate to UserInterface/PythonNtworkStreamPhaseGame.cpp and add the function to the switch. case HEADER_GC_METIN2DEV: ret = RecvM2DevPacket(); break; The name of the function will be RecvM2DevPacket: Now declarate the function, navigate to UserInterface/PythonNetworkStream.h and add it as public: bool RecvM2DevPacket(); Now add the receiver part of the code. Recv "picks" out xy bytes from the buffer and the return type of it is false if there was no data in the buffer by that size otherwise true, which means it was successful. xy = size of the structure bool CPythonNetworkStream::RecvM2DevPacket() { TPacketGCMetin2Dev Metin2DevGC; if (!Recv(sizeof(TPacketGCMetin2Dev), &Metin2DevGC)) { Tracen("Recv Metin2DevGC Packet Error"); return false; } } Now we are calling the BINARY_M2DEV_Test function in game.py and passing the received data. PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "BINARY_M2DEV_Test", Py_BuildValue("(i)", Metin2DevGC.M2int)); This was the client-side of the game-client communication, lets start the server-side: First of all we need to add the header again, navigate to game/packet.h and add this: And the structure: typedef struct packet_metin2dev_packet { BYTE byHeader; int M2int; } TPacketGCMetin2Dev; Now navigate to game/char.cpp and create a function which sends the packet. void CHARACTER::SendMetin2DevPacket() { } Declare it in the game/char.h: void SendMetin2DevPacket(); Now lets add the content of the function. Create a new instance of the structure, set the values of it and send it to the client. void CHARACTER::SendMetin2DevPacket() { if (!GetDesc()) { return; } TPacketGCMetin2Dev Metin2DevGC; Metin2DevGC.byHeader = HEADER_GC_METIN2DEV; Metin2DevGC.M2int = GetPlayerID(); GetDesc()->Packet(&Metin2DevGC, sizeof(TPacketGCMetin2Dev)); } Now add the last function to game.py, this will be called by the binary: def BINARY_M2DEV_Test(self, M2int): import dbg dbg.LogBox(str(M2int)) Finally, lets check how it works: If you have any question or suggestion, please just reply to this topic. Kind Regards, Sanchez
  2. 42 likes
    - Searching Glass, Allows the arrow mark appearing on the private shop where the item you select in the search results and guides for players to call the selling items easier access. You must be the same on the map with the seller. Default time limit; 1 Week - Trading Glass, Without going to the private shop on the same map that allows you can buy directly. Default time limit; 1 Week - Trading Glass+, Without going to the private shop you can buy directly works on any map. Default time limit; 2 Week - Common features, You can be viewed right from cheap to expensive price of items in the private shops, you can see the features of items When you move your mouse over the item you are looking for. Level, item name and bonuses you can search on the basis of price. HowTo tutorial exists in archive, Warning: It doesn't works with published shoulder sash system. You need upgrade attr type, value amounts. Download: http://puu.sh/oeibM/66130c335e.rar It doesn't looks like %100 official but it's works, My last shared and my last working in metin2.
  3. 33 likes
    I go to release a simple system , to see the coins in the inventory. http://youtu.be/93aufcRE_4s REMEMBER: localeInfo is from binary r28k locale is from binary r36k First, go to uiinventory.py and now search: self.wndMoneySlot = self.GetChild("Money_Slot") And down put: self.wndMds = self.GetChild("Mds") self.wndMdsSlot = self.GetChild("Mds_Slot") Now, search def Destroy(self): self.ClearDictionary() .... .... self.wndMoney = 0 self.wndMoneySlot = 0 And down put: self.wndMds = 0 self.wndMdsSlot = 0 Now, Search: def RefreshStatus(self): And change to: def RefreshStatus(self): money = player.GetElk() self.wndMoney.SetText(localeInfo.NumberToMoneyString(money)) import constInfo self.wndMds.SetText(str(constInfo.mds) + " Md's") And down Put: def OnUpdate(self): import constInfo self.wndMds.SetText(str(constInfo.mds) + " Md's") The uiinventory is finished, save and close, now go to locale/xx/ui/inventorywindow.py. Search: ## Print { "name":"Money_Slot", "type":"button", "x":-68, "y":28, "horizontal_align":"center", "vertical_align":"bottom", "default_image" : "d:/ymir work/ui/public/parameter_slot_05.sub", "over_image" : "d:/ymir work/ui/public/parameter_slot_05.sub", "down_image" : "d:/ymir work/ui/public/parameter_slot_05.sub", "children" : ( { "name":"Money_Icon", "type":"image", "x":-21, "y":2, "image":"d:/ymir work/ui/game/windows/money_icon.sub", }, { "name" : "Money", "type" : "text", "x" : 5, "y" : 3, "horizontal_align" : "right", "text_horizontal_align" : "right", "text" : "123456789", }, ), }, And Down Put: { "name":"Mds_Slot", "type":"button", "x":-68, "y":48, "horizontal_align":"center", "vertical_align":"bottom", "default_image" : "d:/ymir work/ui/public/parameter_slot_05.sub", "over_image" : "d:/ymir work/ui/public/parameter_slot_05.sub", "down_image" : "d:/ymir work/ui/public/parameter_slot_05.sub", "children" : ( { "name":"Mds_Icon", "type":"image", "x":-21, "y":2, "image":"d:/ymir work/ui/game/windows/money_icon.sub", }, { "name" : "Mds", "type" : "text", "x" : 5, "y" : 3, "horizontal_align" : "right", "text_horizontal_align" : "right", "text" : "123456789 Md's", }, ), }, Remember change the "x" and "y". Now, go to game.py in root. Search: def __ServerCommand_Build(self): serverCommandList={ And down put: #Carga Mds Start "Mds" : self.__Mds, #Carga Mds End and now, go to the end and put: def __Mds(self, coins): import constInfo constInfo.mds = int(coins) Save and close. Now go to constinfo.py and put mds = 0 And Here the quest: quest mds begin state start begin when login begin loop_timer("carga_mds", 10) end when carga_mds.timer begin local coins = mysql_query("SELECT coins from account.account WHERE id="..pc.get_account_id().." LIMIT 1;")[1][1] cmdchat("Mds "..coins) end end end This is my release in this forum. Sorry my bad english.. I'm Spanish. If you don't know how put, upload my archives uiinventory and inventorywindow.py https://mega.co.nz/#!R9A3SD6Q!IFZ38BXrwGOt0Z8N3qT9g5vr5XAa4DdKdeAf2KRlPEY
  4. 33 likes
    Hi everyone, Maybe just in my country, but it looks so many people started using this annoying PM flooder which cause a buffer overflow in the target client. It can be fixed easily on server-side, so let's do it: Add these functions as public to char.h: void ClearPMCounter(void) { m_iPMCounter = 0; } void IncreasePMCounter(void) { m_iPMCounter++; } void SetLastPMPulse(void); int GetPMCounter(void) const { return m_iPMCounter; } int GetLastPMPulse(void) const { return m_iLastPMPulse; } Add these to char.h too, but as protected: int m_iLastPMPulse; int m_iPMCounter; Add this function to char.cpp: void CHARACTER::SetLastPMPulse(void) { m_iLastPMPulse = thecore_pulse() + 25; } Still in char.cpp search for the Initialize and add these to the function: m_iLastPMPulse = 0; m_iPMCounter = 0; Now navigate to the Whisper function in input_main.cpp and add this after the iExtraLen variable checking at the top: if (ch->GetLastPMPulse() < thecore_pulse()) ch->ClearPMCounter(); if (ch->GetPMCounter() > 3 && ch->GetLastPMPulse() > thecore_pulse()) { ch->GetDesc()->SetPhase(PHASE_CLOSE); return -1; } Search for this still in the Whisper function: if (pkChr == ch) return (iExtraLen); Add these after that: ch->IncreasePMCounter(); ch->SetLastPMPulse();
  5. 27 likes
    Hi guys, Running a server for a year and a half while a bunch of guys gets paid to destroy it by any means ends up giving you a good insight in what the word security really means. So, after being the target of almost every type of attack possible over the Internet, I think I am ready today to write a quick checklist on how your Metin2 server should be secured from criminal and disruptive behavior. I will divide it into several parts: ingame, website, server, staff. I will try to explain in brief how those attacks are executed, but the focus here is in how to defend from them effectively. I do not want this checklist to serve the purposes of hackers. But be aware; you are never 100% safe - it depends on how much your enemy is willing to work on it. So this should be taken as a bare minimum. And don't forget: the science of destruction evolves constantly. What is considered safe today, might not be so safe tomorrow. Disclaimer: This text reflects 5 years of experience managing a server's technical aspects. I do not do certain things (like quests) for a long time so excuse me for any mistakes I may be making here. Part 1 - Ingame bugs and exploits This part refers to threats that may realize through the game client or external software that acts through the game client. While often overlooked, sometimes these can be more dangerous to your server than any other type of attack. Keep an eye in your server's economy - the average price of items. If prices for a particular item or all of them change suddenly, there may be some obscure reason behind it. That is one of the reasons why we keep public and private statistics on the average market price of every item at WoM. One of the most common mistakes - and I commited this myself - when one wants to extensively edit everything is having an item give you more Yang when you NPC it than it costs to buy it from a shop. This gives unlimited Yang to whoever discovers it. There are even public bots which automate the process of buying and selling these items. The effect on the economy is devastating over a sufficient long period, not to mention that it's unfair that some people are infinitely rich and unbalance is never good for any MMORPG. Have your GM double check that no item can be sold for more than it costs. However, this is not the only way that a player can obtain access to unlimited resources. Badly written quests may allow players to obtain their rewards repeatedly by closing their clients while a quest dialog is open. One simple way to avoid this is to make sure that the commands which reward the player are the last in the code block before changing state. Now going into disruptive behaviour - the most annoying probably are the bugs which cause a server core to crash. The most famous is probably the number_ex bug. This causes several commands which depend on this function such as dice to be exploitable by using certain parameters. This bug is fixed in rev 40k and therefore in any game compiled from the source. If you are using 34k, the best you can do is use iMer's lib which provides several security enhancements. If you are using 2089, there are public diffs that patch this. Another bug exists in the war command in 34k and older which leads to a server crash. You cannot disable this command as it is used by the guild leaders to war other guilds. iMer's Lib takes care of this bug in 34k. Older and less known is the gold drop core crash bug present in 2089 and fixed -I believe- in 34k. Dropping huge amounts of gold or any other item which you can acquire in huge numbers in a map will cause the server to crash. I am not aware of public fixes for this exploit. Another favourite is the kickhack or sync position hack -partially fixed only in 40k- which allows a malicious user to disconnect other players at will. There are even videos of this being done in DE years ago. iMer's lib provides a fix for rev 34k. Finally, we have the long list of cheats which purely seek to gain advantage while playing. There are several client protection tutorials and services around this forum so I won't extend myself here about the subject. Part 2 - Server and OS Here we talk about the threats that affect your server and Operating System Part 2.1 Choosing and preparing your server There is no doubt at the moment of writing this that the french hosting company OVH provides the most cost-effective anti-ddos solution in the market. While many companies provide DDoS protection services, these cost several times as much as OVH offerings and this increase does not necessarily translate into a better protection. Therefore we will assume that you are renting either a dedicated server at OVH or a VPS at Eterhost as those are the ones I'm familiar with. Other providers or resellers may be configured in a different manner. Dedicated Server at OVH There are two flavors of the Anti-DDoS solution: Basic and Pro. Basic is free when renting a Kimsufi or Soyoustart server (cheap and intermediate OVH brands respectively). What it does is detect attacks directed at your IP address and route your traffic through the mitigation system during the attack. This is not enough to deter a dedicated hacker though - before the attack is detected, your server may be collapsed for a few minutes, and this can be repeated every hour by the attacker, as happened with one of the TEC attacks on WoM about 1 month ago. The PRO version comes with all the OVH proper (also known as professional) line of servers. It adds the ability to route traffic permanently through the mitigation system and provides you with a simple hardware firewall. This is what you should get if serious attacks are a concern, specifically an Enterprise line server (cheapest is at about 100€/month, VAT included) How to activate permanent mitigation on OVH Professional servers: - Open the new manager. If you don't know where this is, open the classic manager and click on "Home" and then below on the "Dedicated" icon. - Click on IP on the column at the left - Click the little wheel that appears at the right of your server's IP address - Select "Mitigation: permanent" How to set up the hardware firewall: - Click the wheel again and select "Activate firewall". Wait around a minute and then reload the page. - Click the wheel and select "Configure firewall" - You will be presented with the rules screen. You can add up to 20 rules to deny or allow specific ports on the firewall. Start by adding the allowed ports in the lower numbers and end with a global deny rule. Leaving a field blank in the "Add Rule" dialog will result in a wildcard; so if you leave the IP address field blank, this rule will affect all IPs. Adding an allow port port rule: click on Add Rule; choose rule priority; select protocol (TCP or UDP); select Accept; enter the port number. Adding a global deny: choose rule priority (must be higher than the allow port rules); select protocol (TCP or UDP); select Deny. Here is an example set of rules. We have added the SSH port and the game & auth ports, as well as 3306 so our website can connect to MySQL. You can specify the webserver's IP in the rule to prevent others from connecting to your database, although I personally prefer to do this at the software level with the pf firewall; in any case, port 3306 must not be public. "How do I connect with Navicat then?" Simple, use the SSH Tunnel option. This logs you in to SSH and then connects to the MySQL server as localhost. You must enter your server's SSH login details in the SSH, and your MySQL login details in the General tab, but remember we are connecting to localhost or that's what you must enter in hostname, NOT your server's public address, as MySQL doesn't see us as a remote user anymore. Regarding UDP: UDP is your enemy. Disable it completely as I did in the above ruleset. The official client previously used UDP to check on server status, but it's trivial to override it in python so it always shows "NORM" regardless of the result of servercheck. If you are using 40k or source, the check already uses TCP, but your ports must be lower than 32768 (or the source modified) for it to work. VPS at Eterhost Our VPS are always routed through the mitigation system. Hardware firewall can be activated and configured to your needs for 5€/month extra. Part 2.2 - Hardening SSH First things first: have your OS always updated to the current version. It is often recommended by experts to access your server through a non-administrative account (some operating systems such as CentOS even force you to create one at install), so that's what we will be doing. We will create a restricted user for our game server: adduser game We can leave everything as default except for the login group: enter "wheel" here. Users which are part of the wheel group can use the su command to gain administrator privileges. This allows us to completely block root from remote login. Now it's time to create a SSH key for our new user. This makes bruteforce virtually impossible. Finally, let's prevent login from root, and login without key: ee /etc/ssh/sshd_config Look for the "PermitRootLogin" line and leave it this way, uncommenting if necessary: PermitRootLogin no And next look for the "PasswordAuthentication" setting and edit it so it looks like this: PasswordAuthentication no Now let's restart ssh for changes to take effect: service sshd restart Warning: at this point, you should open a new putty window to test that you can login with the new user and key, and that you can use the su command to gain root privileges. Wrong settings may lock you out of your server. Once everything is working, upload your server files to /home/game. This is the home directory of the user - a bit like "My Documents" in Windows. Make sure you change permissions in the files so the "game" user can read and write them: chown -R game /home/game (this command must be run as root! only root can change someone else's permissions. To switch between the game and root account, you use the su (short for superuser) command: root# su game Password: (game user's password) game# su Password: (root user's password) root# Or: root# su game Password: (game user's password) game# exit root# Finally, it may be a good idea to install ssh-guard for extra security or change your SSH port if you don't like your logs being spammed by portscans. To change your SSH port, edit the Port line in /etc/ssh/sshd_config and restart the sshd service as indicated above. Remember to open the new port if you are using a firewall or you will lock yourself out of the server. Part 2.3 Software Firewall: pf At this point it's a good idea to add a second line of defense with the pf firewall. First we will create the /etc/pf.conf file following this sample config. ee /etc/pf.conf Make sure you enter the correct interface and all the ports which must be open: SSH and game ports in our case. Neither p2p ports or db core port should be open to the public! Under trusted_hosts, enter the IP address of your web server so it can connect to the database (We assume a typical set up of web server + game / db server here) instead of opening port 3306 to everyone. This firewall provides us with scrubbing and rate limiting capabilities which the hardware firewall doesn't. Next we will enable pf: kldload pf pfctl -e Check that everything is working fine and then add the following line to /etc/rc.conf to load pf on boot: pf_enable="YES"
  6. 25 likes
    Greetings! The new beta is finished! I'm proud to present r70140-BETA. This time a few things have changed. And in this revision, we have a lot of new stuff. That's the reason I want to make a BETA so everything's tested. In the following I'll provide the download link along with the things I'd love you to test. *** DISCLAIMER *** I am absolutely not responsible for you replacing your core with a Beta-revision. This is clearly undergoing development and had not enough testing to be labeled as stable. Please do not use it in production envirionments unless you're sure what you're doing (and even so it's madness). It's meant for testing purpose. Our main goal is to achieve a stable core. As soon as patches come in, I'll tidy up the patchlog. 1.) What's new? + Boot-Trigger for quests With this you can execute commands, timers, and all the stuff you'd like to have just on boot-time! * revisioned the unique class and added a ton of possibilities to it! More down below! + Added the functionality to create unique-groups + Temp-Variables for quests * upgraded all libs and moved completely to the newest clang version * fixed some big security issues in the source code * fixed the ingame ban and unban commands * unified tables and gave them a new way: unify! * Revisioned the Makefiles and gave the source a new, easier structure * Removed all external dependencies - you won't need them, just install them by ports. No External-folder necessary! * Partial implementation of the wolfman (claws etc. are added, needs review) - removed boost dependency (no boost lib needed yay) And basically everything that has been offered in the earlier versions of the vanilla core. Nothing should be missing. And if you miss something, just feel free to tell me! 2.) What needs testing? There is a lot of stuff to test! In this earlier BETA-stage I won't give out the source code. I will do so once I've made sure the core runs well enough to be released in public. Though there are few things I'd love you to test out! * Please check if the core is vulnerable to any security breaches you may know (also the public ones, don't know if I missed something) * Please test out the new features! I'd really love to know if the new unique-functions and the boot-trigger does the job. 3.) Explanation to new features * Unique with container support Unique has evolved! This time you have a few new possibilities. Don't know what unique is? Here's a short explanation: With the unique-questfunctions you can spawn or set mobs, npcs and now even players to have a unique name. This name is stored into a unique-container. You can access this container and get all the vid's by their unique name (also called: the key) So for example you can spawn a boss with a key. Later on you can check if this specific mob has been killed or not. Or you can set his hp on-the-fly. There's basically no limits! And now with the revised system you'll have even more options. The new unique system works with containers. By default there are two containers reserved: __DEFAULT__ and __CHARACTER__. The first one is for all the basic stuff. And the second one is reserved for players. Now, as you may have noticed, there's a default one which means that the container-stuff is optional. If you just use the unique-functions without specifying a container, it'll just use the default stuff. But you CAN use your own containers just as you want to. You can create, delete and list all the containers running. There is a list with all the quest-functions down below. * Boot-Trigger This is pretty self-explanatory. With this release you can use "when boot begin" to specify a block of code that will be executed once the core has been booted. * Temp-Variables With the new temp-variables you can set and remove player-specific variables. They are stored in the core and not written to disk or database. So be careful because they might get dropped once the core shutdowns. It's just a quick storage for people who want to have something like a cache for quick access. The new quest functions: nil unique.spawn_unique(string key, int vnum, string pos=unused, string container=optional) nil unique.set_unique(string key, int vid, string container=optional) nil unique.purge_unique(string key, string container=optional) nil unique.kill_unique(string key, string container=optional) bool unique.is_unique_dead(string key, string container=optional) int unique.get_hp_perc(string key, string container=optional) nil unique.set_def_grade(string key, int def, string container=optional) nil unique.set_hp(string key, int hp, string container=optional) nil unique.set_max_hp(string key, int maxhp, string container=optional) int unique.get_vid(string key, string container=optional) bool unique.exists(string key, string container=optional) table unique.get_container_list() --this prints out all the unique containers table unique.get_container_list(string key) --this prints out all the vids in the unique-container "key" nil unique.remove_container(string key) --removes a whole container (flushes it when called on standard containers) nil pc.temp_var_set(string key, string value) string pc.temp_var_get(string key) nil pc.temp_var_delete(string key) Thanks a lot for participating! If there are any questions, this is the topic related to it. Further releases will be made public here too! If you'd like to contribute, just post code additions here. Download: Here Download (source code): Here Password for both archives is: vanilla Libs are included. If you're building your own vanilla binary you'll first have to move into every project of the Internal directory and rebuild the libs. The main Makefile is not adapted yet, I was too lazy Best Regards Vanilla
  7. 25 likes
    Hi there Dev's, today I'm gonna show you and give you as well, if you want ofc, the old skill effects from Metin2 (M1 to G1). These effects are from the time when Metin2 was opened in .kr and .cn in 2005 and till the new patch. Since my last topic asking for these effects, I've finally managed to do it. So I'm gonna share with you. If you're trying to open an oldschool server, or not, these effects could be useful. Here's some prints. Body Warrior Berserk Dash Sword Spin Three-Way Cut Mental Warrior Spirit Strike (W) Sword Strike Weaponry Sura Dragon Swirl Black Magic Sura Spirit Strike (S) Dark Orb Blade-Fight Force Ninja Rolling Dagger Dragon Force Shaman Dragon's Strength Dragon's Roar Flying Talisman Healing Force Shaman Attack Up (effect on hand) This may be a shitty "release" for you but for me it ain't. I always wanted this and I've finally did it. Download Hope you like it.
  8. 24 likes
    Hi everyone, I forgot to wrote the Client-Game communication last week, but here it is now: First start again with the HEADER, the name of mine would be HEADER_CG_METIN2DEVORG. Navigate to UserInterface/Packet.h and add this: HEADER_CG_METIN2DEVORG = 58, I will send the VID of the player to the server with one int variable: typedef struct command_metin2dev_send_packet { BYTE byHeader; int data; } TPacketCGMetin2DevOrg; Now navigate to UserInterface/PythonNetworkStreamModule.cpp and add this: PyObject* netCallM2DevPacket(PyObject* poSelf, PyObject* poArgs) { int iData; if (!PyArg_ParseTuple(poArgs, "i", &iData)) { return Py_BuildException(); } if (iData < 0) { return Py_BuildNone(); } CPythonNetworkStream& rns = CPythonNetworkStream::Instance(); rns.SendMetin2DevOrgPacket(iData); return Py_BuildNone(); } Open UserInterface/PythonNetworkStream.h and search for this: bool RecvMallOpenPacket(); Add this over that: bool SendMetin2DevOrgPacket(int data); Open PythonNetworkStreamPhaseGame.cpp and the fill the content of the send function: bool CPythonNetworkStream::SendMetin2DevOrgPacket(int data) { TPacketCGMetin2DevOrg M2DevPacket; M2DevPacket.byHeader = HEADER_CG_METIN2DEVORG; M2DevPacket.data = data; if (!Send(sizeof(M2DevPacket), &M2DevPacket)) return false; return SendSequence(); } Now add the latest codes on the client side, navigate to UserInterface/PythonNetworkStreamModule.cpp and add this: // M2DEV { "SendM2DevPacket", netCallM2DevPacket, METH_VARARGS }, Lets continue with the server-side, first start again with the HEADER in game/packet.h: HEADER_CG_METIN2DEVORG = 58, And with the structure: typedef struct command_metin2dev_send_packet { BYTE byHeader; int data; } TPacketCGMetin2DevOrg; The first argument of Set is HEADER, second is the size of the structure, third is an optional string and the fourth is a boolean. Nearly the most important part of the function is the boolean, we can decide here, do we want to use sequence check? In this case I want, so set it to true. Open game/packet_info.cpp and add this to the CPacketInfoCG::CPacketInfoCG(): Set(HEADER_CG_METIN2DEVORG, sizeof(TPacketCGMetin2DevOrg), "Metin2Dev", true); Now navigate to game/input_main.cpp and add this to the switch at the end of the file: case HEADER_CG_METIN2DEVORG: Metin2DevReceivePacket(ch, c_pData); break; Create the function for the Metin2DevReceivePacket still in game/input_main.cpp: void CInputMain::Metin2DevReceivePacket(LPCHARACTER ch, const char* c_pData) { } Now add declaration of the Metin2DevReceivePacket to the CInputMain class in game/input.h: void Metin2DevReceivePacket(LPCHARACTER ch, const char* c_pData); Fill the content of the function: TPacketCGMetin2DevOrg* p = (TPacketCGMetin2DevOrg*)c_pData; sys_log(0, "PLAYER ID: %i", p->data); Thats all, now just make a simple button in the game to call this function: net.SendM2DevPacket(player.GetTargetVID()) Example: def Button1_Event(self): net.SendM2DevPacket(player.GetTargetVID()) Finally, check how it works: Kind Regards, Sanchez
  9. 22 likes
    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 http://pastebin.com/ 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
  10. 21 likes
    Hello, im here today releasing my version of slot effect system. Is not the same as the official looks like but in the future i will update this to look the same. Screenshot to see how it looks like. Everything in this system was made by me. Tutorial: Go to UserInterface > PythonPlayer.cpp Search for : void CPythonPlayer::SetItemData(TItemPos Cell, const TItemData & c_rkItemInst) Add in the end of the funcion: PyCallClassMemberFunc(m_ppyGameWindow, "OnNewItem", Py_BuildValue("(i)", Cell.cell)); Compile It. Go to root > constInfo.py Add this somewhere: NEWITEMS = [] Save it. Go to root > game.py Add this function: def OnNewItem(self, cell): if not cell in constInfo.NEWITEMS: constInfo.NEWITEMS.append(cell) Save It. Go to root > uiinventory.py Search for : def RefreshBagSlotWindow(self): Add this before this: (if 0 == itemCount:) : if itemCount == 0 and slotNumber in constInfo.NEWITEMS: constInfo.NEWITEMS.remove(slotNumber) Add this under this: (setItemVNum(i, itemVnum, itemCount)) : self.wndItem.EnableCoverButton(i) if slotNumber in constInfo.NEWITEMS: self.wndItem.SetCoverButton(i, "d:/ymir work/ui/game/quest/slot_button_00.sub",\ "d:/ymir work/ui/game/quest/slot_button_00.sub",\ "d:/ymir work/ui/game/quest/slot_button_00.sub",\ "d:/ymir work/ui/new_icon.tga", FALSE, FALSE) self.wndItem.DisableCoverButton(i) Search for: def OverInItem(self, overSlotPos): Add under: slotPos = overSlotPos Add in the end: if overSlotPos in constInfo.NEWITEMS: self.wndItem.EnableCoverButton(slotPos) constInfo.NEWITEMS.remove(overSlotPos) Save It. Finally go to ymirwork/ui and add this file: https://mega.nz/#!VgA2GKrR!iB4vDwhCvT0yt6Zy1L4mTSiMVsijk7KhOstcoey_J8I Pack root and etc. Have fun This may not be the most optimized way to do this system, but at least you have a way. In the future i will post more updates such as a more optimized versions and with official effects. If you find any bugs please post it. #UPDATE Kind Regards, Frozen
  11. 21 likes
    Hi, I've been working on a more complete Eter management solution, still a work-in-progress. Introduction & description I've always hated the lack of organization when building or editing large quantities of files using the current tools, also they all lack a good UI, as a result I started making my own. It's meant to have a profile-based approach (you create your profile, which corresponds to a client) and all files regarding this and only this profile will be in the same place. This is a community-driven project, so I'll change it according to our needs. Requirements - .NET framework 4.5, previous versions won't work for the simple fact that I'm using some of the latest updates (which lack downward compatibility). FAQs File description Main features list - Profile-based approach to improve organization (image) - Index preview, and item selection (both for unpacking and packing, image) - Quick unpack and repack functions (image1, image2) - Size optimizer, it finds duplicates and not compressed files (image) Planned development - Implement global quick pack & repack, it will enable users to quickly process files outside of the current profile. (implemented) - Improve Size Optimizer, adding the capability to automatically repack all needed files instead of just showing informaton. - Improve "Output log" and "Detailed log" windows. (implemented) - Improve human-error prevention and exception handling (the most importat one, at the moment) - Add support for multi-threaded unpacking & packing actions while also setting a user-defined limit, for example: -- You can add 20 files to the operations list, while only X being processed at a time, to prevent crashes. Known issues and limitations - Limitation: if an item inside the epk file is greater than 600mb (or its encryption/decryption size), the file will be ignored, this is a known limitation of the .NET framework for programs targeting x86 architectures (the real cap is somewhere between 1.2-1.6gb, but to prevent crashes I downsized it) - No support for multi-threaded actions. - Sometimes when clicking enter it won't update the GridView (FIXED) - Packing with quick unpack will output a wrong file Path How to setup your profile IMPORTANT NOTE: In some files, you'll notice a message in the "Output log" window alerting you to some files with different hash than expected, this is due to the fact that most eix files are not 100% accuretly built. You can confirm the integrity of the file by extracting the same file with Tim's unpacker, you'll notice it's the same checksum. PLEASE READ THIS BEFORE USING THE SIZE OPTIMIZER. Download: Mega.co.nz VT~ Change-log Credits & final notes Used oberhumer.com for the LZO algorithm. Thanks to: - Tim, for helping me out understand how Eter files work, general architectural design input and guidance. - Marty, for helping me find out some major bugs, aswell as pointing out various errors in my implementations. - MadTiago, MarcoTuna, Pacificador, Kforce and Alejandro, for being my test slaves .
  12. 19 likes
    Hello, like the old topic ( >here< ) this topic is reserved for SHARES ONLY. If you're searching some specific files use our file request topic >here<. Additionally to this you can search for your files in the latest fully unpacked client: 17.0.7 whole unpacked client: https://metin2dev.org/board/index.php?/topic/3541-official-unpacked-updates-metin2de/&do=findComment&comment=84202 17.0.12 whole unpacked client: https://metin2dev.org/board/index.php?/topic/3541-official-unpacked-updates-metin2de/&do=findComment&comment=86090 17.1 updates only: https://metin2dev.org/board/index.php?/topic/3541-official-unpacked-updates-metin2de/&do=findComment&comment=86516 If you spam in here (which includes asking for files) you will get an infraction! Statistic (for the first 12 hours....): Hidden posts: 4 Warned posts: 3 Sincerly, .PolluX
  13. 18 likes
    Anti Wait Hack: Anti Safezone: Anti Ghostmode: Anti Wallhack: Anti Long name generator: #Update 1: -Clientside- -Serverside- Anti Mining Bot: Fishing without water fix Anti Colorful Shop Anti Drophack #Update 2: -Serverside- Anti Fish Bot Anti Guild Maker(low level) Activate Anti Teleport Hack -Clientside- Activate py inject protection Anti Anti Stun & Anti Visual GM Effect Anti Attackspeed & Anti Movespeed This thread subjects enough for general cheats For better bot and script cheat security change module or function names For this here basic tutorial for change net module name
  14. 18 likes
    Well, such a thing is quite easy, and I know it since 2011~2012 (when the first 30k game cores were released to be more precise). You can find some diff patch files of that time for 30k game cores on the web that do this, but I will explain to you how to do it via source code editing. Before all, why the 40k game core files have a login more slower than usual? That's because ymir implemented an additional encryption security using cryptopp, and at login, they added some key agreement checks, which ended up the login to be more slower. You can actually disable such a feature, so that you can have the login fast like the old game revisions had. Disabling it will actually remove the "key agreement" issue, and will encrypt the connection with xtea instead of some cryptopp algorithms. (no big security issues, so it's safe to do) The edit is quite simple: Via server, you have to go and edit ^/Srcs/Server/common/service.h commenting #define _IMPROVED_PACKET_ENCRYPTION_ to // #define _IMPROVED_PACKET_ENCRYPTION_ Via client, same story for ^\Srcs\Client\EterBase\ServiceDefs.h commenting #define _IMPROVED_PACKET_ENCRYPTION_ to // #define _IMPROVED_PACKET_ENCRYPTION_ Additionally, in the client, you must also edit the archaic pong from ^\Srcs\Client\UserInterface\Locale.cpp like this: find #define LSS_SECURITY_KEY "testtesttesttest" change it to #define LSS_SECURITY_KEY "1234abcd5678efgh" Video of a quick login: (using a second rate connection, and with 4810 programs opened simultaneously) https://youtu.be/Rp2EeICMkFU Here how the code should be at the end: http://imgur.com/a/RDO7r Enjoy your abione.
  15. 16 likes
    Hello metin2dev community! I'm new here and I'm learning how to mod metin. Yesterday I have been trying to work with item_proto and I must say - it's really difficult to find everything item_proto related (packers, converters, etc...) So I have made 2 converters and now I want to share 'em with this great community. HOW TO UNPACK/CONVERT/PACK ITEM_PROTO (this tutorial is only for people using 40K+ item_proto without TXT files (for example vanilla core) What we are going to do: 1. Unpack item_proto (so we will get XML file) 2. Convert this XML to SQL (for Navicat query) 3. Convert SQL back to XML (so we can pack it again) 4. Pack item_proto (from XML) What we will need: 1. Proto archiver (download) - http://stevecraft.cz/hracky/proto_archiver.rar 2. My XML to SQL converter I have written (no download) - http://www.stevecraft.cz/hracky/xml_to_sql.php 3. My SQL to XML converter I have written (no download) - http://www.stevecraft.cz/hracky/sql_to_xml.php PASSWORD: METIN How to do it: 1. First of all we need to download and extract proto_archiver.rar (use WinRar or 7zip) 2. Then we need to move our item_proto to folder, where we have extracted proto_archiver.rar 3. Run unpack_item_proto.bat and item_proto.xml will appear 4. Open item_proto.xml 5. Open XML to SQL converter 5. Make sure, that lines from item_proto.xml looks like example in XML to SQL converter (for example there must be column LocalizedName) 6. Paste the content of item_proto.xml into textarea in XML to SQL converter. 7. Click Convert and wait for action to be done 8. Fix errors if any and try again (for example you can have , in name column so converter will think that that name are 2 columns separated by ,) 9. After you have your conversion done, you can make query to your item_proto table. 10. Do what you want (changes in DB, additional queries, ...) 11. Now you need to dump SQL file (right click to item_proto table - dump SQL file) 12. Save it somewhere and open it 13. Delete everything on the start so only lines with INSERT INTO will remain 14. Copy everything and paste it into SQL to XML converter and click Convert 15. Everything should be ok now, so copy your XML result and save it into file item_proto.xml 16. Run pack_item_proto.bat and it will make from new item_proto.xml packed item_proto DONE
  16. 15 likes
    metin2_patch_user_situation https://mega.nz/#!6JgW0LYZ!m9g3GGhGFbiA4Z9VssPVu6kSeB48uEFXSwcl2AXBm-U metin2.sg eterPacks 2017.04.29. https://mega.nz/#!mFhU0CzY!9L6OC-cH6rSrVZi1npqkRCwW_TXGaJGkfBUJRJhDuRA
  17. 14 likes
    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 Advance Refine System.rar Soul Bind System.rar Cheque System.rar
  18. 14 likes
    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! questcategory.7z server-side.7z
  19. 13 likes
    *char.cpp *OXEvent.h *OXEvent.cpp http://puu.sh/kvX1R/87f226ed49.jpg http://puu.sh/kvXcM/ba43917fbb.jpg
  20. 12 likes
    Hi guys! I releasing something bigger after long time! There is new small map with boss and mobs. You need granny 2.9 for this release. Package containing files for client and server, so you can't do anything, just install it. Enjoy! Password for download: www.plechito.eu Download: http://www.plechito.eu/freedownloads/Moon_cave_pack.rar
  21. 11 likes
    Hello, Have a bug in much published channel switcher due from DirectConnect function here is unbugged switcher https://www.youtube.com/watch?v=cJ45_H32lCY *Move: uichangechannel and ui_wrapper in root pack *networkmodule.py Search: self.isAutoLogin=0 Add it under: self.channel = 0 *locale/xx/ui/systemdialog.py Search: { "name" : "game_option_button", "type" : "button", "x" : 10, "y" : 117, "text" : uiScriptLocale.GAMEOPTION_TITLE, "default_image" : ROOT + "XLarge_Button_01.sub", "over_image" : ROOT + "XLarge_Button_02.sub", "down_image" : ROOT + "XLarge_Button_03.sub", }, Add it under: { "name" : "change_ch_button", "type" : "button", "x" : 10, "y" : 147, "text" : "CH Switcher", "default_image" : ROOT + "XLarge_Button_01.sub", "over_image" : ROOT + "XLarge_Button_02.sub", "down_image" : ROOT + "XLarge_Button_03.sub", "disable_image" : ROOT + "XLarge_Button_03.sub", }, *game.py Search: self.interface.ShowDefaultWindows() Add it under: self.stream.isAutoSelect = 0 Search: self.interface = interfaceModule.Interface() Add it under: self.interface.SetStream(self.stream) *intrologin.py Search: if constInfo.SEQUENCE_PACKET_ENABLE: net.SetPacketSequenceMode() Add it upper: net.ACC_ID = id net.ACC_PWD = pwd *interfacemodule.py Search: def __del__(self): systemSetting.DestroyInterfaceHandler() event.SetInterfaceWindow(None) Add it under: def SetStream(self, stream): self.stream = stream Search: self.dlgSystem = uiSystem.SystemDialog() Change: self.dlgSystem = uiSystem.SystemDialog(self.stream) *uisystem.py Add in imports import uiChangeChannel Search: def __init__(self): Change: def __init__(self, stream): Search: def __init__(self, stream): Find: self.__Initialize() Add it under: self.stream = stream Search: self.GetChild("system_option_button").SAFE_SetEvent(self.__ClickSystemOptionButton) Add it upper: self.GetChild("change_ch_button").SAFE_SetEvent(self.__ClickChangeChannelButton) Search: def __OnClosePopupDialog(self): Add it upper: def __ClickChangeChannelButton(self): self.Close() if not self.changeChDlg: self.changeChDlg = uiChangeChannel.uiChangeChannel(self.stream) self.changeChDlg.Show() Search: self.gameOptionDlg = None Add it under: self.changeChDlg = None Search: if self.systemOptionDlg: self.systemOptionDlg.Destroy() Add it under: if self.changeChDlg: self.changeChDlg.Destroy() http://puu.sh/kJddR/bbb92686dd.rar
  22. 10 likes
    Hello Today I want to share with all of you a little thing. All times when you are trying to open your safebox, it's requesting the password, isn't it? But for what? I modified to limit these requests to one input per login. Of course if you warp or change character, you need to retype your password again. But with extra modifications you can do it to store the password until you close the client, but I don't recommend this. So, first go to the uiSafeBox.py file and paste this line into the __init__ method of the PasswordDialog class, with taking care of the tabulators: self.lastPassword = "" This variable will store your last entered password. Then replace the Accept method of the same class with this: (take a look for the syntax, modulename, and true/false!) def OnAccept(self): self.lastPassword = str(self.passwordValue.GetText()) m2net.SendChatPacket(self.sendMessage + self.lastPassword) self.CloseDialog() return True When you accept the password input dialog, the entered password will be saved, if it's correct if it isn't as well. Don't worry about it, it will be reset if you entered wrong password. The next step is that to paste these new functions into the same class. def InitSafeboxPassword(self): self.lastPassword = "" def GetSafeboxPwd(self): return self.lastPassword As you can see, here is a function which will reset the entered password . With this, the file is done. Open interfaceModule.py and serach this line: ## Safebox then paste this function below: def InitSafeboxPassword(self): self.dlgPassword.InitSafeboxPassword() Then replace the AskSafeboxPassword and AskMallPassword functions with these: def AskSafeboxPassword(self): if self.wndSafebox.IsShow(): return if self.dlgPassword.IsShow(): self.dlgPassword.CloseDialog() return self.dlgPassword.SetSendMessage("/safebox_password ") if self.dlgPassword.GetSafeboxPwd() != "": self.dlgPassword.OnAccept() return self.dlgPassword.SetTitle(localeInfo.PASSWORD_TITLE) self.dlgPassword.ShowDialog() def AskMallPassword(self): if self.wndMall.IsShow(): return if self.dlgPassword.IsShow(): self.dlgPassword.CloseDialog() return self.dlgPassword.SetSendMessage("/mall_password ") if self.dlgPassword.GetSafeboxPwd() != "": self.dlgPassword.OnAccept() return self.dlgPassword.SetTitle(localeInfo.MALL_PASSWORD_TITLE) self.dlgPassword.ShowDialog() With these functions, if the last entered password is correct, the storages will open automatically with the last entered password. The file is done. Next, open your game.py and search this function: OnSafeBoxError and extend it with this line: self.interface.InitSafeboxPassword() So, as you can see this is the answer from the server to entered wrong password and this function will reset the last entered password as well . That's all, I hope you like it, and have fun.
  23. 10 likes
    Hi devs, The system is so simple, you will see the yellow title if that item contains your name otherwise you will see the red title. UserInterface/PythonTextTail.cpp in search #include "PythonSystem.h" Add : #include "PythonPlayer.h" Try PythonTextTail.cpp in search pTextTail->pOwnerTextInstance->SetColor(1.0f, 1.0f, 0.0f); Under add : CInstanceBase * pInstanceBase = CPythonCharacterManager::Instance().GetMainInstancePtr(); if (pInstanceBase) { if (strcmp(pInstanceBase->GetNameString(), c_szName)) pTextTail->pOwnerTextInstance->SetColor(1.0f, 0.0f, 0.0f); } and build client.. System screen;
  24. 9 likes
    Hi, Metin2dev Screen: a simple intro login IntroLogin : add : import os def __LoadScript(self, fileName): self.Start = GetObject("start_button") self.Home = GetObject("home_button") self.Quit = GetObject("quit_button") self.Menu = GetObject("menu_button") self.FaceBookLike = GetObject("FaceBookButton") self.Conf = GetObject("config_button") Searched : self.serverList.SetEvent(ui.__mem_func__(self.__OnSelectServer)) self.FaceBookLike.SetEvent(ui.__mem_func__(self.__onclickFaceBook)) self.Conf.SetEvent(ui.__mem_func__(self.__onclickConf)) self.Home.SetEvent(ui.__mem_func__(self.__onclickHomeAdress)) self.Start.SetEvent(ui.__mem_func__(self.__onclickStartCheck)) self.Quit.SetEvent(ui.__mem_func__(self.__onclickQuit)) Searched : self.serverExitButton.SetEvent self.serverExitButton.SetEvent(ui.__mem_func__(self.__OnClickMenuButton)) Searched : def __OnClickSelectServerButton(self): def __onclickConf(self): os.system("start config.exe") def __onclickHomeAdress(self): os.startfile("http://www.mypage.com") def __onclickFaceBook(self): os.startfile("http://www.facebook.com/mypage") def __onclickStartCheck(self): self.__RequestServerStateList() self.serverBoard.Show() self.connectBoard.Hide() self.loginBoard.Hide() self.Menu.Hide() def __onclickQuit(self): self.stream.SetPhaseWindow(0) def __OnClickMenuButton(self): self.serverBoard.Hide() self.Menu.Show() Searched : self.serverBoard.SetPosition(self.xServerBoard, self.yServerBoard) to the bottom : self.serverBoard.Hide() self.connectBoard.Hide() self.loginBoard.Hide() self.Menu.Show() LoginWindow Locale/xx Edit locale name { "name" : "FaceBookButton", "type" : "button", "x" : 35, "y" : SCREEN_HEIGHT-120, "default_image" : "locale/xx/ui/face.sub", "over_image" : "locale/xx/ui/face2.sub", "down_image" : "locale/xx/ui/face2.sub", "tooltip_text" : "Facebook Page", }, to the bottom Patch Version Client Version NO URLLİB! I can, if desired because of the simple intrologin ## Check { "name" : "Show", "type" : "thinboard", "x" : SCREEN_WIDTH-165, "y" : 0, "width" : 166, "height" : 90, "children" : ( { "name" : "Neu_Text", "type" : "text", "x" : 10, "y" : 3, "vertical_align" : "center", "text_vertical_align" : "center", "text" : "Patch Version: 00001", }, { "name" : "Neu_Edit", "type" : "text", "x" : 100, "y" : 42, "width" : 120, "height" : 18, }, { "name" : "Client_Text", "type" : "text", "x" : 10, "y" : -23, "vertical_align" : "center", "text_vertical_align" : "center", "text" : "Client Version: 00001", }, { "name" : "Client_Edit", "type" : "text", "x" : 100, "y" : 17, "width" : 120, "height" : 28, }, ), }, ## Menu { "name" : "menu_button", "type" : "thinboard", 'x' : (SCREEN_WIDTH - 204) / 2, 'y' : (SCREEN_HEIGHT - 100) / 2, "width" : 200, "height" : 190, "children" : ( { "name" : "start_button", "type" : "button", "x" : 10, "y" : 17, "text" : "Start Game", "text_color" : 0xffF8BF24, "default_image" : ROOT + "XLarge_Button_01.sub", "over_image" : ROOT + "XLarge_Button_02.sub", "down_image" : ROOT + "XLarge_Button_03.sub", }, { "name" : "config_button", "type" : "button", "x" : 10, "y" : 62, "text" : "Config", "text_color" : 0xffF8BF24, "tooltip_text" : "Turns game settings.", "default_image" : ROOT + "XLarge_Button_01.sub", "over_image" : ROOT + "XLarge_Button_02.sub", "down_image" : ROOT + "XLarge_Button_03.sub", }, { "name" : "home_button", "type" : "button", "x" : 10, "y" : 107, "text" : "Home Page", "text_color" : 0xffF8BF24, "tooltip_text" : "Redirects to the main page.", "default_image" : ROOT + "XLarge_Button_01.sub", "over_image" : ROOT + "XLarge_Button_02.sub", "down_image" : ROOT + "XLarge_Button_03.sub", }, { "name" : "quit_button", "type" : "button", "x" : 10, "y" : 152, "text" : "Exit", "text_color" : 0xffF8BF24, "default_image" : ROOT + "XLarge_Button_01.sub", "over_image" : ROOT + "XLarge_Button_02.sub", "down_image" : ROOT + "XLarge_Button_03.sub", }, ), }, Sub and JPG Download Link : https://mega.co.nz/#!ItMi0aQT!QXeDnsVPczpRXkynFcgKtStLHxfLQLUoh5DHF2xJLuw ready loginwindow,intrologin in the present, You can not use those! loginwindow: locale/tr Edit locale name! intrologin : locale_is_turkey Edit locale name! Example: localeInfo,Locale
  25. 9 likes
    Hello, I'd like to share a fix for "Phase Game does not handle this header (header: 81, last: 45, 81)". Let's start First of all I'd like to begin from adding some debug info in client, in order to be sure that this fix is necessary (check spoiler below). Compile your game client and try to catch an error with header. Check out client syserr.txt. There should be more info (we've added it with previous changes). If you'll have there something like this: Means that this fix is for you At this point we'll start with fix (if you didn't have "!Recv(sizeof(BLA), &BLA)" in syserr.txt I don't sure that this fix is for you). GAME SOURCE: game/src/packet.h game/src/questpc.cpp CLIENT SOURCE: UserInterface\Packet.h UserInterface\PythonNetworkStreamPhaseGame.cpp That's it. As you can see we've just deleted TEMP_BUFFER from server function and put all data in packet body. Let me know if you'll have problems with compiling (I could forget to add something in this TUT). And sorry if my English isn't good enough for you Regards.
  26. 8 likes
    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: https://mega.co.nz/#!ut0gSTTA!Dr4onEvhWAxN506Aywv_ezRcFQawMic6Q2GbrtwDb0o Password: www.metin2dev.org Have fun ! Kind Regards, Insane
  27. 7 likes
    clang-devel should be installed just via ports. It should work in FreeBSD < 10. c++14 needs the newer clang version. If you're on one of the older compilers like gcc 4.2 it most likely won't work. Also you need devel/libc++ and devel/libcxxrt To build you then only need security/googletest, security/cryptopp, graphics/devil (only jpg needed, all else is not needed), devel/gmake, devel/makedepend and database/mariadb101-client (or any other mysql client for the lib). These are all the dependencies. I've gathered them together into a list. Note that every additional port should be compiled with clang instead of gcc! You cannot use gcc-compiled libs in a clang-project. First install: - lang/clang-devel (you don't need to use the devel-version of clang, you can just install one of the most recent versions) - devel/libc++ - devel/libcxxrt - devel/gmake (should already be installed by one of the ports above) - devel/makedepend And then add the following to /etc/make.conf: CC = clang-devel CPP = clang-cpp-devel CXX = clang++-devel CFLAGS += -stdlib=libc++ After that you can start installing the dependencies: - security/googletest - security/cryptopp - graphics/devil (note: Only jpg needed) - databases/mariadb101-client (no server needed, only the client. You can also use mysql if you wish to, we only need the client lib) If everything is installed, make sure you rebuild the Depend-File. For this you can just cd into the source directory and remove it. Then you can just execute the following command: gmake depend After that you'll have everything you need. You can build the sources. gmake debug|release|all Note that you can either choose to compile debug, release or all. You can also use install if you specified a path in your Makefile. This way the created binary will be pushed into a directory once it's finished.
  28. 7 likes
    Was just about to post this tool on here, and I saw your post... xD Don't worry, it's perfectly fine! However, I just think this is not the right section, as it more rightfully belongs to the "Tools" section. The video is pretty good, so I thank you for it, even though it only shows the export part. Just one last thing, if the mega link ever goes down, here's a direct download link from my site: http://www.ricky92.com/MDE_Tool_by_ricky92.ms
  29. 6 likes
    Hello everyone, today I present my second release.I called "Luna" It's a design of a presentation for a hypothetical metin2 server. Inside the archive you will find the .PSD files complete with everything, ready to be modified and to be adapted to your needs. I hope you enjoy it. Sorry for errors in translation from Italian to English. Screen Download
  30. 6 likes
    Hello devs. I think that webzen already fixxed this, because I can't reverse the CSlotWindow::OnMouseOver it may be virtualized :sob: The problem is that, when you are trying to make conditions for the slot with runtime mouse overin, the slot doesn't handle the overin event until now. Here is a demonstration video to show the fixxed problem. Without this fix the MouseOverIn event was running down if your cursor came to the slotboard which is the board of the slots :| instead of the slot. It's difficult to explain. Before you start to implement it, make safety backup of your files! 1.) Define the new OverIn event into the SlotWindow class in the ui.py file: 2.) Define new functions and a helper variable into the eterPythonLib\PythonSlotWindow.h. 3.) Make fit, and add the new functions into the eterPythonLib\PythonSlotWindow.cpp. Example usage: def LoadObj(self): self.wndItem = self.GetChild("ItemSlot") self.wndItem.SetOverInEvent(ui.__mem_func__(self.OverIn)) self.wndItem.SetOverOutEvent(ui.__mem_func__(self.OverOut)) def OverIn(self, selectedSlotPos): chat.AppendChat(chat.CHAT_TYPE_INFO, "OverIn %d", selectedSlotPos) def OverOut(self): chat.AppendChat(chat.CHAT_TYPE_INFO, "OverOut")
  31. 5 likes
  32. 5 likes
    I won't make a big project for the client. But I will do some few things like python 3.6 and I also will release a guide + source download for those things. But nothing like the core^^ Additionally I'm planning on gathering information for the next version of the core. Please share some feedback if you have and tell me what you'd like to see in the next revision. Few things I can already mention: - Option to switch compression algorithms. You'll be able to switch from lzo to lz4 and backwards by CONFIG - Option to switch encryption algorithms. You'll be able to switch from xtea to CAST-128 or AES and vice versa (does only work with enhanced security disabled) - Option to setup pong and other stuff via CONFIG. Of course some stuff does only work with enhanced security disabled. - Option to enable/disable custom MySQL-functions for passwords (so you can use e. g. salt for better security) - Ingame Elevation with a standard passphrase (enabled by default!) The next release focuses on stability and security. The goal is to add more diversity when it comes to encryptions and hardening your server. With custom passphrases and stuff you'll be able to switch to other implementations easily. Also the custom password functions will further protect the passwords even when an attacker gets insight on the database. Of course the core will also be able to use a custom phrase to further lengthen the password and making it more difficult for attackers to retrieve the original strings. Let me hear your thoughts EDIT: Btw. I tried to fix every bug that's been made public. But I'm not 100% sure I got everything. That's why I'm asking you kindly to revise the core and see if there's anything unstable before I brand it as a stable one. That's why It's called a BETA
  33. 4 likes
    To clarify a few things: - If someone spammed, a report is enough. Please do not write an extra post for this. - Double- (or even more) posts are allowed for shares in this topic.
  34. 4 likes
    The short answer: The long answer:
  35. 4 likes
    I don't think there is the need to say what the video is about xD Best Regards, Heur.
  36. 4 likes
  37. 4 likes
    Stop copy and paste.. Here is the new one: M2(cz)_EterPacks_17.0.12.7z
  38. 4 likes
    This quest will warp to the village whoever logins into a map which minimum level required is higher than the player's level. This basically fixes those who abuse the Wedding Ring or the Warp Scrolls to go to maps they normally shouldn't be able to go into. For example: if a player logins into the Grotto of Exile but his level is less than 75, he will be teleported back to his village. The maps and the minimum levels are fully customizable. Have fun! quest warp_check begin state start begin when login begin local map_indexes = { -- [map_index] = minimum_level [91] = 75, --** Grotto of Exile 1st Floor, [82] = 75, --** Grotto of Exile 2nd Floor, [216] = 75, --** Devils Catacomb, [218] = 90, --** Cape Dragon Head [219] = 90, --** Dawn Mist Wood [220] = 90, --** Mount Thunder [221] = 90 --** Bay Black Sand }; if (map_indexes[pc.get_map_index()] ~= nil and pc.get_level() < map_indexes[pc.get_map_index()]) then syschat("Your level is too low to stay in this map. You will be teleported back to your village.") warp_to_village(); end -- if end -- when end -- state end -- quest
  39. 4 likes
    https://mega.nz/#!mNBhERhC!Cw5ewv6ncfp7aj2hijvDq7oEzZ8AGeYsNRfefVhSEcI I didn't follow the new patchfiles, so this is the whole pack folder unpacked.
  40. 4 likes
    I did not use the BSD-functions. I use c++ standards. Lots of stuff can be handled via std-lib. Since c++11 there's a lot of new features. For example I replaced the boost::unordered_map with std::unordered_map. This also ensures cross-compatibility since you can build libc also on unix-systems. Also the security issues were SQL injections most of the time. For example the auth-messenger. But it's not limited to sql injections since there also were a few things not coded correctly with which you'd possibly crash the core. Most of them is already public so nothing too new. @galet Clientside you can just change the pong like you want to. There's nothing needed, unless you want to change the pong via config files there too (which shouldn't be done). The reason I implement this on the source is for people who just want to change those things on-the-fly and maybe release a updated binary. Or you just want to have the possibilities without messing with the core. It's more simple, the client part should be done too of course but that's not one of those things I'd do. I think I'll write a guide on how to change the encryption, e. g. xtea to AES regarding the client. This way they everyone can implement those things in their own client.
  41. 4 likes
    Hi, Im releasing my metin2 cms. Reason: few people made refund after paying me on paypal (i'm not using this stupid system for selling stuffs anymore) Features: Almost everything customizable in administration - no programming knowledge required Highly secured (CMS is using PDO driver instead of mysql_ function, bruteforce protection, anti flood protection) Responsive template (bootstrap) Almost every user actions on web are logged You can choose if you want to use classic php email function or SMTP server Built-in ticket system Referral system Coupons Itemshop - you can enable discount action, let users change quantity of item, add normal item / premium Easy to translate language (all strings are in 1 file) SEO friendly links (yoursite.com/team instead of yoursite.com?page=team) Automatic paypal payment script, paysafecard and amazon code payment scripts And many others... (see screenshots) Screenshots: http://goucko.cz/grand/ I didn't implement installation script, so you must install it manually (tutorial in readme.txt) If you like my CMS, you can donate me on paypal - https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=YZBSXKU3RUXZ2 Don't remove my copyright, please. Download link: http://test.goucko.cz/grand_FINAL.rar Scan: https://www.virustotal.com/en/file/f4af61d96ed71667c84bb4fb9e0264f90c42cc202db2711025aee93e44558464/analysis/1451329199/ EDIT: Bugfix 1 - Rename file "inc/classes/securimage.class.php" to "Securimage.class.php" (first letter need to be uppercase)
  42. 4 likes
    There is a small configuration to get bonus of pet. Maybe somebody use it. How it looks in game: In uitooltip.py -. search (item.ITEM_TYPE_QUEST == itemType:) and after this statement: if itemVnum >= 53001 and itemVnum <= 53026: self.AppendSpace(5) for g in xrange(item.ITEM_APPLY_MAX_NUM): (affectType, affectValue) = item.GetAffect(g) affectString = self.__GetAffectString(affectType, affectValue) if affectString: affectColor = self.GetChangeTextLineColor(affectValue) self.AppendTextLine(affectString, affectColor) its all. PS: If you dont have a item.ITEM_TYPE_QUEST == itemType: Just find elif item.ITEM_TYPE_USE == itemType: and after add item.ITEM_TYPE_QUEST == itemType: Looks like: elif item.ITEM_TYPE_USE == itemType: ..... ..... elif item.ITEM_TYPE_QUEST == itemType: This is nothing special but i think it looks good
  43. 3 likes
    Special thanks for design and help: [url=https://metin2dev.org/board/index.php?/profile/12872-legolasofficial/]LegolasOfficial[/url] Download: https://mega.nz/#!pBUj0IoC!tYUbK3liAC5fSxxWQ1sWjUKypNFphPergj4lDZxk6RQ
  44. 3 likes
    Hello, A few weeks ago, being bored I thought about creating a visual editor for item_proto, without the need of XML, and here's the result: https://cataclismo.github.io/item_proto_lib/ I should mention that this is my first time working with CLI and C#. Pretty fun actually. Also, the binaries for graphic interface (including library dll) are built for x64 arch. If anyone wants, I can provide the source code for the graphic interface, but because of laziness, I made the interface a bit tricky, yet easy to modify (on some parts). Enjoy PS: Any feedback is welcome. Not tested with an actual client. Just read and written some item_proto files. xD
  45. 3 likes
    Here is a little fix to disable the double potion sounds (green & purple): UI\PythonItem.cpp -> DWORD CPythonItem::__GetUseSoundType(const CItemData& c_rkItemData) Search the case of the ability_up and replace it with this: case CItemData::USE_ABILITY_UP: { if ((c_rkItemData.GetIndex() == 27053 || c_rkItemData.GetIndex() == 27054) || (c_rkItemData.GetIndex() >= 27100 && c_rkItemData.GetIndex() <= 27105) || (c_rkItemData.GetIndex() >= 27110 && c_rkItemData.GetIndex() <= 27115)) return USESOUND_NONE; else return USESOUND_POTION; } break; This is an exception to block the playusesound when you are using an item from inventory: netSendItemUsePacket -> CPythonNetworkStream::SendItemUsePacket -> __PlayInventoryItemUseSound Because of the SpecificEffectPacket plays the sound of the potions as well.
  46. 3 likes
    Draw metin2 in png format, I hope you enjoy it Photoshop CS6 project: password: luca17081998 fabbro chibi 1920x 1080 progetto photoshop cs6 password: luca17081998 Charon chibi 1920x 1080. PNG progetto photoshop cs6 password: luca17081998 draw ninja metin format PNG, 1920x 1080
  47. 3 likes
    https://metin2origins.ro/ http://patchmetin2origins.ro https://www.facebook.com/groups/metin2origins https://www.facebook.com/Mt2origins/?fref=ts
  48. 3 likes
    Author: Ionuț ( me ) Size: 3.54 MB Version: v2.4 Type: Open-Source Features: Modern design with elements in bootstrap (v4 alpha 3), admin panel (currently in beta), member panel (currently basic systems), update system, registration, general settings in the admin panel, offline system (if the server is offline, notifications will be displayed, also the last copy of the top site), database of news is sqlite, settings files are in json. Language: English & Romanian Preview: Download: https://metin2cms.cf/v2 Documentation : https://metin2cms.cf/v2/documentation/ Install: Just edit config.php with your datas. CMS is not completely. It will be updated. I expect criticism / opinions / advice constructive. To report an error: https://ionut.work/contact
  49. 3 likes
    I'm currently building a new itemshop (Web + ingame). What do you think of this and how is your opinion to my idea to use the client design of Metin2 for this? Video of the current state:
  50. 3 likes
    Hi ! client install: game.py make a import calendar let the last of the game.py and paste this def Calendar(self): import calendar self.calendar = calendar.Calendar() self.calendar.Show() then look : onPressKeyDict[app.DIK_F4] = lambda : self.__PressQuickSlot(7) stick below: onPressKeyDict[app.DIK_F6] = lambda : self.Calendar() https://mega.co.nz/#!0d8mSTpS!nIjBlv_cIjIlF5m-d7WcS53ulFbTjGshPj5Hk-DtU0Y already ready calendar no copy elsewhere