Jump to content

Search the Community

Showing results for tags 'fix'.

  • Search By Tags

    Type tags separated by commas.
  • Search By Author

Content Type


Forums

  • Metin2 Dev
    • Announcements
  • Community
    • Member Representations
    • Off Topic
  • Miscellaneous
    • Metin2
    • Showcase
    • File Requests
    • Community Support - Questions & Answers
    • Paid Support / Searching / Recruiting
  • Metin2 Development
  • Metin2 Development
    • Basic Tutorials / Beginners
    • Guides & HowTo
    • Binaries
    • Programming & Development
    • Web Development & Scripts / Systems
    • Tools & Programs
    • Maps
    • Quests
    • 3D Models
    • 2D Graphics
    • Operating Systems
    • Miscellaneous
  • Private Servers
    • Private Servers
  • Uncategorized
    • Drafts
    • Trash
    • Archive
    • Temporary
    • Metin2 Download

Product Groups

  • Small Advertisement
  • Large Advertisement
  • Advertising

Categories

  • Third Party - Providers Directory

Categories

  • Overview
  • Pages
    • Overview
    • File Formats
    • Network
    • Extensions

Find results in...

Find results that contain...


Date Created

  • Start

    End


Last Updated

  • Start

    End


Filter by number of...

Joined

  • Start

    End


Group


Pillory


Marketplace


Game Server


Country


Nationality


Github


Gitlab


Discord


Skype


