Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions Changelog.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4077,3 +4077,6 @@ When setting a property like MORE to the a spell or skill defname, trying to rea
- Changed: Object timers are now saved in worldsave files as TIMERMS, to avoid ambiguity and reliance on git build number to determine if TIMER expressed a number in seconds or milliseconds.
- Changed: Added 5 seconds timeout to DNS hostname resolution at startup (avoid getting stuck when connectivity is enabled but not working).
- Changed: CANMASK formatted in worldsave files as hexadecimal number, instead of decimal.

29-11-2025, canerksk
- Added: Added Itemlist.* and Charlist.* function for server. The function is based on the guildstones.* function. It is a function that outputs all items or chars on the server. It can be used with serv.charlist/itemlist.count as serv.charlist/itemlist.0.name/p/uid/.
84 changes: 84 additions & 0 deletions src/game/CServerConfig.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1926,6 +1926,90 @@ bool CServerConfig::r_WriteVal( lpctstr ptcKey, CSString & sVal, CTextConsole *
return true;
}

if (!strnicmp(ptcKey, "CHARLIST.", 9))
{
lpctstr pszCmd = ptcKey + 9;
CChar *pChar = nullptr;
size_t x = 0;

if (!strnicmp(pszCmd, "COUNT", 5))
{
for (size_t i = 0; i < g_World.m_Chars.size(); ++i)
{
pChar = g_World.m_Chars[i].get();
if (pChar == NULL)
continue;
if (!pChar->IsDeleted())
++x;
}

sVal.FormatSTVal(x);
return true;
}

size_t iNumber = Exp_GetVal(pszCmd);
SKIP_SEPARATORS(pszCmd);
sVal.SetValFalse();

for (size_t i = 0; i < g_World.m_Chars.size(); ++i)
{
pChar = g_World.m_Chars[i].get();
if (pChar == nullptr)
continue;
if (!pChar->IsDeleted())
{
if (iNumber == x)
return pChar->r_WriteVal(pszCmd, sVal, pSrc);
++x;
}
}

return true;
}


if (!strnicmp(ptcKey, "ITEMLIST.", 9))
{
lpctstr pszCmd = ptcKey + 9;
CItem *pItem = nullptr;
size_t x = 0;

if (!strnicmp(pszCmd, "COUNT", 5))
{
for (size_t i = 0; i < g_World.m_Items.size(); ++i)
{
pItem = g_World.m_Items[i].get();
if (pItem == NULL)
continue;
if (!pItem->IsDeleted())
++x;
}

sVal.FormatSTVal(x);
return true;
}

size_t iNumber = Exp_GetVal(pszCmd);
SKIP_SEPARATORS(pszCmd);
sVal.SetValFalse();

for (size_t i = 0; i < g_World.m_Items.size(); ++i)
{
pItem = g_World.m_Items[i].get();
if (pItem == nullptr)
continue;
if (!pItem->IsDeleted())
{
if (iNumber == x)
return pItem->r_WriteVal(pszCmd, sVal, pSrc);
++x;
}
}

return true;
}


if ( !strnicmp( ptcKey, "CLIENT.",7))
{
ptcKey += 7;
Expand Down
5 changes: 5 additions & 0 deletions src/game/CWorld.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1402,6 +1402,8 @@ bool CWorld::LoadWorld() // Load world from script
CWorldTickingList::ClearTickingLists();

m_Stones.clear();
m_Items.clear();
m_Chars.clear();
m_Multis.clear();
m_Parties.clear();
m_GMPages.clear();
Expand Down Expand Up @@ -1721,6 +1723,9 @@ void CWorld::Close()
m_Stones.clear();
m_Multis.clear();

m_Chars.clear();
m_Items.clear();

{
#if MT_ENGINES
std::unique_lock<std::shared_mutex> lock_su(_Ticker._vObjStatusUpdates.MT_CMUTEX);
Expand Down
4 changes: 4 additions & 0 deletions src/game/CWorld.h
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,10 @@ extern class CWorld : public CScriptObj, public CWorldThread

sl::unique_ptr_vector<CGMPage> m_GMPages; // Owns current outstanding GM pages. (CGMPage)
sl::unique_ptr_vector<CItemStone> m_Stones; // Owns guild/town stones. (not saved array)

sl::raw_ptr_view_vector<CItem> m_Items; // world dynamic items
sl::raw_ptr_view_vector<CChar> m_Chars; // world dynamic chars

sl::unique_ptr_vector<CPartyDef> m_Parties; // Owns all active parties.
sl::raw_ptr_view_vector<CItemMulti> m_Multis; // World multis?
sl::smart_ptr_view_vector<CResourceDef> m_TileTypes; // Links to CItemTypeDef items owned by g_Cfg.m_ResHash
Expand Down
4 changes: 4 additions & 0 deletions src/game/chars/CChar.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,8 @@ CChar::CChar( CREID_TYPE baseID ) :
ADDTOCALLSTACK("CChar::CChar");
g_Serv.StatInc( SERV_STAT_CHARS ); // Count created CChars.

g_World.m_Chars.emplace_back(this);

m_pArea = nullptr;
m_pParty = nullptr;
m_pClient = nullptr; // is the char a logged in player?
Expand Down Expand Up @@ -368,6 +370,8 @@ CChar::~CChar()

g_Serv.StatDec( SERV_STAT_CHARS );

g_World.m_Chars.erase_element(this);

EXC_CATCH;
}

Expand Down
5 changes: 5 additions & 0 deletions src/game/items/CItem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,9 @@ CItem::CItem( ITEMID_TYPE id, CItemBase * pItemDef ) :
ASSERT( pItemDef );

g_Serv.StatInc(SERV_STAT_ITEMS);

g_World.m_Items.emplace_back(this);

m_type = IT_NORMAL;
m_Attr = 0;
m_CanUse = pItemDef->m_CanUse;
Expand Down Expand Up @@ -279,6 +282,8 @@ CItem::~CItem()

g_Serv.StatDec(SERV_STAT_ITEMS);

g_World.m_Items.erase_element(this);

EXC_CATCH;
}

Expand Down