Lead0b110010100
-
Posts
16 -
Joined
-
Last visited
-
Feedback
0%
Content Type
Forums
Store
Third Party - Providers Directory
Feature Plan
Release Notes
Docs
Events
Posts posted by Lead0b110010100
-
-
But... why should someone do that xDD
And why should a server admin care hahahha
- 2
- 1
- 1
-
Thank you very much Ikarus. Not only that you fixxed it, I love how you explain the bug and your solution.
I knew one more developer in this board that did that some time ago (Vanilla) and I missed such posts.
I even learned something, thank you.
- 1
- 1
-
1 hour ago, Cysgod said:
Did anyone test the impact on cpu usage or the time needed for the execution of the functions? The usage of a ordered std::map should be (in theory) way slower.
ATM I moved the fixed sized arrays into a new struct and added a shared_ptr as member variable to the CHARACTER class. When "SetPlayerProto" gets called I'll create a shared_ptr of the new struct. - Which ofc means I wont save any memory for players which don't use all slots.
In idle (without players) this results in a drop from 1480mb to 540mb ram per channel -> ~64% less ramusage.
You ware totally right, I replaced std::map with std::unordered_map here.
-
20 hours ago, Hik said:
Can you post the changes you made?
Okay? No problem:
SpoilerFrom 00c973263a61583dceede12f790312434ac69fed Mon Sep 17 00:00:00 2001 From: Lead0b110010100 <Lead0b110010100@outlook.com> Date: Sat, 23 Oct 2021 14:21:15 +0200 Subject: [PATCH] Squashed commit of the following: commit ba3633233cf2e6bd08664c5cfab93155bc1ce05d Author: Lead0b110010100 <Lead0b110010100@outlook.com> Date: Sat Oct 23 14:18:01 2021 +0200 Refactoring. commit 2328c9c4e7336eb2bf6428206ab2aedc2a50f343 Author: Lead0b110010100 <Lead0b110010100@outlook.com> Date: Sat Oct 23 14:00:06 2021 +0200 Improve performants by changing char array with map. commit cb1c00629cd21f4c0bfb9cc79ca2a322013fce7e Author: Lead0b110010100 <Lead0b110010100@outlook.com> Date: Sat Oct 23 13:28:54 2021 +0200 Improve performants by changing char array with map. commit af1e5bee7838815de735e9e280ece47aceb54f8c Author: Lead0b110010100 <Lead0b110010100@outlook.com> Date: Sat Oct 23 13:14:57 2021 +0200 Improve performants by changing char array with map. commit 125bc19585cf904e8f40fcb687dbd0b3730ad13a Author: Lead0b110010100 <Lead0b110010100@outlook.com> Date: Sat Oct 23 12:45:01 2021 +0200 Improve performants by changing char array with map. --- Server/game/src/char.cpp | 6 +- Server/game/src/char.h | 35 ++++++--- Server/game/src/char_item.cpp | 134 +++++++++++++++++++++++++--------- 3 files changed, 125 insertions(+), 50 deletions(-) diff --git a/Server/game/src/char.cpp b/Server/game/src/char.cpp index 246ea710..475888e5 100644 --- a/Server/game/src/char.cpp +++ b/Server/game/src/char.cpp @@ -322,7 +322,7 @@ void CHARACTER::Initialize() m_pkChrSyncOwner = NULL; memset(&m_points, 0, sizeof(m_points)); - memset(&m_pointsInstant, 0, sizeof(m_pointsInstant)); + m_pointsInstant = {}; memset(&m_quickslot, 0, sizeof(m_quickslot)); m_bCharType = CHAR_TYPE_MONSTER; @@ -9075,12 +9075,12 @@ bool CHARACTER::HasGroupMemberInParty() const LPITEM CHARACTER::GetSwitchbotItem(uint8_t slot) { - return m_pointsInstant.pSwitchbotItems[slot]; + return GetSwitchbotItemFromGrid(slot); } LPITEM CHARACTER::GetSoulshieldItem(uint8_t slot) { - return m_pointsInstant.pItems[SOULSHIELD_EQUIP_SLOT_START + slot]; + return GetItemFromGrid(SOULSHIELD_EQUIP_SLOT_START + slot); } LPITEM CHARACTER::GetSafeboxItem(uint16_t slot) diff --git a/Server/game/src/char.h b/Server/game/src/char.h index 5a6e0f6a..5c185a2c 100644 --- a/Server/game/src/char.h +++ b/Server/game/src/char.h @@ -225,6 +225,15 @@ typedef struct character_point /* 저장되지 않는 캐릭터 데이터 */ typedef struct character_point_instant { + character_point_instant() : points(), fRot(0.0f), iMaxHP(0), iMaxSP(0), position(0), + instant_flag(0), dwAIFlag(0), dwImmuneFlag(0), dwLastShoutPulse(0), parts(), + pItems(), pItemGrid(), pExtraItems(), pExtraItemGrid(), pSwitchbotItems(), + pCubeNpc(nullptr), battle_victim(nullptr), gm_level(GM_PLAYER), + bBasePart(PART_MAIN), iMaxStamina(0), pWardrobeItems(), wardrobeIsLoaded(false), + isWardrobeItemUnequiping(0), wardrobeCount(0) + { + }; + GoldType points[POINT_MAX_NUM]; float fRot; @@ -245,20 +254,17 @@ typedef struct character_point_instant // char는 인벤을 uint8_t array로 grid를 관리하고, exchange나 cube는 CGrid로 grid를 관리하고 뭐냐 이거... // grid를 만들어 놨으면 grid를 쓰란 말이야!!! // ㅅㅂ 용혼석 인벤을 똑같이 따라서 만든 나도 잘못했다 ㅠㅠ - LPITEM pItems[INVENTORY_AND_EQUIP_SLOT_MAX]; - uint8_t bItemGrid[INVENTORY_AND_EQUIP_SLOT_MAX]; + std::map<uint16_t, LPITEM> pItems; + std::map<uint8_t, uint8_t> pItemGrid; - LPITEM pExtraItems[EXTRA_INVENTORY_MAX_NUM]; - uint16_t wExtraItemGrid[EXTRA_INVENTORY_MAX_NUM]; + std::map<uint16_t, LPITEM> pExtraItems; + std::map<uint16_t, uint16_t> pExtraItemGrid; #ifdef ENABLE_SWITCHBOT - LPITEM pSwitchbotItems[SWITCHBOT_SLOT_COUNT]; + std::map<uint16_t, LPITEM> pSwitchbotItems; #endif - // by mhh - LPITEM pCubeItems[CUBE_MAX_NUM]; LPCHARACTER pCubeNpc; - LPCHARACTER battle_victim; uint8_t gm_level; @@ -268,7 +274,7 @@ typedef struct character_point_instant int32_t iMaxStamina; #ifdef ENABLE_WARDROBE - LPITEM pWardrobeItems[WARDROBE_SLOT_COUNT]; + std::map<uint16_t, LPITEM> pWardrobeItems; bool wardrobeIsLoaded; int32_t isWardrobeItemUnequiping; int32_t wardrobeCount; @@ -1022,6 +1028,15 @@ public: void SetItem(TItemPos Cell, LPITEM item); LPITEM GetItem(TItemPos Cell) const; LPITEM GetInventoryItem(ItemCellType wCell) const; + + ItemCellType GetFromItemGrid(ItemCellType cell) const; + ItemCellType GetFromExtraItemGrid(ItemCellType cell) const; + + LPITEM GetItemFromGrid(ItemStackType cell) const; + LPITEM GetExtraItemFromGrid(ItemStackType cell) const; + LPITEM GetSwitchbotItemFromGrid(ItemStackType cell) const; + LPITEM GetWardrobeItemFromGrid(ItemStackType cell) const; + bool IsEmptyItemGrid(TItemPos Cell, uint8_t size, int32_t iExceptionCell = -1) const; LPITEM GetExtraInventoryItem(ItemCellType wCell) const; @@ -1889,8 +1904,6 @@ public: public: bool ItemProcess_Polymorph(LPITEM item); - // by mhh - LPITEM *GetCubeItem() { return m_pointsInstant.pCubeItems; } bool IsCubeOpen() const { return (m_pointsInstant.pCubeNpc ? true : false); } void SetCubeNpc(LPCHARACTER npc) { m_pointsInstant.pCubeNpc = npc; } LPCHARACTER GetCubeNpc() { return m_pointsInstant.pCubeNpc; } diff --git a/Server/game/src/char_item.cpp b/Server/game/src/char_item.cpp index 9d92abd5..8a0e5cfe 100644 --- a/Server/game/src/char_item.cpp +++ b/Server/game/src/char_item.cpp @@ -248,14 +248,14 @@ LPITEM CHARACTER::GetItem(TItemPos Cell) const sys_err("CHARACTER::GetInventoryItem: invalid item cell %d", wCell); return NULL; } - return m_pointsInstant.pItems[wCell]; + return GetItemFromGrid(wCell); case EXTRA_INVENTORY: if (wCell >= EXTRA_INVENTORY_MAX_NUM) { sys_err("CHARACTER::GetInventoryItem: invalid EXTRA item cell %d", wCell); return NULL; } - return m_pointsInstant.pExtraItems[wCell]; + return GetExtraItemFromGrid(wCell); #ifdef ENABLE_SWITCHBOT case SWITCHBOT: if (wCell >= SWITCHBOT_SLOT_COUNT) @@ -263,7 +263,7 @@ LPITEM CHARACTER::GetItem(TItemPos Cell) const sys_err("CHARACTER::GetInventoryItem: invalid switchbot item cell %d", wCell); return NULL; } - return m_pointsInstant.pSwitchbotItems[wCell]; + return GetSwitchbotItemFromGrid(wCell); #endif #ifdef ENABLE_WARDROBE case WARDROBE: @@ -272,7 +272,7 @@ LPITEM CHARACTER::GetItem(TItemPos Cell) const sys_err("CHARACTER::GetInventoryItem: invalid wardrobe item cell %d", wCell); return NULL; } - return m_pointsInstant.pWardrobeItems[wCell]; + return GetWardrobeItemFromGrid(wCell); #endif default: @@ -309,7 +309,7 @@ void CHARACTER::SetItem(TItemPos Cell, LPITEM pItem) return; } - LPITEM pOld = m_pointsInstant.pItems[wCell]; + LPITEM pOld = GetItemFromGrid(wCell); if (pOld) { @@ -322,14 +322,14 @@ void CHARACTER::SetItem(TItemPos Cell, LPITEM pItem) if (p >= INVENTORY_MAX_NUM) continue; - if (m_pointsInstant.pItems[p] && m_pointsInstant.pItems[p] != pOld) + if (GetItemFromGrid(p) && GetItemFromGrid(p) != pOld) continue; - m_pointsInstant.bItemGrid[p] = 0; + m_pointsInstant.pItemGrid[p] = 0; } } else - m_pointsInstant.bItemGrid[wCell] = 0; + m_pointsInstant.pItemGrid[wCell] = 0; } if (pItem) @@ -345,11 +345,11 @@ void CHARACTER::SetItem(TItemPos Cell, LPITEM pItem) // wCell + 1 로 하는 것은 빈곳을 체크할 때 같은 // 아이템은 예외처리하기 위함 - m_pointsInstant.bItemGrid[p] = wCell + 1; + m_pointsInstant.pItemGrid[p] = wCell + 1; } } else - m_pointsInstant.bItemGrid[wCell] = wCell + 1; + m_pointsInstant.pItemGrid[wCell] = wCell + 1; } m_pointsInstant.pItems[wCell] = pItem; @@ -364,7 +364,7 @@ void CHARACTER::SetItem(TItemPos Cell, LPITEM pItem) return; } - LPITEM pOld = m_pointsInstant.pExtraItems[wCell]; + LPITEM pOld = GetExtraItemFromGrid(wCell); if (pOld) { @@ -375,10 +375,10 @@ void CHARACTER::SetItem(TItemPos Cell, LPITEM pItem) if (p >= EXTRA_INVENTORY_MAX_NUM) continue; - if (m_pointsInstant.pExtraItems[p] && m_pointsInstant.pExtraItems[p] != pOld) + if (GetExtraItemFromGrid(p) && GetExtraItemFromGrid(p) != pOld) continue; - m_pointsInstant.wExtraItemGrid[p] = 0; + m_pointsInstant.pExtraItemGrid[p] = 0; } } @@ -391,7 +391,7 @@ void CHARACTER::SetItem(TItemPos Cell, LPITEM pItem) if (p >= EXTRA_INVENTORY_MAX_NUM) continue; - m_pointsInstant.wExtraItemGrid[p] = wCell + 1; + m_pointsInstant.pExtraItemGrid[p] = wCell + 1; } } @@ -402,7 +402,8 @@ void CHARACTER::SetItem(TItemPos Cell, LPITEM pItem) #ifdef ENABLE_SWITCHBOT case SWITCHBOT: { - LPITEM pOld = m_pointsInstant.pSwitchbotItems[wCell]; + LPITEM pOld = GetSwitchbotItemFromGrid(wCell); + if (pItem && pOld) { return; @@ -528,7 +529,7 @@ void CHARACTER::SetItem(TItemPos Cell, LPITEM pItem) if (m_pointsInstant.isWardrobeItemUnequiping > 0) { int32_t pos = m_pointsInstant.isWardrobeItemUnequiping - 1; - LPITEM item = m_pointsInstant.pWardrobeItems[pos]; + LPITEM item = GetWardrobeItemFromGrid(pos); m_pointsInstant.isWardrobeItemUnequiping = -1; pItem->RemoveFromCharacter(); @@ -548,7 +549,7 @@ LPITEM CHARACTER::GetWear(ItemCellType bCell) const return NULL; } - return m_pointsInstant.pItems[INVENTORY_MAX_NUM + bCell]; + return GetItemFromGrid(INVENTORY_MAX_NUM + bCell); } void CHARACTER::SetWear(ItemCellType bCell, LPITEM item) @@ -606,7 +607,7 @@ void CHARACTER::ClearItem() #endif #ifdef ENABLE_WARDROBE for (i = 0; i < WARDROBE_SLOT_COUNT; i++) { - item = m_pointsInstant.pWardrobeItems[i]; + item = GetWardrobeItemFromGrid(i); if (item != nullptr) { item->SetSkipSave(true); @@ -635,9 +636,9 @@ bool CHARACTER::IsEmptyItemGrid(TItemPos Cell, uint8_t bSize, int32_t iException if (bCell >= INVENTORY_MAX_NUM) return false; - if (m_pointsInstant.bItemGrid[bCell]) + if (GetFromItemGrid(bCell)) { - if (m_pointsInstant.bItemGrid[bCell] == iExceptionCell) + if (GetFromItemGrid(bCell) == iExceptionCell) { if (bSize == 1) return true; @@ -655,8 +656,8 @@ bool CHARACTER::IsEmptyItemGrid(TItemPos Cell, uint8_t bSize, int32_t iException if (p / (INVENTORY_MAX_NUM / INVENTORY_PAGE_COUNT) != bPage) return false; - if (m_pointsInstant.bItemGrid[p]) - if (m_pointsInstant.bItemGrid[p] != iExceptionCell) + if (GetFromItemGrid(p)) + if (GetFromItemGrid(p) != iExceptionCell) return false; } while (++j < bSize); @@ -684,8 +685,8 @@ bool CHARACTER::IsEmptyItemGrid(TItemPos Cell, uint8_t bSize, int32_t iException if (p / (INVENTORY_MAX_NUM / INVENTORY_PAGE_COUNT) != bPage) return false; - if (m_pointsInstant.bItemGrid[p]) - if (m_pointsInstant.bItemGrid[p] != iExceptionCell) + if (GetFromItemGrid(p)) + if (GetFromItemGrid(p) != iExceptionCell) return false; } while (++j < bSize); @@ -703,9 +704,9 @@ bool CHARACTER::IsEmptyItemGrid(TItemPos Cell, uint8_t bSize, int32_t iException ++iExceptionCell; - if (m_pointsInstant.wExtraItemGrid[bCell]) + if (GetFromExtraItemGrid(bCell)) { - if (m_pointsInstant.wExtraItemGrid[bCell] == iExceptionCell) + if (GetFromExtraItemGrid(bCell) == iExceptionCell) { if (bSize == 1) return true; @@ -723,8 +724,8 @@ bool CHARACTER::IsEmptyItemGrid(TItemPos Cell, uint8_t bSize, int32_t iException if (p / (EXTRA_INVENTORY_MAX_NUM / EXTRA_INVENTORY_PAGE_COUNT) != bPage) return false; - if (m_pointsInstant.wExtraItemGrid[p]) - if (m_pointsInstant.wExtraItemGrid[p] != iExceptionCell) + if (GetFromExtraItemGrid(p)) + if (GetFromExtraItemGrid(p) != iExceptionCell) return false; } while (++j < bSize); @@ -751,8 +752,8 @@ bool CHARACTER::IsEmptyItemGrid(TItemPos Cell, uint8_t bSize, int32_t iException if (p / (EXTRA_INVENTORY_MAX_NUM / EXTRA_INVENTORY_PAGE_COUNT) != bPage) return false; - if (m_pointsInstant.wExtraItemGrid[p]) - if (m_pointsInstant.wExtraItemGrid[p] != iExceptionCell) + if (GetFromExtraItemGrid(p)) + if (GetFromExtraItemGrid(p) != iExceptionCell) return false; } while (++j < bSize); @@ -765,12 +766,13 @@ bool CHARACTER::IsEmptyItemGrid(TItemPos Cell, uint8_t bSize, int32_t iException case SWITCHBOT: { ItemCellType wCell = Cell.cell; + if (wCell >= SWITCHBOT_SLOT_COUNT) { return false; } - if (m_pointsInstant.pSwitchbotItems[wCell]) + if (GetSwitchbotItemFromGrid(wCell)) { return false; } @@ -782,12 +784,12 @@ bool CHARACTER::IsEmptyItemGrid(TItemPos Cell, uint8_t bSize, int32_t iException #ifdef ENABLE_WARDROBE case WARDROBE: { - uint16_t wCell = Cell.cell; + ItemStackType wCell = Cell.cell; if (wCell >= WARDROBE_SLOT_COUNT) return false; - return m_pointsInstant.pWardrobeItems[wCell] == nullptr; + return !GetWardrobeItemFromGrid(wCell); } #endif } @@ -8718,7 +8720,7 @@ void CHARACTER::CombineShards(LPITEM shard1, LPITEM shard2) int32_t CHARACTER::GetEmptyWardrobeSlot() const { for (int32_t i = 0; i < WARDROBE_HIDDEN_SLOT_COUNT; i++) - if (!m_pointsInstant.pWardrobeItems[i]) + if (!GetWardrobeItemFromGrid(i)) return i; return -1; @@ -8728,7 +8730,7 @@ int32_t CHARACTER::GetWardrobeRewardSlot(uint32_t dwItemVnum) const { for (int32_t i = 0; i < WARDROBE_HIDDEN_SLOT_COUNT; i++) { - LPITEM item = m_pointsInstant.pWardrobeItems[i]; + LPITEM item = GetWardrobeItemFromGrid(i); if (item && item->GetVnum() == dwItemVnum) return i; @@ -8743,7 +8745,7 @@ int32_t CHARACTER::GetWardrobeSlot(uint32_t dwItemVnum) const for (int32_t i = WARDROBE_HIDDEN_SLOT_COUNT; i < WARDROBE_SLOT_COUNT; i++) { - LPITEM item = m_pointsInstant.pWardrobeItems[i]; + LPITEM item = GetWardrobeItemFromGrid(i); if (item == nullptr) { @@ -8930,3 +8932,63 @@ void CHARACTER::AbsorbAutopotionsInClipping(const TItemPos& pos) ChatPacketTrans(CHAT_TYPE_INFO, "Es wurden %d Autopots absorbiert!", count); } + +ItemCellType CHARACTER::GetFromItemGrid(ItemCellType cell) const +{ + const auto& it = m_pointsInstant.pItemGrid.find(cell); + + if (it == m_pointsInstant.pItemGrid.end()) + return 0; + + return it->second; +} + +ItemCellType CHARACTER::GetFromExtraItemGrid(ItemCellType cell) const +{ + const auto& it = m_pointsInstant.pExtraItemGrid.find(cell); + + if (it == m_pointsInstant.pExtraItemGrid.end()) + return 0; + + return it->second; +} + +LPITEM CHARACTER::GetItemFromGrid(ItemStackType cell) const +{ + const auto& it = m_pointsInstant.pItems.find(cell); + + if (it == m_pointsInstant.pItems.end()) + return nullptr; + + return it->second; +} + +LPITEM CHARACTER::GetExtraItemFromGrid(ItemStackType cell) const +{ + const auto& it = m_pointsInstant.pExtraItems.find(cell); + + if (it == m_pointsInstant.pExtraItems.end()) + return nullptr; + + return it->second; +} + +LPITEM CHARACTER::GetSwitchbotItemFromGrid(ItemStackType cell) const +{ + const auto& it = m_pointsInstant.pSwitchbotItems.find(cell); + + if (it == m_pointsInstant.pSwitchbotItems.end()) + return nullptr; + + return it->second; +} + +LPITEM CHARACTER::GetWardrobeItemFromGrid(ItemStackType cell) const +{ + const auto& it = m_pointsInstant.pWardrobeItems.find(cell); + + if (it == m_pointsInstant.pWardrobeItems.end()) + return nullptr; + + return it->second; +} -- 2.33.1.windows.1
- 1
- 2
- 1
-
I tested it and got like 44% RAM usage reduction. But I had to do some changes in order to not get exceptions when running the server on windows. (Due to unintialized usage of map) + I changed way more lines of code to do that, but the idea is absolutely correct.
- 1
- 1
-
Add a way to contact you, maybe discord?
-
I do have a fix for that actually. But I don't know if I want to sell / release it.
Maybe in some months in my own shop.
- 1
- 1
- 2
-
9 hours ago, TAUMP said:
sql injection inc
That comment is dumb af. You can't secure your self against sql injections by just disallowing people from using special characters. That's not the point of cyber defence.
-
Very nice release, I was bothering with that since I first saw that stupidity!
There is only one way we could improve the code 'style'. I think at the end, performance wise, It won't really affect the compilation or execution speed:
Instead of increasing the counters before any continue; or at the end of the while loop, use "do-while" in combination with the increment operator:
do { [...] } while (TextFileLoader.SetChildNode("hairdata", dwHairDataCount++));
-
26 minutes ago, Cunoo said:
Thanks for this info
Already use clang.. So my src is changed to clang.If you're done updating to llvm11 and 64 bit. Don't forget to play arounf with -fsanitizer. It works like a charm and helps me a lot!
- 1
-
3 hours ago, Finnis said:
Hey, you only need to change 'long' to 'int32_t' in game source. (Would be better if you'd change the other types as well - e.g: byte -> uint8_t, short -> int16_t, etc)
For more informations you can check this link.
He needs to do that, but he needs to recompile / use the 64 bit equvivalent of the libs too.
And he needs to recompile metin2's libs like libthecore etc etc.
It's not as easy as it sounds if you ask me. Changing dependencies is always a shit ton of work / trial & error.
- 1
-
Not possible with VS Code extensions as far as I know.
But you could try SSHFS, there are tools that were developed from google to ensure a nice workflow.
-
Hey Lead here from the other board. I don't think he has stolen it from me, maybe he got the idea from there and then coded it himself.
I would recognize my own code style if he had really copied it one for one.
- 3
Fullscreen resolution overflow fix
in Bug Fixes
Posted
Oh wow, my comment got more backlash than I thought it would. I was like "Why should someone put such a crazy value there, that's stupid as hell. But someone did, so did you find a fix for it."
The problem we are trying to solve here is not a new one, try entering 9000000000 as a value for the width parameter for example. It will also overflow, resulting in a 'random' value of m_Config.width or a crash. We can't really 'fix' the underlying problem here, which is that serialization of numbers can result in overflows. If you take a 8 bit data type like 'long long' instead of the 4 bit 'int' for m_Config.width, someone could still write a bigger number. What I wan't to say is:
This check might result in randomly true or false, regarding the value after the overflow in the config parameter.
if (m_Config.width >= screen_width_1)
Sorry if my first comment sounded rude or offensive, it was definitely not meant like that.