Premium filipw1 1931 Posted April 25, 2020 Premium Share Posted April 25, 2020 (edited) When you are changing attributes in your item for every-single attribute server sends update packet to client, which is up to 4 unnecessary packets per one change. You must agree this is pointless. If you use bonus switcher and, let's say, with 500ms delay for 7 items it is 5 * 7 * 2 update packets per second. Going lower with delay you will get absurd amount of those packets. Another issue is you are not able to read attributes, I mean, avarage human cannot. After digging in code I got rid of redundant packets and received smoother in-game experience Spoiler item.cpp // search for: CItem::CItem(DWORD dwVnum) : m_dwVnum(dwVnum), m_bWindow(0), m_dwID(0), m_bEquipped(false), m_dwVID(0), m_wCell(0), m_dwCount(0), m_lFlag(0), m_dwLastOwnerPID(0), m_bExchanging(false), m_pkDestroyEvent(NULL), m_pkUniqueExpireEvent(NULL), m_pkTimerBasedOnWearExpireEvent(NULL), m_pkRealTimeExpireEvent(NULL), m_pkExpireEvent(NULL), m_pkAccessorySocketExpireEvent(NULL), m_pkOwnershipEvent(NULL), m_dwOwnershipPID(0), m_bSkipSave(false), m_isLocked(false), m_dwMaskVnum(0), m_dwSIGVnum (0) { memset( &m_alSockets, 0, sizeof(m_alSockets) ); memset( &m_aAttr, 0, sizeof(m_aAttr) ); } // extend it with ", m_bIsChangingAttr(false)" like shown: CItem::CItem(DWORD dwVnum) : m_dwVnum(dwVnum), m_bWindow(0), m_dwID(0), m_bEquipped(false), m_dwVID(0), m_wCell(0), m_dwCount(0), m_lFlag(0), m_dwLastOwnerPID(0), m_bExchanging(false), m_pkDestroyEvent(NULL), m_pkUniqueExpireEvent(NULL), m_pkTimerBasedOnWearExpireEvent(NULL), m_pkRealTimeExpireEvent(NULL), m_pkExpireEvent(NULL), m_pkAccessorySocketExpireEvent(NULL), m_pkOwnershipEvent(NULL), m_dwOwnershipPID(0), m_bSkipSave(false), m_isLocked(false), m_dwMaskVnum(0), m_dwSIGVnum (0), m_bIsChangingAttr(false) { memset( &m_alSockets, 0, sizeof(m_alSockets) ); memset( &m_aAttr, 0, sizeof(m_aAttr) ); } // search for: m_bSkipSave = false; // add below: m_bIsChangingAttr = false; // search for: if (!m_pOwner || !m_pOwner->GetDesc()) return; // add below: if (IsChangingAttr()) return; item.h // search for: DWORD GetSIGVnum() const { return m_dwSIGVnum; } // add below: public: bool IsChangingAttr() { return m_bIsChangingAttr; } void SetChangingAttr(bool changing) { m_bIsChangingAttr = changing; } private: bool m_bIsChangingAttr; item_attribute.cpp // inside function "ChangeAttribute" search for: int iAttributeCount = GetAttributeCount(); // add below: SetChangingAttr(true); // inside function "ChangeAttribute" search for: for (int i = GetAttributeCount(); i < iAttributeCount; ++i) { if (aiChangeProb == NULL) { PutAttribute(tmpChangeProb); } else { PutAttribute(aiChangeProb); } } // add below: SetChangingAttr(false); UpdatePacket(); This how it looks for 150ms switch delay: gif With my fix: gif Download: This is the hidden content, please Sign In or Sign Up Edited September 4, 2022 by Metin2 Dev Core X - External 2 Internal 60 1 1 2 11 3 30 Link to comment Share on other sites More sharing options...
Leafxc 1 Posted April 25, 2020 Share Posted April 25, 2020 (edited) 4 hours ago, filipw1 said: When you are changing attributes in your item for every-single attribute server sends update packet to client, which is up to 4 unnecessary packets per one change. You must agree this is pointless. If you use bonus switcher and, let's say, with 500ms delay for 7 items it is 5 * 7 * 2 update packets per second. Going lower with delay you will get absurd amount of those packets. Another issue is you are not able to read attributes, I mean, avarage human cannot. After digging in code I got rid of redundant packets and received smoother in-game experience This how it looks for 150ms switch delay: gif With my fix: gif Download: This is the hidden content, please Sign In or Sign Up Good Job Mind telling me why you recorded 2 diff. clients? Edited September 4, 2022 by Metin2 Dev Core X - External 2 Internal 1 Link to comment Share on other sites More sharing options...
Premium filipw1 1931 Posted April 27, 2020 Author Premium Share Posted April 27, 2020 On 4/25/2020 at 8:03 PM, Leafxc said: Good Job Mind telling me why you recorded 2 diff. clients? I have an old server project on my pc, I used it to demonstrate problem, since I don't have this fix there, then I used another server project I'm working on Link to comment Share on other sites More sharing options...
Honorable Member xP3NG3Rx 19679 Posted October 22, 2021 Honorable Member Share Posted October 22, 2021 (edited) I would like to mention here a minor bugfix about the update packets which cause the lags on changing attributes (maybe with manual mouse drag only? dunno). I hope it is visible on the video, if not just test it by yourself. Spoiler https://metin2.download/picture/WVGShIHhrtef2On3f7P19Tn6553kIOdz/.gif What you need to do with these microlags is easy, just open the interfaceModule.py and there inside the Interface class you will find a function which is the RefreshInventory. Every different window which has refreshable item grid, it runs down from there even if the windows isn't opened. This cause the fps drop which is visible even with human eyes. The solution is, you have to put an (IsShow) if statement before they run down like the way how it looks like on my side: def RefreshInventory(self): self.wndTaskBar.RefreshQuickSlot() if self.wndInventory and self.wndInventory.IsShow(): self.wndInventory.RefreshItemSlot() if app.ENABLE_DRAGON_SOUL_SYSTEM: if self.wndDragonSoul and self.wndDragonSoul.IsShow(): self.wndDragonSoul.RefreshItemSlot() if app.ENABLE_EXTEND_INVEN_SYSTEM and app.ENABLE_SEPARATED_EXTEND_INVEN_WINDOW: if self.wndInventoryEx and self.wndInventoryEx.IsShow(): self.wndInventoryEx.RefreshItemSlot() if app.ENABLE_MOVE_COSTUME_ATTR or app.ENABLE_MOVE_SASH_ATTR: if app.GetMoveAttrWindowOpen(): if self.wndItemCombination and self.wndItemCombination.IsShow(): self.wndItemCombination.RefreshCombSlotWindow() if app.ENABLE_SHOULDER_SASH_SYSTEM: if player.GetAcceRefineWindowOpen(): if self.wndAcce and self.wndAcce.IsShow(): self.wndAcce.RefreshAcceWindow() if app.ENABLE_CHANGE_LOOK_SYSTEM: if player.GetChangeLookWindowOpen(): if self.wndChangeLook and self.wndChangeLook.IsShow(): self.wndChangeLook.RefreshChangeLookWindow() if self.wndAttr67Add and self.wndAttr67Add.IsShow(): self.wndAttr67Add.RefreshAttr67Window() if app.ENABLE_AURA_SYSTEM: if player.IsAuraRefineWindowOpen(): if self.wndAura and self.wndAura.IsShow(): self.wndAura.RefreshAuraWindow() Edited August 28, 2022 by Metin2 Dev Core X - External 2 Internal 46 1 1 1 13 1 7 Link to comment Share on other sites More sharing options...
Premium WeedHex 635 Posted October 22, 2021 Premium Share Posted October 22, 2021 See also about char_item.cpp in the case, on change attr. Lot of heavy code and logs every application. Many people use it from OnUpdate python, and it's bad for the whole server Link to comment Share on other sites More sharing options...
sxvoyz 61 Posted December 14, 2021 Share Posted December 14, 2021 In CPythonNetworkStream::RecvItemUpdatePacket() we got 2x `RefreshInventory` function' callback. First in rkPlayer.SetItemCount(packet_item_update.Cell, packet_item_update.count); Second is in before `return true;` You can comment `RefreshInventory` callback in SetItemCount but you have to remember about dss refine window. After remove that line, stones will not update themselves. Link to comment Share on other sites More sharing options...
Mafia83 3 Posted April 4, 2023 Share Posted April 4, 2023 (edited) On 10/22/2021 at 2:16 PM, xP3NG3Rx said: I would like to mention here a minor bugfix about the update packets which cause the lags on changing attributes (maybe with manual mouse drag only? dunno). I hope it is visible on the video, if not just test it by yourself. Reveal hidden contents https://metin2.download/picture/WVGShIHhrtef2On3f7P19Tn6553kIOdz/.gif What you need to do with these microlags is easy, just open the interfaceModule.py and there inside the Interface class you will find a function which is the RefreshInventory. Every different window which has refreshable item grid, it runs down from there even if the windows isn't opened. This cause the fps drop which is visible even with human eyes. The solution is, you have to put an (IsShow) if statement before they run down like the way how it looks like on my side: def RefreshInventory(self): self.wndTaskBar.RefreshQuickSlot() if self.wndInventory and self.wndInventory.IsShow(): self.wndInventory.RefreshItemSlot() if app.ENABLE_DRAGON_SOUL_SYSTEM: if self.wndDragonSoul and self.wndDragonSoul.IsShow(): self.wndDragonSoul.RefreshItemSlot() if app.ENABLE_EXTEND_INVEN_SYSTEM and app.ENABLE_SEPARATED_EXTEND_INVEN_WINDOW: if self.wndInventoryEx and self.wndInventoryEx.IsShow(): self.wndInventoryEx.RefreshItemSlot() if app.ENABLE_MOVE_COSTUME_ATTR or app.ENABLE_MOVE_SASH_ATTR: if app.GetMoveAttrWindowOpen(): if self.wndItemCombination and self.wndItemCombination.IsShow(): self.wndItemCombination.RefreshCombSlotWindow() if app.ENABLE_SHOULDER_SASH_SYSTEM: if player.GetAcceRefineWindowOpen(): if self.wndAcce and self.wndAcce.IsShow(): self.wndAcce.RefreshAcceWindow() if app.ENABLE_CHANGE_LOOK_SYSTEM: if player.GetChangeLookWindowOpen(): if self.wndChangeLook and self.wndChangeLook.IsShow(): self.wndChangeLook.RefreshChangeLookWindow() if self.wndAttr67Add and self.wndAttr67Add.IsShow(): self.wndAttr67Add.RefreshAttr67Window() if app.ENABLE_AURA_SYSTEM: if player.IsAuraRefineWindowOpen(): if self.wndAura and self.wndAura.IsShow(): self.wndAura.RefreshAuraWindow() I think that your solution is not exactly the best and look why I say this. https://metin2.download/video/1vvoUjT5M4F92GSSJrpAB3tu6vtUd3iM/.mp4 Edited April 4, 2023 by Metin2 Dev International Core X - External 2 Internal 1 Link to comment Share on other sites More sharing options...
Recommended Posts