### Install MySQL Client on Ubuntu (15.04-19.04) Source: https://github.com/sphereserver/source/blob/master/README.md Installs the MySQL client development libraries on Ubuntu versions 15.04 through 19.04. This command handles both standard and 32-bit installations on 64-bit systems. ```bash # For Ubuntu 15.04 to 19.04 # Install for 32/64-bit OS sudo apt-get install libmysqlclient-dev # Install for 32-bit build on 64-bit OS sudo apt-get install libmysqlclient-dev:i386 ``` -------------------------------- ### Install MySQL 5.7 Client on Ubuntu (19.10+) Source: https://github.com/sphereserver/source/blob/master/README.md Instructions to add MySQL 5.7 repository and install specific MySQL client development libraries on Ubuntu 19.10 and later. Includes handling for 32-bit builds. ```bash # For Ubuntu 19.10 or later sudo add-apt-repository 'deb http://repo.mysql.com/apt/ubuntu/ bionic mysql-5.7' sudo apt-get update --allow-insecure-repositories # Install for 32/64-bit OS sudo apt-get install libmysqlclient-dev=5.7* # Install for 32-bit build on 64-bit OS sudo apt-get install libmysqlclient-dev:i386=5.7* ``` -------------------------------- ### Install Core Build Packages on Ubuntu (32/64-bit) Source: https://github.com/sphereserver/source/blob/master/README.md Installs essential packages for compiling SphereServer on Ubuntu for both 32-bit and 64-bit systems. Includes Git, GCC, G++, and Make. ```bash sudo apt-get install git sudo apt-get install gcc sudo apt-get install g++ sudo apt-get install make ``` -------------------------------- ### Install Core Build Packages on Ubuntu (64-bit for 32-bit build) Source: https://github.com/sphereserver/source/blob/master/README.md Installs necessary packages on a 64-bit Ubuntu system to compile 32-bit versions of SphereServer. Includes Git, GCC (multilib), G++ (multilib), and Make. ```bash sudo apt-get install git sudo apt-get install gcc-multilib sudo apt-get install g++-multilib sudo apt-get install make ``` -------------------------------- ### Install MySQL 5.7 Client on Ubuntu (older versions) Source: https://github.com/sphereserver/source/blob/master/README.md Steps to add MySQL 5.7 repository and install the MySQL client development libraries on Ubuntu versions 14.10 or older. Includes support for 32-bit builds on 64-bit systems. ```bash # For Ubuntu 14.10 or older sudo add-apt-repository 'deb http://repo.mysql.com/apt/ubuntu/ precise mysql-5.7' sudo apt-get update # Install for 32/64-bit OS sudo apt-get install libmysqlclient-dev # Install for 32-bit build on 64-bit OS sudo apt-get install libmysqlclient-dev:i386 ``` -------------------------------- ### Install Required Packages on CentOS/Red Hat (32/64-bit) Source: https://github.com/sphereserver/source/blob/master/README.md Installs packages needed for SphereServer compilation on CentOS/Red Hat for standard 32-bit and 64-bit builds. Includes Git, GCC++, development libraries for C++ and MySQL. ```bash sudo yum install git sudo yum install gcc-c++ sudo yum install glibc-devel sudo yum install mysql-community-devel mysql-community-libs ``` -------------------------------- ### Add 32-bit Architecture Support on Ubuntu Source: https://github.com/sphereserver/source/blob/master/README.md Instructions for enabling 32-bit architecture support on a 64-bit Ubuntu system, a prerequisite for compiling 32-bit builds. ```bash sudo dpkg --add-architecture i386 sudo apt-get update sudo apt-get dist-upgrade ``` -------------------------------- ### Install Required Packages on CentOS/Red Hat (64-bit for 32-bit build) Source: https://github.com/sphereserver/source/blob/master/README.md Installs packages on a 64-bit CentOS/Red Hat system to compile 32-bit SphereServer. Includes Git, GCC++, and i686 versions of development libraries for glibc and MySQL. ```bash sudo yum install git sudo yum install gcc-c++ sudo yum install glibc-devel.i686 sudo yum install mysql-community-devel.i686 mysql-community-libs.i686 ``` -------------------------------- ### Compile SphereServer on Windows (Visual Studio) Source: https://github.com/sphereserver/source/blob/master/README.md Instructions for compiling SphereServer on Windows using Visual Studio. Involves opening the project file, selecting build configurations and platforms, and initiating the build process. Requires VS2015 or later and the 'Desktop Development with C++' workload. ```csharp // Open SphereSvr.vcxproj in Visual Studio. // Select Build Configuration (Debug/Local/Nightly/Release) and Platform (x86/x64). // Go to Build > Build Solution. ``` -------------------------------- ### Add MySQL 5.7 Support on CentOS/Red Hat Source: https://github.com/sphereserver/source/blob/master/README.md Configures the package repository to enable MySQL 5.7 for installation on CentOS and Red Hat systems, covering versions 6 through 9. ```bash # CentOS 6 / Red Hat 6: sudo yum localinstall https://dev.mysql.com/get/mysql80-community-release-el6-9.noarch.rpm # CentOS 7 / Red Hat 7: sudo yum localinstall https://dev.mysql.com/get/mysql80-community-release-el7-10.noarch.rpm # CentOS 8 / Red Hat 8: sudo yum localinstall https://dev.mysql.com/get/mysql80-community-release-el8-8.noarch.rpm # CentOS 9 / Red Hat 9: sudo yum localinstall https://dev.mysql.com/get/mysql80-community-release-el9-4.noarch.rpm # Disable default MySQL 8.0 and enable 5.7 sudo yum-config-manager --disable mysql80-community sudo yum-config-manager --enable mysql57-community ``` -------------------------------- ### Clone SphereServer Source Code Source: https://github.com/sphereserver/source/blob/master/README.md This snippet shows how to clone the SphereServer source code from its GitHub repository using Git and navigate into the project directory. ```bash git clone https://github.com/SphereServer/Source.git cd Source ``` -------------------------------- ### Compile SphereServer on Linux (Make) Source: https://github.com/sphereserver/source/blob/master/README.md Commands to compile the SphereServer source code on Linux using the 'make' utility. Supports both 32-bit and 64-bit builds, with an option for nightly builds. ```bash # Compile 32-bit build (nightly) make NIGHTLY=1 x86=1 # Compile 64-bit build (nightly) make NIGHTLY=1 ``` -------------------------------- ### C++ Load Configuration File with CFile Source: https://context7.com/sphereserver/source/llms.txt This function loads configuration settings from a text file into a CVarDefMap. It reads the file line by line, skipping comments and empty lines, and parses key-value pairs. The CFile class handles file opening and reading in text mode. Input is a filename and a map to store configurations. ```cpp #include "common/CFile.h" // Load configuration file bool LoadConfigFile(LPCTSTR filename, CVarDefMap& configMap) { CFile file; if (!file.Open(filename, OF_READ | OF_TEXT)) { return false; } TCHAR line[SCRIPT_MAX_LINE_LEN]; while (file.ReadString(line, sizeof(line))) { // Skip comments and empty lines if (line[0] == '\0' || line[0] == '/' || line[0] == '#') { continue; } // Parse key=value TCHAR* pValue = strchr(line, '='); if (pValue) { *pValue = '\0'; pValue++; // Trim whitespace TCHAR* pKey = line; while (*pKey == ' ' || *pKey == '\t') pKey++; while (*pValue == ' ' || *pValue == '\t') pValue++; // Store in map configMap.SetStr(pKey, false, pValue); } } file.Close(); return true; } ``` -------------------------------- ### Create Container with Items Source: https://context7.com/sphereserver/source/llms.txt Creates a container (e.g., a chest) at a specified location and populates it with various items like gold, gems, and scrolls. Requires CItem and CPointMap. ```cpp #include "graysvr/CItem.h" // Create a container with items void CreateTreasureChest(CPointMap location) { // Create chest container CItem* pChest = CItem::CreateScript(ITEMID_CHEST_METAL); if (pChest) { pChest->SetType(IT_CONTAINER); pChest->SetAttr(ATTR_MOVE_NEVER); // Lock to ground // Add gold coins CItem* pGold = CItem::CreateScript(ITEMID_GOLD); if (pGold) { pGold->SetAmount(5000); pChest->ContentAdd(pGold); } // Add gems for (int i = 0; i < 10; i++) { CItem* pGem = CItem::CreateScript(ITEMID_GEM_DIAMOND); if (pGem) { pChest->ContentAdd(pGem); } } // Add magical scrolls CItem* pScroll = CItem::CreateScript(ITEMID_SCROLL_BLANK); if (pScroll) { pScroll->SetType(IT_SCROLL); pScroll->m_itSpell.m_spell = SPELL_Resurrection; pChest->ContentAdd(pScroll); } // Place in world pChest->MoveTo(location); pChest->Update(); } } ``` -------------------------------- ### C++ Create World Backup with CFile Source: https://context7.com/sphereserver/source/llms.txt This function creates a backup of the world save files. It uses CFile to create a backup directory and copy the 'sphereworld.scp' file. Error handling is included for file opening and creation. Dependencies include 'common/CFile.h' and logging functionalities. ```cpp #include "common/CFile.h" // Save world backup bool CreateWorldBackup(LPCTSTR backupName) { // Create backup directory CGString backupPath; backupPath.Format("backup/%s", backupName); CFile::CreateDir(backupPath.GetPtr()); // Copy world save files CGString srcPath, dstPath; // Backup main world file srcPath = "saves/sphereworld.scp"; dstPath.Format("%s/sphereworld.scp", backupPath.GetPtr()); CFile srcFile, dstFile; if (!srcFile.Open(srcPath.GetPtr(), OF_READ | OF_BINARY)) { g_Log.Event(LOGL_ERROR, "Failed to open world file for backup\n"); return false; } if (!dstFile.Open(dstPath.GetPtr(), OF_CREATE | OF_WRITE | OF_BINARY)) { g_Log.Event(LOGL_ERROR, "Failed to create backup file\n"); srcFile.Close(); return false; } // Copy file data BYTE buffer[4096]; size_t bytesRead; while ((bytesRead = srcFile.Read(buffer, sizeof(buffer))) > 0) { dstFile.Write(buffer, bytesRead); } srcFile.Close(); dstFile.Close(); g_Log.Event(LOGL_EVENT, "World backup created: %s\n", backupPath.GetPtr()); return true; } ``` -------------------------------- ### Server Initialization and Main Loop (C++) Source: https://context7.com/sphereserver/source/llms.txt Initializes the SphereServer, including network sockets and world data loading, then enters the main processing loop. It handles potential errors during initialization and cleans up resources on exit. Requires 'CServer.h' and 'CLog.h'. ```cpp #include "graysvr/CServer.h" // Initialize and start the server int main(int argc, char* argv[]) { // Server instance is global: g_Serv // Initialize network sockets if (!g_Serv.SocketsInit()) { g_Log.Event(LOGL_FATAL, "Failed to initialize sockets\n"); return -1; } // Load world data and scripts if (!g_Serv.Load()) { g_Log.Event(LOGL_FATAL, "Failed to load server data\n"); return -1; } // Set server to running mode g_Serv.SetServerMode(SERVMODE_Run); // Main server loop while (g_Serv.m_iExitFlag == 0) { g_Serv.OnTick(); // Process one server tick } // Cleanup g_Serv.SocketsClose(); return g_Serv.m_iExitFlag; } ``` -------------------------------- ### Initialize MySQL Database Connection C++ Source: https://context7.com/sphereserver/source/llms.txt Initializes the MySQL database connection for the server. It reads connection parameters from sphere.ini and establishes a connection using the global g_Serv.m_hdb instance. Handles potential connection errors. ```cpp #include "common/CDataBase.h" bool InitializeDatabase() { // Database instance is global: g_Serv.m_hdb try { // Connection parameters set in sphere.ini: // MYSQL.HOST=localhost // MYSQL.PORT=3306 // MYSQL.USER=spheredb // MYSQL.PASSWORD=password // MYSQL.DB=sphere_database g_Serv.m_hdb.Connect(); g_Log.Event(LOGL_EVENT, "MySQL database connected successfully\n"); return true; } catch (...) { g_Log.Event(LOGL_ERROR, "Failed to connect to MySQL database\n"); return false; } } ``` -------------------------------- ### Load and Parse Custom Scripts (C++) Source: https://context7.com/sphereserver/source/llms.txt Loads and parses a custom script file line by line using the CScript class. It handles opening the file, reading text lines, skipping comments, and parsing key-value pairs for items, NPCs, and spawn points. Dependencies include common/CScript.h and graysvr/CResourceBase.h. ```cpp #include "common/CScript.h" #include "graysvr/CResourceBase.h" // Load custom script file bool LoadCustomScripts(LPCTSTR filename) { CScript script; // Open script file if (!script.Open(filename, OF_READ | OF_TEXT)) { g_Log.Event(LOGL_ERROR, "Failed to open script: %s\n", filename); return false; } // Parse script line by line while (script.ReadTextLine(true)) { CScriptKey key; // Get current line TCHAR* pszLine = script.GetKey(); if (!pszLine || pszLine[0] == '\0') { continue; // Skip empty lines } // Skip comments if (pszLine[0] == '/' && pszLine[1] == '/') { continue; } // Parse key=value pairs key.ParseKey(pszLine); if (key.IsKey("ITEM")) { ITEMID_TYPE itemID = static_cast(key.GetArgVal()); g_Log.Event(LOGL_EVENT, "Loading item: 0x%x\n", itemID); } else if (key.IsKey("NPC")) { CREID_TYPE npcID = static_cast(key.GetArgVal()); g_Log.Event(LOGL_EVENT, "Loading NPC: 0x%x\n", npcID); } else if (key.IsKey("SPAWN")) { // Parse spawn coordinates int x = 0, y = 0, z = 0; sscanf(key.GetArgStr(), "%d,%d,%d", &x, &y, &z); g_Log.Event(LOGL_EVENT, "Spawn location: %d,%d,%d\n", x, y, z); } } script.Close(); return true; } ``` -------------------------------- ### Sphere Server 64-bit Architecture Support Source: https://github.com/sphereserver/source/blob/master/changelog.txt This documentation highlights the addition of 64-bit architecture support for the Sphere Server. Both 32-bit and 64-bit builds are compiled separately but share the same source code and script pack. Switching between architectures requires compatible MySQL client libraries. ```text // Windows: replace 'libmysql.dll' file with the version included on downloaded zip // Linux: replace MySQL package (Ubuntu: 'libmysqlclient20' to 64bit or 'libmysqlclient20:i386' to 32bit / CentOS: 'mysql-community-libs' to 64bit or 'mysql-community-libs.i686' to 32bit) ``` -------------------------------- ### Load Player Data Asynchronously from MySQL C++ Source: https://context7.com/sphereserver/source/llms.txt Initiates an asynchronous SQL query to fetch player data from the 'characters' table based on player UID. It uses g_Serv.m_hdb.AsyncQueue to queue the query and specifies a callback function 'OnPlayerDataLoaded' to handle the results. The 'true' argument indicates that a callback is expected. ```cpp #include "common/CDataBase.h" void LoadPlayerDataAsync(LPCTSTR playerUID) { CGString query; query.Format("SELECT * FROM characters WHERE uid='%s'", playerUID); // Queue async query with callback function g_Serv.m_hdb.AsyncQueue(true, "OnPlayerDataLoaded", query.GetPtr()); } ``` -------------------------------- ### Initialize Client Encryption Source: https://context7.com/sphereserver/source/llms.txt Initializes the encryption mechanism for a client connection based on its version. It uses the CEncrypt class to set the appropriate encryption type (Twofish, Blowfish, or Login) and initializes it with a provided seed. Logs the encryption type used. Requires CClient and CEncrypt. ```cpp #include "common/CEncrypt.h" // Initialize encryption for client void InitializeClientEncryption(CClient* pClient, DWORD seed) { if (!pClient) { return; } // Get client version to determine encryption type CEncrypt* pEncrypt = &pClient->m_Crypt; // Initialize encryption with client seed pEncrypt->Init(seed); // Set encryption mode based on client type if (pClient->GetNetState()->m_clientType >= CLIENTTYPE_7000) { // Modern clients use enhanced encryption pEncrypt->SetEncryptionType(ENC_TWOFISH); } else if (pClient->GetNetState()->m_clientType >= CLIENTTYPE_4000) { // Medium-age clients pEncrypt->SetEncryptionType(ENC_BLOWFISH); } else { // Legacy clients pEncrypt->SetEncryptionType(ENC_LOGIN); } g_Log.Event(LOGL_EVENT, "Encryption initialized for client (type: %d)\n", pEncrypt->GetEncryptionType()); } ``` -------------------------------- ### Handle Client Targeting Source: https://context7.com/sphereserver/source/llms.txt Processes a client's target selection, checks if the target is valid, and displays information about the targeted character or item. Requires CClient, CChar, and CObjBase. ```cpp #include "graysvr/CClient.h" #include "network/packet.h" // Handle client targeting bool HandleTargeting(CClient* pClient, CChar* pCharSrc, CObjBase* pTarget) { if (!pClient || !pCharSrc) { return false; } // Check what was targeted if (!pTarget) { pClient->SysMessage("That is not a valid target."); return false; } // Check if target is a character if (pTarget->IsChar()) { CChar* pCharTarg = dynamic_cast(pTarget); // Display character info pClient->SysMessagef("Name: %s", pCharTarg->GetName()); pClient->SysMessagef("Health: %d/%d", pCharTarg->Stat_GetVal(STAT_STR), pCharTarg->Stat_GetMax(STAT_STR)); // Check distance int distance = pCharSrc->GetDist(pCharTarg); if (distance > 2) { pClient->SysMessage("Target is too far away."); return false; } return true; } // Check if target is an item if (pTarget->IsItem()) { CItem* pItem = dynamic_cast(pTarget); pClient->SysMessagef("Item: %s (ID: 0x%x)", pItem->GetName(), pItem->GetDispID()); return true; } return false; } ``` -------------------------------- ### Character Creation and Management (C++) Source: https://context7.com/sphereserver/source/llms.txt Handles the creation of NPC characters and modification of player character stats. It involves setting character attributes, skills, and their position in the world. Dependencies include 'CChar.h', 'CWorld.h', and 'CClient.h'. ```cpp #include "graysvr/CChar.h" #include "graysvr/CWorld.h" // Create a new NPC character void SpawnGuardNPC(CPointMap location) { // Create character from template CREID_TYPE guardID = CREID_GUARD; CChar* pGuard = CChar::CreateNPC(guardID); if (pGuard) { // Set NPC brain type pGuard->NPC_LoadScript(true); pGuard->SetNPCBrain(NPCBRAIN_GUARD); // Set statistics pGuard->Stat_SetVal(STAT_STR, 100); pGuard->Stat_SetVal(STAT_DEX, 80); pGuard->Stat_SetVal(STAT_INT, 50); // Set skills pGuard->Skill_SetBase(SKILL_SWORDSMANSHIP, 850); // 85.0 skill pGuard->Skill_SetBase(SKILL_TACTICS, 800); pGuard->Skill_SetBase(SKILL_PARRYING, 750); // Set home location and wander distance pGuard->m_ptHome = location; pGuard->m_pNPC->m_Home_Dist_Wander = 10; // Place in world pGuard->MoveToChar(location); pGuard->NPC_CreateTrigger(); pGuard->Update(); g_Log.Event(LOGL_EVENT, "Guard spawned at %d,%d,%d\n", location.m_x, location.m_y, location.m_z); } } // Modify player character stats bool LevelUpPlayer(CChar* pChar) { if (!pChar || !pChar->IsClient()) { return false; } // Check current stats int strVal = pChar->Stat_GetVal(STAT_STR); int dexVal = pChar->Stat_GetVal(STAT_DEX); int intVal = pChar->Stat_GetVal(STAT_INT); // Increase stats pChar->Stat_SetVal(STAT_STR, strVal + 5); pChar->Stat_SetVal(STAT_DEX, dexVal + 5); pChar->Stat_SetVal(STAT_INT, intVal + 5); // Update client display pChar->UpdateStatsFlag(); // Send message to player CClient* pClient = pChar->GetClient(); if (pClient) { pClient->SysMessage("You feel stronger!"); } return true; } ``` -------------------------------- ### Load Player Statistics from MySQL C++ Source: https://context7.com/sphereserver/source/llms.txt Executes a SQL query to retrieve player statistics such as total kills, deaths, and playtime from the 'player_stats' table. It processes the results and logs the found records. Handles query execution failures. ```cpp #include "common/CDataBase.h" bool LoadPlayerStatistics(LPCTSTR accountName) { CVarDefMap results; // Prepare query CGString query; query.Format("SELECT player_name, total_kills, total_deaths, playtime " "FROM player_stats WHERE account='%s' ORDER BY playtime DESC", accountName); // Execute query if (!g_Serv.m_hdb.Query(query.GetPtr(), results)) { g_Log.Event(LOGL_ERROR, "Database query failed: %s\n", query.GetPtr()); return false; } // Process results int rowCount = results.GetKeyNum(); g_Log.Event(LOGL_EVENT, "Found %d player records\n", rowCount); for (int i = 0; i < rowCount; i++) { CVarDefMap* pRow = dynamic_cast(results.GetKeyPtr("ROW", i)); if (!pRow) continue; LPCTSTR name = pRow->GetKeyStr("player_name"); int kills = pRow->GetKeyNum("total_kills"); int deaths = pRow->GetKeyNum("total_deaths"); int playtime = pRow->GetKeyNum("playtime"); g_Log.Event(LOGL_EVENT, "Player: %s | K: %d | D: %d | Time: %d hours\n", name, kills, deaths, playtime / 3600); } return true; } ``` -------------------------------- ### Save Player Kill Log to MySQL C++ Source: https://context7.com/sphereserver/source/llms.txt Logs a player kill event to the 'pvp_log' table and updates the 'total_kills' and 'total_deaths' counters in the 'player_stats' table. Uses CGString for query formatting and g_Serv.m_hdb.Exec for non-query commands. Returns false if logging fails. ```cpp #include "common/CDataBase.h" bool SavePlayerKill(LPCTSTR killerName, LPCTSTR victimName) { CGString query; query.Format("INSERT INTO pvp_log (killer, victim, timestamp) " "VALUES ('%s', '%s', NOW())", killerName, victimName); if (!g_Serv.m_hdb.Exec(query.GetPtr())) { g_Log.Event(LOGL_ERROR, "Failed to log kill to database\n"); return false; } // Update kill counter query.Format("UPDATE player_stats SET total_kills = total_kills + 1 " "WHERE player_name='%s'", killerName); g_Serv.m_hdb.Exec(query.GetPtr()); // Update death counter query.Format("UPDATE player_stats SET total_deaths = total_deaths + 1 " "WHERE player_name='%s'", victimName); g_Serv.m_hdb.Exec(query.GetPtr()); return true; } ``` -------------------------------- ### Handle Character Death in C++ Source: https://context7.com/sphereserver/source/llms.txt Manages the consequences of a character's death, including setting the dead flag, creating a corpse with transferable items, tracking player kills/deaths, and presenting a resurrection prompt. Requires CChar and CItemCorpse objects. ```cpp #include "graysvr/CCharFight.h" // Handle player death void HandleCharacterDeath(CChar* pChar, CChar* pKiller) { if (!pChar) { return; } // Set dead flag pChar->SetStatFlag(STATF_DEAD); // Create corpse CItemCorpse* pCorpse = dynamic_cast( CItem::CreateScript(ITEMID_CORPSE, pChar)); if (pCorpse) { pCorpse->SetCorpseType(pChar->GetDispID()); pCorpse->SetHue(pChar->GetHue()); pCorpse->MoveTo(pChar->GetTopPoint()); // Transfer items to corpse CItemContainer* pPack = pChar->GetPackSafe(); if (pPack) { CItem* pItem = pPack->GetContentHead(); while (pItem) { CItem* pNext = pItem->GetNext(); // Check if item is blessed/newbie if (!pItem->IsAttr(ATTR_BLESSED | ATTR_NEWBIE)) { pCorpse->ContentAdd(pItem); } pItem = pNext; } } pCorpse->Update(); } // Track murder if (pKiller && pKiller->IsClient() && pChar->IsClient()) { CCharPlayer* pKillerPlayer = pKiller->m_pPlayer; if (killerPlayer) { pKillerPlayer->m_wMurders++; // Check if player is now a murderer if (pKillerPlayer->m_wMurders >= 5) { pKiller->SetHue(HUE_RED); // Red name CClient* pClient = pKiller->GetClient(); if (pClient) { pClient->SysMessage("You are now a murderer!"); } } } } // Track death if (pChar->IsClient()) { CCharPlayer* pPlayer = pChar->m_pPlayer; if (pPlayer) { pPlayer->m_wDeaths++; } } // Resurrect prompt CClient* pClient = pChar->GetClient(); if (pClient) { pClient->addDeath(); // Show resurrection menu } } ``` -------------------------------- ### Sphere_dialog.scp Picinpic Documentation Source: https://github.com/sphereserver/source/blob/master/changelog.txt Documentation and comments for the 'picinpic' dialog element have been added to sphere_dialog.scp. This helps users understand and implement the new feature. ```sphere [sphere_dialog.scp]: Added 'picinpic' docs/comments ``` -------------------------------- ### Create Magical Weapon Source: https://context7.com/sphereserver/source/llms.txt Creates a magical sword with custom properties such as damage, elemental effects, and bonuses. It can optionally be added to the owner's inventory. Requires CItem and CChar classes. ```cpp #include "graysvr/CItem.h" // Create a magical weapon with properties CItem* CreateMagicalSword(CChar* pOwner) { // Create longsword item CItem* pSword = CItem::CreateScript(ITEMID_LONGSWORD); if (pSword) { // Set item name pSword->SetName("Flame Longsword"); // Set magical properties pSword->m_Attr |= ATTR_MAGIC | ATTR_IDENTIFIED; pSword->SetAttr(ATTR_EXCEPTIONAL); // Set combat bonuses pSword->m_DamageIncrease = 35; // +35% damage pSword->m_HitFireArea = 25; // 25% fire area attack pSword->m_StrengthBonus = 8; // +8 strength pSword->m_WeaponSpeed = 30; // +30% swing speed // Set durability pSword->m_itWeapon.m_Hits_Cur = 255; pSword->m_itWeapon.m_Hits_Max = 255; // Set color (orange/red for fire) pSword->SetHue(HUE_RED); // Add to owner's backpack if specified if (pOwner) { CItemContainer* pPack = pOwner->GetPackSafe(); if (pPack) { pPack->ContentAdd(pSword); } } pSword->Update(); } return pSword; } ``` -------------------------------- ### Spawn Monster Source: https://context7.com/sphereserver/source/llms.txt Spawns a creature (monster) at a specified location. It handles NPC creation, loading, movement, and updates. Optionally, it can assign a master to the spawned creature, making it a pet or summon. Requires CChar and g_World. ```cpp #include "graysvr/CWorld.h" // Spawn creature at location CChar* SpawnMonster(CREID_TYPE monsterID, CPointMap location, CChar* pMaster = NULL) { CChar* pMonster = CChar::CreateNPC(monsterID); if (pMonster) { pMonster->NPC_LoadScript(true); pMonster->MoveToChar(location); pMonster->Update(); pMonster->NPC_CreateTrigger(); // Set master if specified (for pets/summons) if (pMaster) { pMonster->NPC_PetSetOwner(pMaster); pMonster->Skill_Start(NPCACT_FOLLOW_TARG); } g_World.m_uidObj = pMonster->GetUID(); // Set as current script object } return pMonster; } ``` -------------------------------- ### Sphere Server Libev Library Updates and Optimization Source: https://github.com/sphereserver/source/blob/master/changelog.txt This changelog entry notes the update of internal Libev libraries from v4.27 to v4.31 and later to v4.33. It also mentions misc optimizations to the internal variables engine, ported from the SphereX branch by Nolok, which significantly improves server startup file loading performance. ```text // Updated internal Libev libs v4.27 to v4.31 // Updated internal Libev libs v4.31 to v4.33 // Misc optimizations on internal variables engine. // This should give a big performance boost to load files at server startup // Ported from SphereX branch, credits to Nolok ``` -------------------------------- ### OF_OSIMultiSight Item Visibility (SphereServer) Source: https://github.com/sphereserver/source/blob/master/changelog.txt The optional feature OF_OSIMultiSight in sphere.ini will now consistently display items with the CAN=can_i_block flag, regardless of other conditions. This improves visibility of blocking items within multi-user environments. ```sphere Changed: OF_OSIMultiSight optional feature on sphere.ini now will always show items that have CAN=can_i_block set. ``` -------------------------------- ### Save Player Data to Script File (C++) Source: https://context7.com/sphereserver/source/llms.txt Saves player character data to a script file using the CScript class. It writes a character section header and then individual key-value pairs for the player's name, stats, position, and skills. Requires a valid CChar pointer and a CScript object opened for writing. ```cpp #include "common/CScript.h" #include "graysvr/CResourceBase.h" // Write script data bool SavePlayerData(CChar* pChar, CScript& script) { if (!pChar) { return false; } // Write character section header script.WriteSection("[CHARACTER 0%x]", pChar->GetUID()); // Write character properties script.WriteKey("NAME", pChar->GetName()); script.WriteKeyVal("STR", pChar->Stat_GetBase(STAT_STR)); script.WriteKeyVal("DEX", pChar->Stat_GetBase(STAT_DEX)); script.WriteKeyVal("INT", pChar->Stat_GetBase(STAT_INT)); // Write position CPointMap pt = pChar->GetTopPoint(); script.WriteKeyFormat("P", "%d,%d,%d,%d", pt.m_x, pt.m_y, pt.m_z, pt.m_map); // Write skills for (int i = 0; i < SKILL_QTY; i++) { WORD skillVal = pChar->Skill_GetBase(static_cast(i)); if (skillVal > 0) { script.WriteKeyVal(g_Cfg.GetSkillKey(static_cast(i)), skillVal); } } return true; } ``` -------------------------------- ### Send Custom Message to Client Source: https://context7.com/sphereserver/source/llms.txt Sends a custom message with a specified hue to a connected game client. Requires CClient and HUE_TYPE. ```cpp #include "graysvr/CClient.h" #include "network/packet.h" // Send custom message to client void SendCustomMessage(CClient* pClient, LPCTSTR message, HUE_TYPE hue) { if (!pClient || !message) { return; } // Send system message with color pClient->SysMessageDefault(message, hue); } ``` -------------------------------- ### CombatArcheryMovementDelay Setting Addition (sphere.ini) Source: https://github.com/sphereserver/source/blob/master/changelog.txt A new setting, CombatArcheryMovementDelay, has been added to sphere.ini. This setting, ported from an experimental branch, likely controls delays related to archery combat movement. ```ini [sphere.ini]: Added new setting CombatArcheryMovementDelay (ported from experimental branch) ``` -------------------------------- ### Calculate Melee Damage in C++ Source: https://context7.com/sphereserver/source/llms.txt Calculates and applies melee damage based on attacker stats, weapon properties, and defender's armor. It includes critical hit logic and weapon durability updates. Dependencies include CCharFight.h and related game classes. ```cpp #include "graysvr/CCharFight.h" // Calculate and apply combat damage int CalculateMeleeDamage(CChar* pAttacker, CChar* pDefender, CItem* pWeapon) { if (!pAttacker || !pDefender) { return 0; } // Base damage from weapon int damageMin = 5; int damageMax = 15; if (pWeapon && pWeapon->IsTypeWeapon()) { damageMin = pWeapon->Weapon_GetAttack(false); damageMax = pWeapon->Weapon_GetAttack(true); } // Random damage in range int damage = damageMin + (rand() % (damageMax - damageMin + 1)); // Apply attacker strength bonus int str = pAttacker->Stat_GetVal(STAT_STR); damage += (str / 10); // Apply damage increase modifiers if (pWeapon) { damage += (damage * pWeapon->m_DamageIncrease) / 100; } // Calculate defense int defense = pDefender->CalcArmorDefense(); damage -= (defense / 2); // Minimum damage if (damage < 1) { damage = 1; } // Check for critical hit (10% chance) if ((rand() % 100) < 10) { damage *= 2; CClient* pClient = pAttacker->GetClient(); if (pClient) { pClient->SysMessage("Critical hit!"); } } // Apply damage pDefender->OnTakeDamage(damage, pAttacker, DAMAGE_HIT_BLUNT); // Update weapon durability if (pWeapon && pWeapon->m_itWeapon.m_Hits_Cur > 0) { pWeapon->m_itWeapon.m_Hits_Cur--; if (pWeapon->m_itWeapon.m_Hits_Cur <= 0) { CClient* pClient = pAttacker->GetClient(); if (pClient) { pClient->SysMessage("Your weapon breaks!"); } pWeapon->Delete(); } } return damage; } ``` -------------------------------- ### Ship and Movement Functionality Fixes Source: https://github.com/sphereserver/source/blob/master/changelog.txt This snippet outlines fixes and improvements related to ship mechanics and movement. It includes corrections for boat/ship screen updates, the NUDGEUP/NUDGEDOWN functions, and the PILOT function for ships, along with changes to ship tiller interaction and movement packet handling. ```plaintext Fixed: Boat/ship movement not updating client screen. Fixed: Function NUDGEUP/NUDGEDOWN not working correctly. Fixed: Function 'PILOT [PlayerUID]' on ships not working correctly (client >= 7.0.9.0 is required to use this feature). Changed: DClick on ship tiller man now will call the function PILOT by default. Changed: Misc improvements on ship movement packets. ``` -------------------------------- ### Add CODEXOFWISDOM Function Syntax Source: https://github.com/sphereserver/source/blob/master/changelog.txt This snippet details the syntax for a new server function, CODEXOFWISDOM. This function allows for opening the client's Codex of Wisdom menu at a specified topic ID. It accepts two optional parameters: TopicID (ranging from 1 to 176) and ForceOpen (a boolean value of 0 or 1). ```plaintext New function CODEXOFWISDOM to open client Codex of Wisdom menu at given topic ID. -Syntax: CODEXOFWISDOM TopicID (1~176), [ForceOpen (0/1)] ``` -------------------------------- ### Privilege and Account Functionality Fixes Source: https://github.com/sphereserver/source/blob/master/changelog.txt This snippet addresses a specific bug fix related to privilege set (PRIVSET) and account level (ACCOUNT.PLEVEL) functions. It corrects an issue where these functions failed to clear previous privilege flags when a player's level was decreased. ```plaintext Fixed: PRIVSET / ACCOUNT.PLEVEL functions not clearing previous plevel flags when plevel get decreased. ``` -------------------------------- ### Collect Resources In Area Source: https://context7.com/sphereserver/source/llms.txt Collects specified resources (items) within a radius around a center point and moves them to the player's backpack. It checks for movable items and provides feedback to the player on the number of items collected. Requires CWorldSearch, CChar, and CItemContainer. ```cpp #include "graysvr/CWorld.h" // Find items in area void CollectResourcesInArea(CChar* pChar, CPointMap center, int radius, ITEMID_TYPE resourceID) { CWorldSearch area(center, radius); CItemContainer* pPack = pChar->GetPackSafe(); if (!pPack) { return; } int collected = 0; while (true) { CItem* pItem = area.GetItem(); if (!pItem) { break; } // Check if this is the resource we want if (pItem->GetID() == resourceID && !pItem->IsAttr(ATTR_MOVE_NEVER)) { // Move to player's backpack pPack->ContentAdd(pItem); collected++; } } CClient* pClient = pChar->GetClient(); if (pClient && collected > 0) { pClient->SysMessagef("You collected %d items.", collected); } } ``` -------------------------------- ### New Houses Added (multis_houses_contest.scp) Source: https://github.com/sphereserver/source/blob/master/changelog.txt New houses from publish 106/107 have been added to the multis_houses_contest.scp script. This expands the available housing options within the game. ```sphere [items/multis/multis_houses_contest.scp]: Added new houses from publish 106/107 ``` -------------------------------- ### Player and Container Interaction Improvements Source: https://github.com/sphereserver/source/blob/master/changelog.txt This snippet describes changes in how the server handles item dropping and player interactions. It includes a fix for the multi-function CUSTOMIZE, a change in item placement logic when dropping items onto a full container grid (OSI style), and a fix for the optional flag OF_NoDClickTurn's behavior. ```plaintext Fixed: Multi function CUSTOMIZE not working correctly. Changed: When enhanced clients drop items on container grid index already in use, the item now will be placed on next available index (OSI style) instead first available index starting on 0 Fixed: Optional flag OF_NoDClickTurn on sphere.ini affecting target-based actions (now it will affect only DClick actions, as the name suggests). ``` -------------------------------- ### General Code and Configuration Fixes Source: https://github.com/sphereserver/source/blob/master/changelog.txt This snippet consolidates various minor fixes and corrections across different game aspects. It includes addressing misspellings in skill definitions, fixing comments in script files, and ensuring correct resource usage. ```plaintext [items/sphere_item_unsorted.scp]: UNEXISTANT RESOURCE i_pillow_fancy [sphere_newb.scp]: Wrong Comment Section [sphere_skills.scp]: ArmorRating MISTAPE ArmorRaring [sphere_template_sets.scp]: Fixed some error on server start ``` -------------------------------- ### Sphere Server Configuration and Script Updates Source: https://github.com/sphereserver/source/blob/master/changelog.txt This section covers modifications to configuration files (sphere.ini, sphere_backward_compatibility.scp) and script files (sphere_spells.scp, sphere_msgs.scp). These changes address issues with NPC behavior, item duplication, and spell effects, while also introducing new functionalities like supporting an 'amount' argument for 'addnpc' and 'static' functions. ```ini ; sphere.ini MulFiles=0 ; sphere_backward_compatibility.scp addnpc c_pig 5 static c_orc 10 ``` ```scp [sphere_spells.scp] // Fixed wrong LOCAL.FieldWidth value on field spells [sphere_msgs.scp] // Removed: npc_pet_deserted, party_add_too_fast, hl_one_client // Updated: magery_5, msg_frozen // Fixed typo: forensics_carbedby -> forensics_carvedby ``` -------------------------------- ### Broadcast Server Message Source: https://context7.com/sphereserver/source/llms.txt Broadcasts a server message to all currently online players. It utilizes the global g_World instance to send the message with an optional hue. No specific dependencies are required beyond the CWorld class. ```cpp #include "graysvr/CWorld.h" // Broadcast message to all online players void BroadcastServerMessage(LPCTSTR message, HUE_TYPE hue = HUE_TEXT_DEF) { // Global world instance: g_World g_World.Broadcast(message, hue); } ``` -------------------------------- ### Guest Account Privilege Removal (SphereServer) Source: https://github.com/sphereserver/source/blob/master/changelog.txt The obsolete 'guest' account privilege (plevel 0) has been removed. Guest privileges can now be softcoded, and accounts with PLEVEL=0 will automatically be updated to PLEVEL=1 (player) upon server startup. ```sphere Removed: Obsolete 'guest' account priv (plevel 0) -All 'guest' privs can be softcoded, so there's no reason to keep it hardcoded -Accounts with PLEVEL=0 (guest) will be automatically updated to PLEVEL=1 (player) at server startup ``` -------------------------------- ### Kick Player from Server Source: https://context7.com/sphereserver/source/llms.txt Removes a player from the server, optionally providing a reason. Logs the kick event and sends a message to the client before disconnecting. Requires CClient and CChar. ```cpp #include "graysvr/CClient.h" // Kick client from server void KickPlayer(CClient* pClient, LPCTSTR reason) { if (!pClient) { return; } CChar* pChar = pClient->GetChar(); if (pChar) { g_Log.Event(LOGL_EVENT, "Kicking player '%s' (Account: %s) - Reason: %s\n", pChar->GetName(), pClient->GetAccount()->GetName(), reason); } // Send message before disconnect pClient->SysMessagef("You have been kicked: %s", reason); // Disconnect client pClient->addKick(NULL, false); } ``` -------------------------------- ### New Vice Virtue Items Added (sphere_item_vice_virtue.scp) Source: https://github.com/sphereserver/source/blob/master/changelog.txt New items related to vice and virtue themes have been added from publish 107 to the sphere_item_vice_virtue.scp script. ```sphere [items/sphere_item_vice_virtue.scp]: Added new items from publish 107 ``` -------------------------------- ### Sphere.ini Setting Changes (GuestsMax, AccApp) Source: https://github.com/sphereserver/source/blob/master/changelog.txt The GuestsMax setting has been removed from sphere.ini, and the obsolete AccApp setting has been replaced with the new AutoAccountCreation. These changes streamline account management configurations. ```ini [sphere.ini]: Removed GuestsMax setting and replaced obsolete AccApp with new AutoAccountCreation ``` -------------------------------- ### SCP File Item and NPC Additions Source: https://github.com/sphereserver/source/blob/master/changelog.txt This snippet lists various additions and modifications to SCP (Scripting Control Package) files related to items and NPCs. It includes the addition of new character icons, holiday items, mount definitions, and other in-game assets across different SCP files. ```scp [items/sphere_item_char_icons.scp]: Added char icon 'i_pet_skeletal_cat' and 'i_pet_khal_ankur' [items/sphere_item_holiday_anniversary.scp]: Added publish 101 items [items/sphere_item_holiday_halloween.scp]: Added publish 101 items [items/sphere_item_holiday_thanksgiving.scp]: File renamed to 'sphere_item_holiday_other.scp' and added publish 100 items [items/sphere_item_memories.scp]: Added mount memory 'i_mt_skeletal_cat' [items/sphere_item_vegetation.scp]: Added publish 100 items [npcs/sphere_monsters.scp]: Added new TOL mount chardef 'c_skeletal_cat' and 'c_khal_ankur' [sphere_defs.scp]: Added mount defs for Skeletal Cat and some new bufficon/buffcliloc defs ```