Website

  1. Hey, Today i will show you how you can fix easy the invisibility effect bug and the AFFECT_EUNHYEONG = sealth ninja skill from 17.5 Official update. InstanceBase.cpp (Is hiding the ninja from the minimap) InstanceBaseEffect.cpp Search for: Replace with:
  2. M2 Download Center Download Here ( Internal ) Hi devs, today I will release the fix I made for the skill cooldown, already fixed on official servers, this is the bug it self: And this is the fix: Regards! Fix skill cooldown ~ Shang.rar ### root/ui.py ### Search: def SetSlotCoolTimeColor(self, slotIndex, r, g, b, a): wndMgr.SetSlotCoolTimeColor(self.hWnd, slotIndex, r, g, b, a) ### Add after: def StoreSlotCoolTime(self, key, slotIndex, coolTime, elapsedTime = 0.0): wndMgr.StoreSlotCoolTime(self.hWnd, key, slotIndex, coolTime, elapsedTime) def RestoreSlotCoolTime(self, key): wndMgr.RestoreSlotCoolTime(self.hWnd, key) Thanks to @Horinna for report that bug. Here's the fix: """ Find this: elif (not self.__CanUseSkillNow()) or (skillGrade != j): skillPage.SetSlotCount(realSlotIndex, 0) skillPage.DisableCoverButton(realSlotIndex) Add this under:""" skillPage.DeactivateSlot(realSlotIndex) # After the else, paste this: if player.IsSkillActive(slotIndex) and (skillGrade == j): # fix001 skillPage.ActivateSlot(realSlotIndex) # The if should look like this: if (skillGrade == skill.SKILL_GRADE_COUNT) and j == (skill.SKILL_GRADE_COUNT-1): skillPage.SetSlotCountNew(realSlotIndex, skillGrade, skillLevel) elif (not self.__CanUseSkillNow()) or (skillGrade != j): skillPage.SetSlotCount(realSlotIndex, 0) skillPage.DisableCoverButton(realSlotIndex) skillPage.DeactivateSlot(realSlotIndex) # fix else: skillPage.SetSlotCountNew(realSlotIndex, skillGrade, skillLevel) if player.IsSkillActive(slotIndex) and (skillGrade == j): # fix skillPage.ActivateSlot(realSlotIndex)
  3. In EterPackManager.cpp update this: bool CEterPackManager::Get(CMappedFile & rMappedFile, const char * c_szFileName, LPCVOID * pData) { if (m_iSearchMode == SEARCH_PACK_FIRST) { if (GetFromPack(rMappedFile, c_szFileName, pData)) return true; if (c_szFileName[1] != ':' && GetFromFile(rMappedFile, c_szFileName, pData)) { TraceError("%s", c_szFileName); // only for log. it's not an error. return true; } } if (m_iSearchMode == SEARCH_FILE_FIRST) { if (GetFromFile(rMappedFile, c_szFileName, pData)) return true; return GetFromPack(rMappedFile, c_szFileName, pData); } return false; } And bool CEterPackManager::isExist(const char * c_szFileName) { return isExistInPack(c_szFileName); } In CEterPackManager::GetFromFile comment if(m_bTryRelativePath) {.....} (not sure necessary, i did it in the past) In UserInterface set bPackFirst to true to not load from d:/ and false to load from d:/ bool bPackFirst = TRUE; bPackFirst = TRUE; There is a common problem on all metin2 sources. The game will first load the files which are in d:/ymir work folder and if you have a dvd/cd-rom with letter D the game will load very slow and have big fps drops (for some players the game can be unplayable). I know many players who had a dvd-rom with letter D and reported me how bad the client works. Using this solution: 1. The game will no longer load d:/ymir files. 2. Client will open faster, load the files faster. 3. Less fps drop. Normal metin2 client without fix and with a dvd-rom that has letter D assigned: [Hidden Content] After fix: [Hidden Content] Check this video:
  4. This video was presented to me yesterday and vietnam flashbacks came back to me to the first time I found out about this. Three years ago I thought it was just my client, maybe this part was deleted when it was not supposed to, but I guess it's not. Why does this work, I have absolutely no clue but it's amazing that it behaves like that. Let's get to fixing it. Open PythonPlayerSkill.cpp and add: DWORD dwMotionIndex = pSkillData->GetSkillMotionIndex(rkSkillInst.iGrade); DWORD dwLoopCount = pSkillData->GetMotionLoopCount(rkSkillInst.fcurEfficientPercentage); if (!pkInstMain->NEW_UseSkill(rkSkillInst.dwIndex, dwMotionIndex, dwLoopCount, pSkillData->IsMovingSkill() ? true : false)) { //Tracenf("CPythonPlayer::__UseSkill(%d) - pkInstMain->NEW_UseSkill - ERROR", dwSlotIndex); return false; } after: if (pSkillData->IsFanRange()) { if (pkInstMain->NEW_GetInstanceVectorInFanRange(float(dwRange), *pkInstTarget, &kVct_pkInstTarget)) { It should look like this: Literally the end.
  5. Hi guys, A guy reported to me a weird bug about shamans w/m which are skipping collision when they are too fast to attack. On default source files it is still an unresolved bug which appear when the shaman's attack speed is more than 145/150. here a video which show how it is not getting the damage text for each hit on the stone. here the FIX. ATTENTION: Since the problem is the InvisibleTime on Attack.msa which it is too high, we could think to reduce it without need to edit nothing in our source (and it may be more efficient), but honestly i preferred to make a function which calculating the "adjustment" of the invisible time using the speed attack to don't risk to get the reversed problem (2 damage on 1 hit when the attack speed is low) feel free to use one of the two options.
  6. So, @ Syreldar was making a quest for a server I am working on and, he noticed that after the value 255, the direction set was not working properly. For some reason, dir is an int almost everywhere, except his declaration in the struct and the two lua functions. I understand the int in the spawnmob function as a parameter, for the -1 thing to decide to make it random, but then, it should be a number between 0 and 359 but somehow they decided to go with an 8bits representation number (BYTE) So here we are fixing another korean mistake.. Go to regen.h, and replace: BYTE direction; with uint16_t direction; Go to questlua_dungeon.cpp, replace: BYTE dir = (int) lua_tonumber(L, 4); with uint16_t dir = static_cast<uint16_t>(lua_tonumber(L, 4)); both in dungeon_spawn_mob_dir_ac and dungeon_spawn_mob_dir (not needed but for consistency at this point..) Go to char_manager.cpp in: LPCHARACTER CHARACTER_MANAGER::SpawnMob(DWORD dwVnum, long lMapIndex, long x, long y, long z, bool bSpawnMotion, int iRot, bool bShow) add: if(iRot > 359){ iRot = 359; } before if (iRot == -1) iRot = number(0, 360); and that's it.
  7. Hello, today I saw that people are using the old collsion rendering code from ymir and I think its disgusting and useless to be honest. The new method is using wire framed 3d meshes instead of weird circles that look like a psychosis. You enable the collision rendering by opening the console and run the "collision" command Before: After: [Hidden Content] Once again thanks to everyone from sura-head. esp @HelloBrightness ( Amas ) and @CYN3. and thanks to @ TAUMPfor testing it.
  8. notice: it's my first release ever it will take years until im a profesionall c++ coder but it makes me alot of fun and i will push my knowledge forward fix is only for people that using v0.3 of lennt's shoulderband-system. EterGrnLib/ThingInstance.cpp on "void CGraphicThingInstance::DeformNoSkin()" under CGrannyLODController * pkLOD = m_LODControllerVector[i]; if (!pkLOD->isModelInstance()) continue; make a new line and paste this code if (pkLOD->isModelInstance()) // if you want it a bit pretty pkLOD->Deform(&m_matAbsoluteTrans); // u could rewrite this whole c++ code to be pretty still in EterGrnLib/ThingInstance.cpp on "void CGraphicThingInstance::OnDeform()" under CGrannyLODController * pkLOD = m_LODControllerVector[i]; if (!pkLOD->isModelInstance()) continue; make a new line and paste this code if (pkLOD->isModelInstance()) // but anyway cute kitty known as meleys pkLOD->Deform(&m_matAbsoluteTrans); // fix it for the little people out theere Notice: inside the c++ code of the system - official pet system - some code is missing and u will need a solution for evolution too ! LICENSE: if you wanna share this solution on others boards please link my name as reference and my profile link thank you for listening to me THANKS GO'S TO: @Weedhex helping me and teach me a bit C++ ! @xP3NG3Rx releasing the patches that i need sometimes ! @V0lvox he teach me a bit C++ ! @Sandworks for showing me how to work with a world editor ! @Raylee because correct me if i making mistakes and i make alot of them ! @ChuckNorris & @Polux because you two are the greatest admins ! @Helia01 for the Maintaince Solution ! @Anix because you are a good friend ! (we will find the beta client) !! @martysama because i love this guy hes my idol and someday i will be so good like you in C++ ! @Tim66613 - if u read this you was one of my idols in the past im active since 2003/2004 - ! @Syriza for helping me also ! @Kori - for not giving me up sometimes - i know i can be sometimes a asshole, crazy as hell,anoying but i also have a good heart and i think u see it i add this text after his answer maybe he see it someday ! AND ALL THE OTHERS THAT NOT LISTED HERE I JUST WANNA SAY ALL OF YOU - THANK YOU - BECAUSE WITHOUT YOU ALL I WOULD BE NOTHING ! AND THIS COMES FROM MA HEART TO YOU !
  9. Hello I found a base bug and I have found its solution. I share it with you with tests. Bug 1: Many times when attacking with Sword Strike the damage fails and this damage behavior varies very strange. Fix: Remove CRUSH flag from skill_proto (index 20) Bug 2: The damage of Sword Strike is too low compared to the other skills of your group. Fix: Change eSkillType from MELEE to RANGE in skill_proto (index 20) Testing bug 1: [Hidden Content]
  10. Download Center Github or Internal Link With this 'system' you will be able to open the PM Window just by clicking on the Player Name on any Chat Category not only on Global (normal, group, guild...) I use martysama so if you use anything else you need to edit it for your sources. Because i did not found an full tutorial here it is, is not perfect i know. Preview: [Hidden Content] Bellow is just an example, follow the tutorial on github or download it from dev. Pack Search inside interfacemodule.py and edit it like bellow: def MakeHyperlinkTooltip(self, hyperlink): tokens = hyperlink.split(":") if tokens and len(tokens): type = tokens[0] if "item" == type: self.hyperlinkItemTooltip.SetHyperlinkItem(tokens) # Add this under like here elif "msg" == type and str(tokens[1]) != player.GetMainCharacterName(): self.OpenWhisperDialog(str(tokens[1])) Server Srcs Search inside input_main.cpp and make the changes like bellow: // With Chat Color #ifdef ENABLE_CHAT_COLOR_SYSTEM static const char* colorbuf[] = {"|cFFffa200|H|h[Staff]|h|r", "|cFFff0000|H|h[Shinsoo]|h|r", "|cFFffc700|H|h[Chunjo]|h|r", "|cFF000bff|H|h[Jinno]|h|r"}; int len = snprintf(chatbuf, sizeof(chatbuf), "%s |Hmsg:%s|h%s|h|r : %s", (ch->IsGM()?colorbuf[0]:colorbuf[MINMAX(0, ch->GetEmpire(), 3)]), ch->GetName(), ch->GetName(), buf); #endif // Without Chat Color just change it like this int len = snprintf(chatbuf, sizeof(chatbuf), "|Hmsg:%s|h%s|h|r : %s", ch->GetName(), ch->GetName(), buf); Source @ Sanchez Client Srcs Search inside PythonNetworkStreamPhaseGame.cpp bool CPythonNetworkStream::RecvChatPacket() { .. // Search this like case CHAT_TYPE_WHISPER: { .. } .. } And add this inside the case, like this:
  11. Hey there! I've come across this bug where the female Ninja attacks with the bow much more faster than the male Ninja. I did not find the fix anywhere on this forum, so I decided to write the actual FIX for this issue. What's the cause of this BUG? The issue is with the duration of the animation file (attack.gr2), where the male Ninja's animation takes 1.5 seconds, while the female Ninja's takes 1 second. Ymir basically did not verify the duration of the anim for both femal and male So, let's fix this bug once and for all. I found the corrected attack.gr2 animation file, with both genders now having the attack set to 1 second. By replacing the files in your client with the ones from the archive, you will resolve this issue. Before the FIX (gif): [Hidden Content] After the FIX (gif): [Hidden Content] Download:
  12. 1) my msm gr2 server_client all ready good working 2) data/client msm/gr2/etc all ready good working i have this bug on 2023 again and again on my pc with anydesk 5 develope from france for see this problem We fixed it (temporarily) My server working BEST without bug mount (temporarily for find an even better fix) 1) OPEN INPUT_MAIN 2) SEARCH: const float fDist = DISTANCE_SQRT ((ch->GetX() - pinfo->lX) / 100, (ch->GetY() - pinfo->lY) / 100); if (((false == ch->IsRiding() && fDist > 750) || fDist > 999) && OXEVENT_MAP_INDEX != ch->GetMapIndex()) { sys_log (0, "MOVE: %s trying to move too far (dist: %.1fm) Riding(%d)", ch->GetName(), fDist, ch->IsRiding()); ch->Show (ch->GetMapIndex(), ch->GetX(), ch->GetY(), ch->GetZ()); ch->Stop(); return; } 3) ADD AFTER if (true == ch->IsRiding()) { ch->UpdateSectree(); }
  13. Hi, I will share with you the solution of a general problem that occurs in infrastructures such as MartySama that use an account recording system over REGISTRY. When you save your account, the data is saved in the Windows Registry, as shown in the example below. Everything is great, the system is exactly what we wanted. Account information is no longer saved in files in the client. However, there is a problem. Players have this problem. If you save your character information using Turkish characters, the client does not open and gives an error. It states that you have a problem with characters used on a system that supports ASCII encoding. Check This ; LoginWindow.__LoadScript.BindObject - <type 'exceptions.UnicodeEncodeError'>:'ascii' codec can't encode character u'\xe7' in position 8: ordinal not in range(128) To resolve this, follow the steps below. Root/Intrologin.py find in "def SAB_Click_Save(self, slot):" if len(id) == 0: self.PopupNotifyMessage(localeInfo.LOGIN_INPUT_ID, self.SetIDEditLineFocus) return Add this just above the code if any(ord(char) > 127 for char in id + pwd): self.PopupNotifyMessage(localeInfo.TURKISH_WORDS) return It will be enough to add the following message anywhere in locale_game.txt TURKISH_WORDS Please do not use Turkish characters when registering your account! It's done! A few things I want to point out. 1. I am not a perfect developer, I have Python knowledge and this is how I found a solution. It's short and it works. 2. If you have a better solution suggestion, please specify. Instead of making fun of me, I ask you to respect the way I try to be useful to the community. 3. I had another account on Metin2.dev but I forgot the information so I created a new account. Moderators please understand me ^^ Kind Regards.
  14. This vulnerability should affect every server. You can duplicate item rewards, and also crash the server through dangling pointers. The danger of this bug escalates to how many custom systems, and how many crafting quests (for example, the vitality ore quest, not the cube system) you have in your server. How to trigger it: Any quest that uses select & wait, and the item lua module after that is vulnerable. After the server uses select() or wait(), the player's quest state is suspended. After the player replies using the CG packet, the quest state is recovered. So what's wrong with it? It doesn't verify if the stored quest item ptr expired. You basically need to destroy the selected item ptr in order to dupe the rewards of the quest. After some tries, you may get a core crash in the game. (dangling pointers often cause crashes only after that memory sector has been rewritten) In my files, I've checked (since several years ago) if the quest state was suspended for the the default windows such as exchange, cube, shop. This bug can work very easily on offline shops or other new systems that don't check that. After the select() or wait() is called, you send the selected item to the (e.g.) offlineshop system window. It will delete the item ptr in the game. Now, you can press "Ok" on the quest, and the quest will proceed as if the item still existed. The item still exists in the offlineshop, but not the item ptr anymore. The item won't be deleted by the quest even after item.remove() is called. This is the fix: diff --git a/s3ll_server/Srcs/Server/game/src/char.cpp b/s3ll_server/Srcs/Server/game/src/char.cpp index 0ea307fa..65b1dd65 100644 --- a/s3ll_server/Srcs/Server/game/src/char.cpp +++ b/s3ll_server/Srcs/Server/game/src/char.cpp @@ -303,7 +303,10 @@ void CHARACTER::Initialize() m_dwQuestNPCVID = 0; m_dwQuestByVnum = 0; - m_pQuestItem = NULL; + m_dwQuestItemVID = 0; m_dwUnderGuildWarInfoMessageTime = get_dword_time()-60000; @@ -6123,33 +6126,37 @@ LPCHARACTER CHARACTER::GetQuestNPC() const void CHARACTER::SetQuestItemPtr(LPITEM item) { - m_pQuestItem = item; + m_dwQuestItemVID = (item) ? item->GetVID() : 0; } void CHARACTER::ClearQuestItemPtr() { - m_pQuestItem = NULL; + m_dwQuestItemVID = 0; } LPITEM CHARACTER::GetQuestItemPtr() const { - return m_pQuestItem; + if (!m_dwQuestItemVID) + return nullptr; + return ITEM_MANAGER::Instance().FindByVID(m_dwQuestItemVID); } diff --git a/s3ll_server/Srcs/Server/game/src/char.h b/s3ll_server/Srcs/Server/game/src/char.h index cc4da2bb..74b3470e 100644 --- a/s3ll_server/Srcs/Server/game/src/char.h +++ b/s3ll_server/Srcs/Server/game/src/char.h @@ -1674,9 +1674,9 @@ class CHARACTER : public CEntity, public CFSM, public CHorseRider private: DWORD m_dwQuestNPCVID; DWORD m_dwQuestByVnum; - LPITEM m_pQuestItem; + DWORD m_dwQuestItemVID{}; // @fixme304 (LPITEM -> DWORD) // Events To unlock the client in order to move your windows with a quest open, you edit this from interfacemodule.py: You can even Hide the TopBar and BottomBar from uiQuest.py for a better result. Important: after this fix, the item ptr may be nullptr after they press enter, so you need to check if the item ptr is still valid by using this function: ALUA(item_is_available) { auto item = CQuestManager::instance().GetCurrentItem(); lua_pushboolean(L, item != nullptr); return 1; } ... { "is_available", item_is_available }, // [return lua boolean] By simply doing: when 169.take begin local s1=select("Yes", "No") if s1==2 then return end if not item.is_available() then return end end If you want to tryhard, and be sure that the item ptr didn't get swapped, you can do as following via quest:
  15. Hello everyone. Here is a little snippet for the chat history. I made this to turn back the "All" state if you turn off every each button.
  16. Download Metin2 Download Hi Guys, I m pretty sure most of you perfectly know what i m meaning for "DEVIL TOWER LAG AFTER WARP", It's a critical FPS Drop which happen very often just after a warp in a dungeon. I ve found the way to definitely fix it with a few lines short change. Just to spend a few words for those who want to understand something before copying and pasting the fix here is the explanation of the bug: Here is the code: DOWNLOAD ZIP
  17. Disclaimer: This fix is intended for correct server data. I really advise you not to ban any player based on data gathered by this, but just to take into consideration that one player appearing a lot in this list (in different maps) is suspicious. I strongly recommend you to inspect which mobs are problematic for false positives, then to fix them. Hello everyone, While working on some clientside thing. I noticed one big exploit that I was able to reproduce. Long story short, I was basically able to extend any collision and be able to reproduce (in a makeshift dirty way) the famous "kill aura" or whatever you call it. Basically allowing you to hit monsters from really far away without any problem. That's one of the most common thing the bots are using. Videos of the bug: Spoiler Videos of the fix: Spoiler The fix Spoiler [Hidden Content] Have a nice day!
  18. Hello friends and enemies, ladies and gentlemans, I was playing with my introEmpire.py and as always I got an obstacle in my way, the "select empire phase" was not working properly. BEFORE(ymir): - Client was receiving a random number(1,3) if you didn't had an empire selected. - Packet that sends "simple information" to the client was called after changing the phase to "select phase". AFTER: - Client is receiving correctly the empire ID. - Client is initializing the "select empire" phase if you have no characters on your account (if pid columns in table player.player_index are set on 0) NOTE: - Other bugs not tested yet but everything seems to be OK for now ... - Need to do something about the remaining row in player.player_index table after deleting all the characters on the account.(too lazy, too sleepy now 6:33 AM ...) Here is the FIX(minimalist tutorial): root/introSelect.py (disabling the reselectempire phase) game/src/input_db.cpp
  19. Disable loading BGM music/sounds when the player has the Volume set on 0.0 I speak about this ones when you open the client, login, select character, loading. 0706 17:55:00831 :: BGM/login_window.mp3 > 304 kb 0706 17:55:08657 :: BGM/characterselect.mp3 > 472 kb 0706 17:55:19083 :: BGM/enter_the_east.mp3 > 3.14 mb But you can add the maps with specific songs to the list... 0706 18:26:21453 :: BGM/desert.mp3 > 3.61 mb 0706 18:36:17583 :: BGM/follow_war_god.mp3 > 4.63 mb 0706 18:38:00674 :: BGM/save_me.mp3 > 2.90 mb ... and more Inside the Client Srcs file: SoundManager.cpp (MilesLib) Search for the function and make the changes like bellow: void CSoundManager::PlayMusic(DWORD dwIndex, const char * c_szFileName, float fVolume, float fVolumeSpeed) { # add this if (GetMusicVolume() == 0.0) return; # add this if (dwIndex >= CSoundManagerStream::MUSIC_INSTANCE_MAX_NUM) return; ... } The only one bug problem is that when an player changes an song with the volume 0 it will not load (ty @ Karbust) this can be fixed from python (root/uisystemoption.py) When the player is choosing any song set the volume to 5/10% then load the mp3 file. def __OnChangeMusic(self, fileName): # you can try snd.SetMusicVolume(0.1 * net.GetFieldMusicVolume()) systemSetting.SetMusicVolume(0.1) Sorry if it did not help you, and however to see the files loading without any use... It bothers me. If you have an better way post it bellow and i will update the topic.
  20. Hey M2DEV! Today I will show you how to fix one unpleasant error related to the auto attack. When you attack a monster automatically and for example want to move away from the monster, what do you do? Probably you will turn off the auto attack and try to move away from the monster using the WASD keys? Yes, but it won't work because the target doesn't reset when you try to disable the auto-attack. Before fix: [Hidden Content] After fix: [Hidden Content] Open file: UserInterface\PythonPlayer.h Make "__ClearAutoAttackTargetActorID();" public! Open file: UserInterface\PythonPlayerModulec.cpp We need to create a new method PyObject * playerClearAutoAttackTargetActorID(PyObject* poSelf, PyObject* poArgs) { CPythonPlayer::Instance().__ClearAutoAttackTargetActorID(); return Py_BuildNone(); } add method to s_methods[] { "ClearAutoAttackTargetActorID", playerClearAutoAttackTargetActorID, METH_VARARGS }, Compile bin! Open file: root/uitaskbar.py search elif self.EVENT_MOVE_AND_ATTACK == event: replace this part: elif self.EVENT_MOVE_AND_ATTACK == event: btn = self.mouseModeButtonList[dir].GetChild("button_move_and_attack") func = player.MBF_SMART player.ClearAutoAttackTargetActorID() tooltip_text = localeInfo.TASKBAR_ATTACK pack root file! P.S Please forgive me for my English, I use a GoogleTranslate
  21. I noticed one bug with specular, probably every server has it, simply ymir bug. I've never played much metin but now it happened to me on the server so I searched searched but couldn't find anything then a guy named @rid gave me a fix no problem without paying and even wrote me that I can post it on the forum so here you are. [Hidden Content] Thanks @rid for share his fix.
  22. For all the years I had been actively dismissing the problem of the misaligned cursor in the text edit box when centred. The day finally came that I fixed it. Broken Fixed [Hidden Content]
  23. Premise: I don't know whether you have this system from a free release elsewhere or you bought it and I have no idea if they are the same or not (even though the same version can be found in the first server files of Rubinum). There are two issues I was concerned with: -creating an item when you request the infos -putting the mob data dictionary in constinfo The first is if you have, in CreateDropItemVector function something like this: if (item) vec_item.push_back(item); So, we create an item and we do nothing with it, staying in memory for no purpose. Instead, we can use a vector of pairs. Open item_manager.h Replace bool CreateDropItemVector(LPCHARACTER pkChr, LPCHARACTER pkKiller, std::vector<LPITEM> & vec_item); with: bool CreateDropItemVector(LPCHARACTER pkChr, LPCHARACTER pkKiller, std::vector<std::pair<int,int> > & vec_item); Now, open item_manager.cpp Replace bool ITEM_MANAGER::CreateDropItemVector(LPCHARACTER pkChr, LPCHARACTER pkKiller, std::vector<LPITEM> & vec_item) With bool ITEM_MANAGER::CreateDropItemVector(LPCHARACTER pkChr, LPCHARACTER pkKiller, std::vector<std::pair<int,int> > & vec_item) and remove LPITEM item = NULL; and edit the function accordingly. EX for common_drop_item, replace: std::vector<CItemDropInfo>::iterator it = g_vec_pkCommonDropItem[bRank].begin(); while (it != g_vec_pkCommonDropItem[bRank].end()) { const CItemDropInfo & c_rInfo = *(it++); if (iLevel < c_rInfo.m_iLevelStart || iLevel > c_rInfo.m_iLevelEnd) continue; TItemTable * table = GetTable(c_rInfo.m_dwVnum); if (!table) continue; item = NULL; if (table->bType == ITEM_POLYMORPH) { if (c_rInfo.m_dwVnum == pkChr->GetPolymorphItemVnum()) { item = CreateItem(c_rInfo.m_dwVnum, 1, 0, true); if (item) item->SetSocket(0, pkChr->GetRaceNum()); } } else item = CreateItem(c_rInfo.m_dwVnum, 1, 0, true); if (item) vec_item.push_back(item); } with std::vector<CItemDropInfo>::iterator it = g_vec_pkCommonDropItem[bRank].begin(); while (it != g_vec_pkCommonDropItem[bRank].end()) { const CItemDropInfo & c_rInfo = *(it++); if (iLevel < c_rInfo.m_iLevelStart || iLevel > c_rInfo.m_iLevelEnd) continue; TItemTable * table = GetTable(c_rInfo.m_dwVnum); if (!table) continue; if(c_rInfo.m_dwVnum > 70103 && c_rInfo.m_dwVnum < 70108) { if (c_rInfo.m_dwVnum != pkChr->GetPolymorphItemVnum()) { continue; } } vec_item.push_back(std::make_pair(c_rInfo.m_dwVnum, 1)); } (edit 70103 and 70108 accordingly with your Polymorph Marble vnums The whole function should look like this: bool ITEM_MANAGER::CreateDropItemVector(LPCHARACTER pkChr, LPCHARACTER pkKiller, std::vector<std::pair<int,int> > & vec_item) { if (pkChr->IsPolymorphed() || pkChr->IsPC()) { return false; } int iLevel = pkKiller->GetLevel(); BYTE bRank = pkChr->GetMobRank(); std::vector<CItemDropInfo>::iterator it = g_vec_pkCommonDropItem[bRank].begin(); while (it != g_vec_pkCommonDropItem[bRank].end()) { const CItemDropInfo & c_rInfo = *(it++); if (iLevel < c_rInfo.m_iLevelStart || iLevel > c_rInfo.m_iLevelEnd) continue; TItemTable * table = GetTable(c_rInfo.m_dwVnum); if (!table) continue; if(c_rInfo.m_dwVnum > 70103 && c_rInfo.m_dwVnum < 70108) { if (c_rInfo.m_dwVnum != pkChr->GetPolymorphItemVnum()) { continue; } } vec_item.push_back(std::make_pair(c_rInfo.m_dwVnum, 1)); } // Drop Item Group { itertype(m_map_pkDropItemGroup) it; it = m_map_pkDropItemGroup.find(pkChr->GetRaceNum()); if (it != m_map_pkDropItemGroup.end()) { typeof(it->second->GetVector()) v = it->second->GetVector(); for (DWORD i = 0; i < v.size(); ++i) { vec_item.push_back(std::make_pair(v[i].dwVnum, v[i].iCount)); } } } // MobDropItem Group { itertype(m_map_pkMobItemGroup) it; it = m_map_pkMobItemGroup.find(pkChr->GetRaceNum()); if ( it != m_map_pkMobItemGroup.end() ) { CMobItemGroup* pGroup = it->second; if (pGroup && !pGroup->IsEmpty()) { const CMobItemGroup::SMobItemGroupInfo& info = pGroup->GetOne(); vec_item.push_back(std::make_pair(info.dwItemVnum, info.iCount)); } } } // Level Item Group { itertype(m_map_pkLevelItemGroup) it; it = m_map_pkLevelItemGroup.find(pkChr->GetRaceNum()); if ( it != m_map_pkLevelItemGroup.end() ) { if ( it->second->IsInLevelRange((DWORD)iLevel) ) { typeof(it->second->GetVector()) v = it->second->GetVector(); for ( DWORD i=0; i < v.size(); i++ ) { DWORD dwVnum = v[i].dwVNum; vec_item.push_back(std::make_pair(dwVnum, v[i].iCount)); } } } } // ETC DropItem if (pkChr->GetMobDropItemVnum()) { itertype(m_map_dwEtcItemDropProb) it = m_map_dwEtcItemDropProb.find(pkChr->GetMobDropItemVnum()); if (it != m_map_dwEtcItemDropProb.end()) { vec_item.push_back(std::make_pair(pkChr->GetMobDropItemVnum(), 1)); } } //Metin if (pkChr->IsStone()) { if (pkChr->GetDropMetinStoneVnum()) { vec_item.push_back(std::make_pair(pkChr->GetDropMetinStoneVnum(), 1)); } } return vec_item.size(); } Note: level item group and drop item group might be different because in my files i have a level_limit_max token and, for drop_item_group, I don't expect to put a Polymorph Marble. Also it's missing the buyertheifgloves item group, but you can clearly see the pattern and modify accordingly. Edit : I found a bug in the mob_drop_item infos. If you don't know, with the type "kill", you drop only one of the items you put in the list, so the info drop, well, will show only one, and then another, and another one, every time you reopen it. To fix this issue, go to item_manager.h and search for: const SMobItemGroupInfo& GetOne() const { return m_vecItems[GetOneIndex()]; } Add after: std::vector<std::pair<int,int>> GetVector() { std::vector<std::pair<int,int>> item_list; for(auto &x : m_vecItems) item_list.emplace_back(std::make_pair(x.dwItemVnum,x.iCount)); return item_list; } then, in item_manager.cpp, instead of: if (pGroup && !pGroup->IsEmpty()) { const CMobItemGroup::SMobItemGroupInfo& info = pGroup->GetOne(); vec_item.push_back(std::make_pair(info.dwItemVnum, info.iCount)); } replace it with: if (pGroup && !pGroup->IsEmpty()) { auto vec_items = pGroup->GetVector(); for(auto &x : vec_items) vec_item.push_back(std::make_pair(x.first,x.second)); } Side Note (how to add drop of the Stones from Metins server side): Before return vec_item.size(); you can also organize the vector as you want or create another one with a certain structure, like, first the common drop items, then the advance items or whatever, you can also clear it for what I care. Me, for example, I sort it to have all the vnums from the smallest to the largest. You can do that by: std::sort(vec_item.begin(), vec_item.end(), std::less<std::pair<int,int> >()); Now, let's go to input_main.cpp Remove: LPITEM pkInfoItem; We don't use an item anymore, remember? So now replace: static std::vector<LPITEM> s_vec_item; with: static std::vector<std::pair<int,int> > s_vec_item; Then replace: if (ITEM_MANAGER::instance().CreateDropItemVector(m_pkChrTarget, ch, s_vec_item) && (m_pkChrTarget->IsMonster() || m_pkChrTarget->IsStone())) with: if ((m_pkChrTarget->IsMonster() || m_pkChrTarget->IsStone()) && ITEM_MANAGER::instance().CreateDropItemVector(m_pkChrTarget, ch, s_vec_item)) This way also, if you target a player or a NPC, it will not trigger the CreateDropItemVector function. Remove everything inside the function if (s_vec_item.size() == 0); //this is useless else if (s_vec_item.size() == 1) //even more useless Just put: for(std::vector<std::pair<int,int> >::const_iterator iter = s_vec_item.begin(); iter != s_vec_item.end();++iter) { pInfo.dwVID = m_pkChrTarget->GetVID(); pInfo.race = m_pkChrTarget->GetRaceNum(); pInfo.dwVnum = iter->first; pInfo.count = iter->second; ch->GetDesc()->Packet(&pInfo, sizeof(TPacketGCTargetInfo)); } That's it. Now the constinfo issue. So, open constinfo.py and remove: import app if app.ENABLE_SEND_TARGET_INFO: MONSTER_INFO_DATA = {} Open uitarget.py and after the imports add: MONSTER_INFO_DATA = {} and replace whatever declaration with constinfo.MONSTER_INFO_DATA with just MONSTER_INFO_DATA Now open game.py. Even here, replace constinfo.MONSTER_INFO_DATA with uiTarget.MONSTER_INFO_DATA Last little fix, open intrologin.py Search for: self.stream.SetLoginInfo(id, pwd) the one in: def __OnClickLoginButton(self): add before uiTarget.MONSTER_INFO_DATA.clear() This should fix the issue when you don't close the client and, if you change the drop, you still see the older drop. Now you may ask, why all the other servers who may have this have never crashed or imploded? To be fair, I don't know and I don't care. Just know, if your system is similar to this, be aware of the issues and that this is one but definitely not the only fix possible.
  24. Hello, Most of you maybe know the exploit in combination with inventory sorting and channel changer, but it's also possible with a small script and no other systems involved. Thanks to Fliegex3 / Colossus. [Hidden Content] char_item.cpp in bool CHARACTER::MoveItem(TItemPos Cell, TItemPos DestCell, WORD count) find if (!IsValidItemPosition(DestCell)) { return false; } add if (Cell.cell == DestCell.cell) return false;
  25. There is a nasty bug where sometimes some items are not loaded in the safebox. This problem occurs because the function that interprets the data from the set packet (RecvSafeBoxSetPacket) is called too early. Fix: // PythonNetworkStream.cpp // 1. Search: Set(HEADER_GC_SAFEBOX_SET, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCItemSet), STATIC_SIZE_PACKET)); // 1. Replace with: Set(HEADER_GC_SAFEBOX_SET, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCItemSet2), STATIC_SIZE_PACKET));
×
×
  • 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.