Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation on 11/30/14 in all areas

  1. M2 Download Center Download Here ( Internal ) 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();
    4 points
  2. M2 Download Center Download Here ( Internal ) Hi devs, I maked new user check system(like IP) with Hardware Needed Files; Server Part: Common -> tables.h, lenght.h Game -> input_auth.cpp, packet.h Client Part: Pack -> intrologin.py, networkmodule.py, constinfo.py Client -> AccountConnector.cpp, AccountConnector.h, Packet.h, PythonNetworkStream.cpp, PythonNetworkStream.h, PythonNetworkStreamModule.cpp, PythonNetworkStreamPhaseLogin.cpp A BACKUP BEFORE YOU START KNOWN BUGS; All Auth Events logging(not only succesfuly) Let's start 1) First Server Part: 1-1) Common 1-1-1) Tables.h Search typedef struct SAccountTable And replace with this typedef struct SAccountTable { DWORD id; char login[LOGIN_MAX_LEN + 1]; char Hwid[HWID_MAX_LEN + 1]; char Snn[SNN_MAX_LEN + 1]; char passwd[PASSWD_MAX_LEN + 1]; char social_id[SOCIAL_ID_MAX_LEN + 1]; char status[ACCOUNT_STATUS_MAX_LEN + 1]; BYTE bEmpire; TSimplePlayer players[PLAYER_PER_ACCOUNT]; } TAccountTable; Search typedef struct SLoginPacket And replace with this typedef struct SLoginPacket { char login[LOGIN_MAX_LEN + 1]; char passwd[PASSWD_MAX_LEN + 1]; char Hwid[HWID_MAX_LEN + 1]; char Snn[SNN_MAX_LEN + 1]; } TLoginPacket; Search typedef struct SPacketGDAuthLogin And replace with this typedef struct SPacketGDAuthLogin { DWORD dwID; DWORD dwLoginKey; char szLogin[LOGIN_MAX_LEN + 1]; char szHwid[HWID_MAX_LEN + 1]; char szSnn[SNN_MAX_LEN + 1]; char szSocialID[SOCIAL_ID_MAX_LEN + 1]; DWORD adwClientKey[4]; BYTE bBillType; DWORD dwBillID; int iPremiumTimes[PREMIUM_MAX_NUM]; } TPacketGDAuthLogin; 1-1-2) Lenght.h Search PASSWD_MAX_LEN = 16, Add it below HWID_MAX_LEN = 50, SNN_MAX_LEN = 50, 1-2) Game 1-2-1) input_auth.cpp Search this function void CInputAuth::Login(LPDESC d, const char * c_pData) Find this char passwd[PASSWD_MAX_LEN + 1]; strlcpy(passwd, pinfo->passwd, sizeof(passwd)); and add it below char Hwid[HWID_MAX_LEN + 1]; strlcpy(Hwid, pinfo->Hwid, sizeof(Hwid)); char Snn[SNN_MAX_LEN + 1]; strlcpy(Snn, pinfo->Snn, sizeof(Snn)); std::auto_ptr<SQLMsg> msg(DBManager::instance().DirectQuery("UPDATE account.account SET hwid = '%s', Snn = '%s' WHERE login = '%s'", pinfo->Hwid, pinfo->Snn, login)); 1-2-2) packet.h Search typedef struct command_login2 and replace with this typedef struct command_login2 { BYTE header; char login[LOGIN_MAX_LEN + 1]; DWORD dwLoginKey; DWORD adwClientKey[4]; char Hwid[HWID_MAX_LEN + 1]; char Snn[SNN_MAX_LEN + 1]; } TPacketCGLogin2; Search typedef struct command_login3 and replace with this typedef struct command_login3 { BYTE header; char login[LOGIN_MAX_LEN + 1]; char passwd[PASSWD_MAX_LEN + 1]; char Hwid[HWID_MAX_LEN + 1]; char Snn[SNN_MAX_LEN + 1]; DWORD adwClientKey[4]; } TPacketCGLogin3; 2) Second Client Part 2-1)Pack 2-1-1)Constinfo.py Add anywhere import os try: Hwid = os.popen("wmic csproduct get uuid").read().split("n")[1] except: Hwid = os.popen("%WINDIR%/system32/wbem/wmic csproduct get uuid").read().split("n")[1] try: Snn = os.popen('wmic path win32_physicalmedia get SerialNumber').read().split("n")[1] except: Snn = os.popen("%WINDIR%/system32/wbem/wmic path win32_physicalmedia get SerialNumber").read().split("n")[1] 2-1-2)Networkmodule.py add this import import constInfo and add it below Hwid=constInfo.Hwid Snn=constInfo.Snn Search self.pwd="" and add it below self.Hwid=constInfo.Hwid self.Snn=constInfo.Snn Search def SetLoginInfo(self, id, pwd) self.id = id self.pwd = pwd net.SetLoginInfo(id, pwd) and replace with this def SetLoginInfo(self, id, pwd, Hwid, Snn): self.id = id self.pwd = pwd self.Hwid = constInfo.Hwid self.Snn = constInfo.Snn net.SetLoginInfo(id, pwd, Hwid, Snn) 2-2-3)introLogin.py Search RUNUP_MATRIX_AUTH = FALSE Add top Hwid = constInfo.Hwid Snn = constInfo.Snn Search this function def Connect(self, id): and replace with this def Connect(self, id, pwd, Hwid, Snn): global Hwid, Snn if constInfo.SEQUENCE_PACKET_ENABLE: net.SetPacketSequenceMode() if IsLoginDelay(): loginDelay = GetLoginDelay() self.connectingDialog = ConnectingDialog() self.connectingDialog.Open(loginDelay) self.connectingDialog.SAFE_SetTimeOverEvent(self.OnEndCountDown) self.connectingDialog.SAFE_SetExitEvent(self.OnPressExitKey) self.isNowCountDown = TRUE else: self.stream.popupWindow.Close() self.stream.popupWindow.Open(localeInfo.LOGIN_CONNETING, self.SetPasswordEditLineFocus, localeInfo.UI_CANCEL) self.stream.SetLoginInfo(id, pwd, Hwid, Snn) self.stream.Connect() Search def __LoadLoginInfo(self, loginInfoFileName): Add it below global Hwid, Snn Search self.pwd = None Add it below self.Hwid = Hwid self.Snn = Snn Search self.Connect(id, pwd) Replace with this self.Connect(id, pwd, Hwid, Snn) Search self.Connect(id, pwd) Replace With This self.Connect(id, pwd, Hwid, Snn) Search def __OnClickLoginButton(self): Add it below global Hwid, Snn 2-2)Client 2-2-1)Packet.h Search PASS_MAX_NUM = 16, and add it below HWID_MAX_NUM = 50, SNN_MAX_NUM = 50, Search typedef struct command_login And replace with this typedef struct command_login { BYTE header; char name[ID_MAX_NUM + 1]; char pwd[PASS_MAX_NUM + 1]; char Hwid[HWID_MAX_NUM + 1]; char Snn[SNN_MAX_NUM + 1]; } TPacketCGLogin; Search typedef struct command_login3 And replace with this typedef struct command_login3 { BYTE header; char name[ID_MAX_NUM + 1]; char pwd[PASS_MAX_NUM + 1]; char Hwid[HWID_MAX_NUM + 1]; char Snn[SNN_MAX_NUM + 1]; DWORD adwClientKey[4]; } TPacketCGLogin3; Search typedef struct command_direct_enter And replace with this typedef struct command_direct_enter { BYTE bHeader; char login[ID_MAX_NUM + 1]; char passwd[PASS_MAX_NUM + 1]; char Hwid[HWID_MAX_NUM + 1]; char Snn[SNN_MAX_NUM + 1]; BYTE index; } TPacketCGDirectEnter; 2-2-2)AccountConnector.h Search void SetLoginInfo(const char * c_szName, const char * c_szPwd Replace with this void SetLoginInfo(const char * c_szName, const char * c_szPwd, const char * c_szHwid, const char * c_szSnn); Search std::string m_strPassword; Add it below std::string m_strHwid; std::string m_strSnn; 2-2-3)AccountConnector.cpp Search this function void CAccountConnector::SetLoginInfo(const char * c_szName, const char * c_szPwd) Replace with this void CAccountConnector::SetLoginInfo(const char * c_szName, const char * c_szPwd, const char * c_szHwid, const char * c_szSnn) { m_strID = c_szName; m_strPassword = c_szPwd; m_strHwid = c_szHwid; m_strSnn = c_szSnn; } Search strncpy(LoginPacket.pwd, m_strPassword.c_str(), PASS_MAX_NUM); add it below strncpy(LoginPacket.Hwid, m_strHwid.c_str(), HWID_MAX_NUM); strncpy(LoginPacket.Snn, m_strSnn.c_str(), SNN_MAX_NUM); Search LoginPacket.pwd[PASS_MAX_NUM] = '0'; Add it below LoginPacket.Hwid[HWID_MAX_NUM] = '0'; LoginPacket.Snn[SNN_MAX_NUM] = '0'; Search SetLoginInfo("", ""); Replace with this SetLoginInfo("", "", "", ""); 2-2-4)PythonNetworkStreamPhaseLogin.cpp Search(2x) if (0 != m_dwLoginKey) and replace with this if (0 != m_dwLoginKey) SendLoginPacketNew(m_stID.c_str(), m_stPassword.c_str(), m_stHwid.c_str(), m_stSnn.c_str()); else SendLoginPacket(m_stID.c_str(), m_stPassword.c_str(), m_stHwid.c_str(), m_stSnn.c_str()); Search this function bool CPythonNetworkStream::SendDirectEnterPacket(const char* c_szID, const char* c_szPassword) replace with this bool CPythonNetworkStream::SendDirectEnterPacket(const char* c_szID, const char* c_szPassword, const char* c_szHwid, const char* c_szSnn, UINT uChrSlot) { TPacketCGDirectEnter kPacketDirectEnter; kPacketDirectEnter.bHeader=HEADER_CG_DIRECT_ENTER; kPacketDirectEnter.index=uChrSlot; strncpy(kPacketDirectEnter.login, c_szID, ID_MAX_NUM); strncpy(kPacketDirectEnter.passwd, c_szPassword, PASS_MAX_NUM); strncpy(kPacketDirectEnter.Hwid, c_szHwid, HWID_MAX_NUM); strncpy(kPacketDirectEnter.Snn, c_szSnn, SNN_MAX_NUM); if (!Send(sizeof(kPacketDirectEnter), &kPacketDirectEnter)) { Tracen("SendDirectEnter"); return false; } return SendSequence(); } Search this function bool CPythonNetworkStream::SendLoginPacket(const char* c_szName, const char* c_szPassword) and replace with this bool CPythonNetworkStream::SendLoginPacket(const char* c_szName, const char* c_szPassword, const char* c_szHwid, const char* c_szSnn) { TPacketCGLogin LoginPacket; LoginPacket.header = HEADER_CG_LOGIN; strncpy(LoginPacket.name, c_szName, sizeof(LoginPacket.name)-1); strncpy(LoginPacket.pwd, c_szPassword, sizeof(LoginPacket.pwd)-1); strncpy(LoginPacket.Hwid, c_szHwid, sizeof(LoginPacket.Hwid)-1); strncpy(LoginPacket.Snn, c_szSnn, sizeof(LoginPacket.Snn)-1); LoginPacket.name[ID_MAX_NUM]='0'; LoginPacket.pwd[PASS_MAX_NUM]='0'; LoginPacket.Hwid[HWID_MAX_NUM]='0'; LoginPacket.Snn[SNN_MAX_NUM]='0'; if (!Send(sizeof(LoginPacket), &LoginPacket)) { Tracen("SendLogin Error"); return false; } return SendSequence(); } Search bool CPythonNetworkStream::SendLoginPacketNew(const char * c_szName, const char * c_szPassword) and replace with this bool CPythonNetworkStream::SendLoginPacketNew(const char * c_szName, const char * c_szPassword, const char * c_szHwid, const char * c_szSnn) 2-2-4)PythonNetworkStreamModule.cpp Search this function PyObject* netSetLoginInfo(PyObject* poSelf, PyObject* poArgs) and replace with this PyObject* netSetLoginInfo(PyObject* poSelf, PyObject* poArgs) { char* szName; if (!PyTuple_GetString(poArgs, 0, &szName)) return Py_BuildException(); char* szPwd; if (!PyTuple_GetString(poArgs, 1, &szPwd)) return Py_BuildException(); char* szHwid; if (!PyTuple_GetString(poArgs, 2, &szHwid)) return Py_BuildException(); char* szSnn; if (!PyTuple_GetString(poArgs, 3, &szSnn)) return Py_BuildException(); CPythonNetworkStream& rkNetStream=CPythonNetworkStream::Instance(); CAccountConnector & rkAccountConnector = CAccountConnector::Instance(); rkNetStream.SetLoginInfo(szName, szPwd, szHwid, szSnn); rkAccountConnector.SetLoginInfo(szName, szPwd, szHwid, szSnn); return Py_BuildNone(); } Search this function PyObject* netSendLoginPacket(PyObject* poSelf, PyObject* poArgs) and replace with this PyObject* netSendLoginPacket(PyObject* poSelf, PyObject* poArgs) { char* szName; if (!PyTuple_GetString(poArgs, 0, &szName)) return Py_BuildException(); char* szPwd; if (!PyTuple_GetString(poArgs, 1, &szPwd)) return Py_BuildException(); char* szHwid; if (!PyTuple_GetString(poArgs, 2, &szHwid)) return Py_BuildException(); char* szSnn; if (!PyTuple_GetString(poArgs, 3, &szSnn)) return Py_BuildException(); CPythonNetworkStream& rkNetStream=CPythonNetworkStream::Instance(); rkNetStream.SendLoginPacket(szName, szPwd, szHwid, szSnn); return Py_BuildNone(); } 2-2-5)PythonNetworkStream.h Search void SetLoginInfo(const char* c_szID, const char* c_szPassword); Replace with this void SetLoginInfo(const char* c_szID, const char* c_szPassword, const char* c_szHwid, const char* c_szSnn); Search bool SendLoginPacket(const char * c_szName, const char * c_szPassword); bool SendLoginPacketNew(const char * c_szName, const char * c_szPassword); Replace with this bool SendLoginPacket(const char * c_szName, const char * c_szPassword, const char * c_szHwid, const char * c_szSnn); bool SendLoginPacketNew(const char * c_szName, const char * c_szPassword, const char * c_szHwid, const char * c_szSnn); Search bool SendDirectEnterPacket(const char * c_szName, const char * c_szPassword, UINT uChrSlot); And replace with this bool SendDirectEnterPacket(const char * c_szName, const char * c_szPassword, const char * c_szHwid, const char * c_szSnn, UINT uChrSlot); Search std::string m_stPassword; Add it below std::string m_stHwid; std::string m_stSnn; 2-2-6)PythonNetworkStream.cpp Search this function void CPythonNetworkStream::SetLoginInfo(const char* c_szID, const char* c_szPassword) And replace with this void CPythonNetworkStream::SetLoginInfo(const char* c_szID, const char* c_szPassword, const char* c_szHwid, const char* c_szSnn) { m_stID=c_szID; m_stPassword=c_szPassword; m_stHwid=c_szHwid; m_stSnn=c_szSnn; } Now run this query commands; ALTER TABLE account.account ADD Hwid VARCHAR(50); ALTER TABLE account.account ADD Snn VARCHAR(50); Create tables DROP TABLE IF EXISTS `snnban`; CREATE TABLE `snnban` ( `Snn` varchar(255) NOT NULL ) ENGINE=InnoDB DEFAULT CHARSET=latin1; DROP TABLE IF EXISTS `hwidban`; CREATE TABLE `hwidban` ( `Hwid` varchar(255) NOT NULL ) ENGINE=InnoDB DEFAULT CHARSET=latin1; Basic php ban script <?php error_reporting(0); if($_GET) { $baglanti = mysqli_connect('localhost', 'root', 'PASSWORD', 'account'); $hwid = mysqli_real_escape_string($baglanti, $_GET['hwid']); $snn = mysqli_real_escape_string($baglanti, $_GET['snn']); if(strlen($snn) == 0) { $hwid_bul = mysqli_query($baglanti, "SELECT null FROM hwidban WHERE hwid='$hwid'"); if(mysqli_num_rows($hwid_bul) > 0) echo 'BLOCK'; mysqli_free_result($hwid_bul); }else{ $snn_bul = mysqli_query($baglanti, "SELECT null FROM snnban WHERE snn='$snn'"); if(mysqli_num_rows($snn_bul) > 0) echo 'BLOCK'; mysqli_free_result($snn_bul); } mysqli_close($baglanti); } ?> Bonus; if you want alternative ways (mac, cpu etc.) check tutorials below #CPU INFO: import platform platform.processor() #MAC INFO: mac = '' for line in os.popen('getmac /nh /fo CSV').readlines(): m = line.split(',')[0] dev = line.split(',')[1] if dev.find('Device') and mac == '': mac = m mac = mac.replace('"', '') #HWID INFO: *DEFAULT hwid = os.popen('wmic csproduct get uuid').read().split("n")[1] #HDD INFO: hddinfo = win32api.GetVolumeInformation("C:") #COMPUTER NAME: pcadi = os.environ['COMPUTERNAME'] #CPU NAME: cpu = os.popen('wmic cpu get name').read().split("n")[1] #MOTHERBOARD INFO: anakart = os.popen('wmic baseboard get serialnumber').read().split("n")[1] #RAM SERIAL: ram = os.popen('wmic memorychip get serialnumber').read().split("n")[2] #BIOS VERSION: biosv = os.popen('wmic bios get smbiosbiosversion').read().split("n")[1] #COMPUTER MODEL: model = os.popen('wmic csproduct get name').read().split("n")[1] #SYSTEM TYPE: systype = os.popen('wmic computersystem get systemtype').read().split("n")[1] #COMPUTER OWNER: owner = os.popen('wmic computersystem get manufacturer').read().split("n")[1] #OS NAME: osname = os.popen('wmic os get Caption,CSDVersion /value').read().split("n")[2].split("Caption=")[-1] #WINDOWS USERNAME: winusnm = os.popen('echo %username%').read().split("n")[0] #VOLUME NAME: volname = os.popen('wmic logicaldisk get volumename').read().split("n")[1] #SMART SNN: *DEFAULT smartsnn = os.popen('wmic path win32_physicalmedia get SerialNumber').read().split("n")[1] #USER SID: usersid = os.popen('wmic useraccount get name,sid').read().split("n")[2].replace(" ", " - ") #TOTAL MEMORY: ramboyut = os.popen('wmic computersystem get TotalPhysicalMemory').read().split("n")[1] Example files: [Hidden Content] Virustotal: [Hidden Content] Result: Sorry my bad english Regards
    3 points
  3. Hi, EnhanceMT is an open source project about improving the Metin2 client & server sources. The server is based on the mainline branch and the client is based on the novaline branch. The purposes are to : Clean and improve sources and databases Easy multi-platforms compilation Fix bugs Work on new systems ? Create a community, working together We are at the moment 3 in the "team", but what we want is that everyone can work on that project, then do pull requests and stuff. As I said it's a community project. I started to work on server sources and what I did/want to do is : Add CMake support (done, only Windows VS 12/13 supported atm) Support Linux compilation (previous point) Re-organize sources (started) Removing unused stuff (HS, XTrap, etc.) If possible, create a separate solution for auth stuff (goal is to have : Auth <-> Multiple realms (channels)) If possible, removing channel99 (previous point) Tutorials will come soon to help you building it. Looking forward for your feedbacks ! Cheers, Sgt
    2 points
  4. Hey Guys, Since this is my first post i want to release a little module i wrote 5 minutes ago. First of all this is for everybody who hates sockets(like me) and don't want to use item_proto for Shinings/Effects whatever. The Code is quiet "crappy" but it is working flawlessly. So lets get started. You wanna create something like this where you declare your maps to store the vnum and effectfilepath #include <map> #ifndef ShiningSettings_H #define ShiningSettings_H 1 extern std::map<int, char*> shiningdata; extern std::map<int, char*>::iterator shiningit; #endif Then you wanna create your function for your python module #include "StdAfx.h" #include "ShiningSettings.h" PyObject* addEffect(PyObject* poSelf, PyObject* poArgs) { int vnum; char* effectpath; if(!PyTuple_GetInteger(poArgs, 0, &vnum)) { return Py_BuildException(); } if(!PyTuple_GetString(poArgs, 1, &effectpath)) { return Py_BuildException(); } if(!shiningdata.count(vnum)){ shiningdata[vnum] = effectpath; } return Py_BuildNone(); } void initShining() { static PyMethodDef s_methods[] = { { "Add", addEffect, METH_VARARGS }, { NULL, NULL }, }; Py_InitModule("Shining", s_methods); } Make also sure you start your function in UserInterface.cpp bool RunMainScript(CPythonLauncher& pyLauncher, const char* lpCmdLine){ //Otherfunctions initShining(); } AND in stdafx.h add this void initShining(); After that open up your InstanceBase.cpp and define your early declared maps also include boost algorithm Just copy this at the start of the file #include "boost/algorithm/string.hpp" std::map<int, char*> shiningdata; std::map<int, char*>::iterator shiningit; Then search for if (12010 <= vnum && vnum <= 12049) and copy the following code after the if-clause if(!shiningdata.empty()){ for (shiningit=shiningdata.begin(); shiningit!=shiningdata.end(); shiningit++) if (shiningit->first == vnum) { std::string substr(shiningit->second); std::vector<string> chars; boost::split(chars, substr, boost::is_any_of("#")); for(std::vector<string>::size_type i = 0; i != chars.size(); i++) { __AttachEffectToArmours(chars[i]); } } } } This will split after a # for multiple shining attached to one amour. Then you need to declare and define a function in InstanceBaseEffect.cpp and InstanceBase.h InstanceBaseEffect.cpp DWORD CInstanceBase::__AttachEffectToArmours(string effectfilename) { const char * effectpath = effectfilename.c_str(); CEffectManager::Instance().RegisterEffect(effectpath, false, false); return m_GraphicThingInstance.AttachEffectByName(0, "Bip01", effectpath); } Again if you wish you can modify it. I already hardcoded the bonename and the boneindex. In InstanceBase.h Search for this: protected: DWORD __AttachEffect(UINT eEftType); DWORD __AttachEffectToArmours(string effectfilename); void __DetachEffect(DWORD dwEID); Replace with this: protected: DWORD __AttachEffect(UINT eEftType); DWORD __AttachEffectToArmours(string effectfilename); DWORD __AttachEffect(char filename[128]); void __DetachEffect(DWORD dwEID); Oh Yeah watch out that your filename is no longer than 128 characters. Last but not least: Create a Python Script in your root Folder (call it whatever you like) import Shining ##Modded Version # Implemented Delim for C++ # delimiter : # EffectTable = { 11290 : ["d:/ymir work/pc/common/effect/armor/armor-4-2-2.mse"], 11291 : ["d:/ymir work/pc/common/effect/armor/armor-4-2-2.mse"], 11292 : ["d:/ymir work/pc/common/effect/armor/armor-4-2-2.mse"], 11293 : ["d:/ymir work/pc/common/effect/armor/armor-4-2-2.mse"], 11294 : ["d:/ymir work/pc/common/effect/armor/armor-4-2-2.mse"], 11295 : ["d:/ymir work/pc/common/effect/armor/armor-4-2-2.mse"], 11296 : ["d:/ymir work/pc/common/effect/armor/armor-4-2-2.mse"], 11297 : ["d:/ymir work/pc/common/effect/armor/grun_shining.mse#d:/ymir work/pc/common/effect/armor/armor-4-2-1.mse"], 11298 : ["d:/ymir work/pc/common/effect/armor/armor-4-2-2.mse#d:/ymir work/pc/common/effect/armor/armor-4-2-1.mse"], 11299 : ["d:/ymir work/pc/common/effect/armor/armor-4-2-2.mse#d:/ymir work/pc/common/effect/armor/armor-4-2-1.mse"], 11259 : ["d:/ymir work/pc/common/effect/armor/armor-4-2-2.mse#d:/ymir work/pc/common/effect/armor/armor-4-2-1.mse"], 11269 : ["d:/ymir work/pc/common/effect/armor/armor-4-2-2.mse#d:/ymir work/pc/common/effect/armor/armor-4-2-1.mse"] } def LoadEffectTable(): for effect in EffectTable: for i in range(len(EffectTable[effect])): vnum = effect effectpath = EffectTable[effect][i] Shining.Add(vnum, effectpath) As you can see 2 Shinings are seperated with an "#". Last but no least import your file in your game and add the following line under the python constructor effecttable.LoadEffectTable() I Hope i didn't forgot anything
    2 points
  5. Hi guys, I'll show yout how to simply open your safebox by inventory button. 1) First you'll need to replace "def ClickMallButton" in "uiinventory.py" by : def ClickMallButton(self): self.choix = ui.BoardWithTitleBar() self.choix.SetSize(210, 80) self.choix.SetCenterPosition() self.choix.AddFlag('float') self.choix.AddFlag('movable') self.choix.SetTitleName("Ouverture entrepôt") self.choix.Show() self.EntrepotIs = ui.Button() self.EntrepotIs.SetEvent(self.OpenIs) self.EntrepotIs.SetParent(self.choix) self.EntrepotIs.SetPosition(35, 40) self.EntrepotIs.SetUpVisual("d:/ymir work/ui/public/middle_button_01.sub") self.EntrepotIs.SetOverVisual("d:/ymir work/ui/public/middle_button_02.sub") self.EntrepotIs.SetDownVisual("d:/ymir work/ui/public/middle_button_03.sub") self.EntrepotIs.SetText("ItemShop") self.EntrepotIs.SetToolTipText("Ouvrir l'entrepot ItemShop") self.EntrepotIs.Show() self.Magasinier = ui.Button() self.Magasinier.SetEvent(self._normal_mall) self.Magasinier.SetParent(self.choix) self.Magasinier.SetPosition(105, 40) self.Magasinier.SetUpVisual("d:/ymir work/ui/public/middle_button_01.sub") self.Magasinier.SetOverVisual("d:/ymir work/ui/public/middle_button_02.sub") self.Magasinier.SetDownVisual("d:/ymir work/ui/public/middle_button_03.sub") self.Magasinier.SetText("Magasinier") self.Magasinier.SetToolTipText("Ouvrir le magasinier") self.Magasinier.Show() 2) Then add this under : def OpenIs(self): self.EntrepotIs.Hide() self.choix.Hide() self.Magasinier.Hide() net.SendChatPacket("/click_mall") def _normal_mall(self): self.EntrepotIs.Hide() self.Magasinier.Hide() self.choix.Hide() net.SendChatPacket("/click_safebox") 3) Open cmd_general.cpp (game src) and search for : ACMD(do_click_mall) { ch->ChatPacket(CHAT_TYPE_COMMAND, "ShowMeMallPassword"); } then add this below : ACMD(do_click_safebox) { ch->ChatPacket(CHAT_TYPE_COMMAND, "ShowMeSafeboxPassword"); } 4) Open cmd.cpp (still game src) and search for : ACMD(do_click_mall); then add this below : ACMD(do_click_safebox); in same file search for : { "click_mall", do_click_mall, 0, POS_DEAD, GM_PLAYER }, and add this below : { "click_safebox", do_click_safebox, 0, POS_DEAD, GM_PLAYER }, 5) You'll need to remove distance limit to open safebox so open "char.cpp" and search for else if (GetDistanceFromSafeboxOpen() > 1000) { ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<â°í> °Å¸®°¡ ¸Ö¾î¼­ â°í¸¦ ¿­ ¼ö ¾ø½À´Ï´Ù.")); return; } here you juste need to comment this block, like this : /* else if (GetDistanceFromSafeboxOpen() > 1000) { ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<â°í> °Å¸®°¡ ¸Ö¾î¼­ â°í¸¦ ¿­ ¼ö ¾ø½À´Ï´Ù.")); return; } */ 6) You're done, now you'll get this menu (you will be able to choose between mall or safebox)
    1 point
  6. M2 Download Center Download Here ( Internal ) Download Here ( GitHub ) Since I have no use for this anymore whatsoever, I changed the repo to be public. Porting it to the source code should be fairly easy as most of the functions and such are the same (yay for LibM2) It includes: SyncPos fix with automatic ban /war fix number_ex fix HorseVnum and Bonus on Mount via Questflag (horse_summon.horse_vnum, horse_summon.apply_type, horse_summon.apply_value) Damage bonuses (devil, undead) are each calculated seperately. CHARACTER::DropGold just returns GiveExp was rewritten to prevent xp boosts and glitches 6th and 7th bonus cant be put on costumes anymore More quest functions: item2.equip item2.get_attr item2.get_wearflag item2.is_wearflag item2.set_attr npc2.get_level npc2.get_pc_pid npc2.get_pc_vid npc2.select pc2.give_or_drop_item_and_select pc2.send_effect pc2.set_level You may still donate XP to guilds when the guild is max. level You'll always get status points max. priv_empire is modifiable via config change_attr time is in seconds and modifiable via config you can add new/modify existing bonuses via config And some other changes I cant think of right now, just snoop through the source. iMer PS: Check the license. If you use any of that source and publish it (even in binary form) you must credit me.
    1 point
  7. Hi devs, I will give here is some enigma plugins Wpm(Anti Write Process Memory) [Hidden Content] [Hidden Content] Rpm(Anti Read process Memory) [Hidden Content] [Hidden Content] Ail(Anti Loadlibary) [Hidden Content] [Hidden Content] Regards.
    1 point
  8. M2 Download Center Download Here ( Internal ) Hello, I have completed this map and I would like to share it with you. It's 3x3 and conceived for farmers.‏ You should know how to implement it, if you don't just ask and I can make a tutorial.‏ Important:‏ Please do not release this without my permission elsewhere as it's only for CP-Community and metin2dev, if I see it on elitepvpers I will ask for it to be deleted. I hope you like the map, if you find any bug or similar let me know and I will fix it.
    1 point
  9. set the "szMasterBonusPoly" as you desire, I'll create a tutorial maybe. ^^
    1 point
  10. Remove the new motions type from the reef_attack_*.msa
    1 point
  11. @thiagosaliba, you should change m_IPMCounter to m_iPMCounter = 0;
    1 point
  12. People said his tools are also account stealers. Even though it's used for normal chat, you can directly use this inside CInputMain::Whisper instead of adding 23849243 data-members/member functions: if (ch->IncreaseChatCounter() >= 10) { // the rest of the code such as extra ban/kick return iExtraLen; } IncreaseChatCounter increases m_bChatCounter by 1, a variable resetted every 5 seconds to 0 via CHARACTER_MANAGER::Update.
    1 point
  13. No, the problem is in the game file, i think vanilla only edit the char.cpp, but need to edit on char_skill.cpp and guild.cpp if (IsAffectFlag(AFF_REVIVE_INVISIBLE)) RemoveAffect(AFFECT_REVIVE_INVISIBLE); to if (IsAffectFlag(AFFECT_REVIVE_INVISIBLE)) RemoveAffect(AFFECT_REVIVE_INVISIBLE);
    1 point
×
×
  • Create New...

Important Information

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