اسکریبت individual_rates یکی از ویژگی این اسکریبت که پلیر یا وی آیپی کامند .rate xp و .rate loot داره 
فایل patch
کد PHP:
diff --git a/src/server/game/Entities/Creature/GossipDef.cpp b/src/server/game/Entities/Creature/GossipDef.cpp 
index f19f247
..70553a1 100644 --- a/src/server/game/Entities/Creature/GossipDef.cpp +++ b/src/server/game/Entities/Creature/GossipDef.cpp @@ -423,+423,@@ void PlayerMenu::SendQuestGiverQuestDetails(Quest const* questuint64 npcGUID
         } 
  
         
data << uint32(quest->GetRewOrReqMoney()); 
-        
data << uint32(quest->XPValue(_session->GetPlayer()) * sWorld->getRate(RATE_XP_QUEST)); 
+        
/*data << uint32(quest->XPValue(_session->GetPlayer()) * sWorld->getRate(RATE_XP_QUEST));*/ +        data << uint32(quest->XPValue(_session->GetPlayer()) * sWorld->getRate(RATE_XP_QUEST) * _session->GetPlayer()->GetCustomXpRate()); 
     } 
  
     
// rewarded honor points. Multiply with 10 to satisfy client @@ -661,+662,@@ void PlayerMenu::SendQuestGiverOfferReward(Quest const* questuint64 npcGUID
     

  
     
data << uint32(quest->GetRewOrReqMoney()); 
-    
data << uint32(quest->XPValue(_session->GetPlayer()) * sWorld->getRate(RATE_XP_QUEST)); 
+    
/*data << uint32(quest->XPValue(_session->GetPlayer()) * sWorld->getRate(RATE_XP_QUEST));*/ +    data << uint32(quest->XPValue(_session->GetPlayer()) * sWorld->getRate(RATE_XP_QUEST) * _session->GetPlayer()->GetCustomXpRate());
  
     
// rewarded honor points. Multiply with 10 to satisfy client 
     
data << uint32(10 quest->CalculateHonorGain(_session->GetPlayer()->GetQuestLevel(quest))); diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp 
index 2b39045
..22e6208 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -872,+872,@@ Player::Player(WorldSessionsession): Unit(true
     
_activeCheats CHEAT_NONE
     
m_achievementMgr = new AchievementMgr(this); 
     
m_reputationMgr = new ReputationMgr(this); 

+    
m_CustomXpRate 1
+    
m_CustomLootRate 1
 } 
  
 
Player::~Player() 
@@ -
6903,+6906,@@ void Player::CheckAreaExploreAndOutdoor() 
                     
XP uint32(sObjectMgr->GetBaseXP(areaEntry->area_level)*sWorld->getRate(RATE_XP_EXPLORE)); 
                 } 
  
+                
XP *= GetCustomXpRate(); 
                 
GiveXP(XPNULL); 
                 
SendExplorationExperience(areaXP); 
             } 
@@ -
15238,+15242,@@ void Player::RewardQuest(Quest const* questuint32 rewardObjectquestGiver
     
bool rewarded = (m_RewardedQuests.find(quest_id) != m_RewardedQuests.end()); 
  
     
// Not give XP in case already completed once repeatable quest -    uint32 XP rewarded uint32(quest->XPValue(this)*sWorld->getRate(RATE_XP_QUEST)); 
+    
/*uint32 XP = rewarded ? 0 : uint32(quest->XPValue(this)*sWorld->getRate(RATE_XP_QUEST));*/ +    uint32 XP rewarded uint32(quest->XPValue(this)*sWorld->getRate(RATE_XP_QUEST) * GetCustomXpRate()); 
  
     
// handle SPELL_AURA_MOD_XP_QUEST_PCT auras 
     
Unit::AuraEffectList const& ModXPPctAuras GetAuraEffectsByType(SPELL_AURA_MOD_XP_QUEST_PCT); diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.
index 1c0fa4e
..b37e99d 100644 --- a/src/server/game/Entities/Player/Player.+++ b/src/server/game/Entities/Player/Player.@@ -2287,+2287,12 @@ class Player : public Unit, public GridObject<Player
         
//! Return collision height sent to client 
         
float GetCollisionHeight(bool mounted) const; 
  
+        
void SetCustomXpRate(uint32 rate) { m_CustomXpRate rate; } 
+        
uint32 GetCustomXpRate() const { return m_CustomXpRate; } 

+        
void SetCustomLootRate(uint32 rate) { m_CustomLootRate rate; } 
+        
uint32 GetCustomLootRate() const { return m_CustomLootRate; } 

     protected: 
         
// Gamemaster whisper whitelist 
         
WhisperListContainer WhisperList
@@ -
2614,+2620,@@ class Player : public Unit, public GridObject<Player
         
uint32 _pendingBindTimer
  
         
uint32 _activeCheats

+        
uint32 m_CustomXpRate
+        
uint32 m_CustomLootRate
 }; 
  
 
void AddItemsSetItem(Player*playerItemitem); diff --git a/src/server/game/Loot/LootMgr.cpp b/src/server/game/Loot/LootMgr.cpp 
index fcef203
..606d9f1 100644 --- a/src/server/game/Loot/LootMgr.cpp +++ b/src/server/game/Loot/LootMgr.cpp @@ -275,17 +275,20 @@ void LootStore::ReportNotExistedId(uint32 id) const 
  
 
// Checks if the entry (quest, non-quest, reference) takes it's chance (at loot generation) 
 // RATE_DROP_ITEMS is no longer used for all types of entries 
-bool LootStoreItem::Roll(bool rate) const 
+
//bool LootStoreItem::Roll(bool rate) const +bool LootStoreItem::Roll(bool rateuint32 customRate) const 
 { 
     if (
chance >= 100.0f
         return 
true
  
     if (
mincountOrRef 0)                                   // reference case -        return roll_chance_f(chance* (rate sWorld->getRate(RATE_DROP_ITEM_REFERENCED) : 1.0f)); 
+       
/* return roll_chance_f(chance* (rate ? sWorld->getRate(RATE_DROP_ITEM_REFERENCED) : 1.0f));*/ +        return roll_chance_f(chance* (rate sWorld->getRate(RATE_DROP_ITEM_REFERENCED) * customRate 1.0f)); 
  
     
ItemTemplate const* pProto sObjectMgr->GetItemTemplate(itemid); 
  
-    
float qualityModifier pProto && rate sWorld->getRate(qualityToRate[pProto->Quality]) : 1.0f
+    
/*float qualityModifier = pProto && rate ? sWorld->getRate(qualityToRate[pProto->Quality]) : 1.0f;*/ +    float qualityModifier pProto && rate sWorld->getRate(qualityToRate[pProto->Quality]) * customRate 1.0f
  
     return 
roll_chance_f(chance*qualityModifier); 
 } 
@@ -
456,+459,@@ bool Loot::FillLoot(uint32 lootIdLootStore const& storePlayerlootOwnerbo 
     items
.reserve(MAX_NR_LOOT_ITEMS); 
     
quest_items.reserve(MAX_NR_QUEST_ITEMS); 
  
-    
tab->Process(*thisstore.IsRatesAllowed(), lootMode);          // Processing is done there, callback via Loot::AddItem() +    //tab->Process(*this, store.IsRatesAllowed(), lootMode);          // Processing is done there, callback via Loot::AddItem() +    tab->Process(*thisstore.IsRatesAllowed(), lootMode0lootOwner->GetCustomLootRate());          // Processing is done there, callback via Loot::AddItem() 
  
     // Setting access rights for group loot case 
     
Groupgroup lootOwner->GetGroup(); 
@@ -
1273,+1277,@@ void LootTemplate::CopyConditions(LootItemli) const 
 } 
  
 
// Rolls for every item in the template and adds the rolled items the the loot -void LootTemplate::Process(Lootlootbool rateuint16 lootModeuint8 groupId) const 
+
//void LootTemplate::Process(Loot& loot, bool rate, uint16 lootMode, uint8 groupId) const +void LootTemplate::Process(Lootlootbool rateuint16 lootModeuint8 groupIduint32 customRate) const 
 { 
     if (
groupId)                                            // Group reference uses own processing of the group 
     

@@ -
1294,+1299,@@ void LootTemplate::Process(Lootlootbool rateuint16 lootModeuint8 groupId 
         
if (!(item->lootmode lootMode))                       // Do not add if mode mismatch 
             
continue; 
  
-        if (!
item->Roll(rate)) 
+        
/*if (!item->Roll(rate))*/ +        if (!item->Roll(ratecustomRate)) 
             continue;                                           
// Bad luck for the entry 
  
         
if (item->mincountOrRef 0)                            // References processing diff --git a/src/server/game/Loot/LootMgr.h b/src/server/game/Loot/LootMgr.
index d338f6f
..cfcc73e 100644 --- a/src/server/game/Loot/LootMgr.+++ b/src/server/game/Loot/LootMgr.@@ -119,+119,@@ struct LootStoreItem 
         group
(_group), needs_quest(_chanceOrQuestChance 0), maxcount(_maxcount
          {} 
  
-    
bool Roll(bool rate) const;                             // Checks if the entry takes it's chance (at loot generation) +    //bool Roll(bool rate) const;                             // Checks if the entry takes it's chance (at loot generation) +    bool Roll(bool rateuint32 customRate) const;          // Checks if the entry takes it's chance (at loot generation) 
     
bool IsValid(LootStore const& storeuint32 entry) const; 
                                                             
// Checks correctness of values 
 
}; 
@@ -
227,+228,@@ class LootTemplate 
         
// Adds an entry to the group (at loading stage) 
         
void AddEntry(LootStoreItemitem); 
         
// Rolls for every item in the template and adds the rolled items the the loot -        void Process(Lootlootbool rateuint16 lootModeuint8 groupId 0) const; 
+        
/*void Process(Loot& loot, bool rate, uint16 lootMode, uint8 groupId = 0) const;*/ +        void Process(Lootlootbool rateuint16 lootModeuint8 groupId 0uint32 customRate 1) const; 
         
void CopyConditions(ConditionList conditions); 
         
void CopyConditions(LootItemli) const; 
  
diff --git a/src/server/game/Miscellaneous/Formulas.h b/src/server/game/Miscellaneous/Formulas.
index 6579485.
.dc142bb 100644 --- a/src/server/game/Miscellaneous/Formulas.+++ b/src/server/game/Miscellaneous/Formulas.@@ -180,+180,@@ namespace Trinity 
                         gain 
*= 2
                 } 
  
-                return 
uint32(gain sWorld->getRate(RATE_XP_KILL)*premium_rate); 
+                
/*return uint32(gain * sWorld->getRate(RATE_XP_KILL)*premium_rate);*/ +                return uint32(gain sWorld->getRate(RATE_XP_KILL) * player->GetCustomXpRate()); 
             } 
  
             
sScriptMgr->OnGainCalculation(gainplayeru); diff --git a/src/server/game/Scripting/ScriptLoader.cpp b/src/server/game/Scripting/ScriptLoader.cpp 
index edabc7b
..d62f780 100644 --- a/src/server/game/Scripting/ScriptLoader.cpp +++ b/src/server/game/Scripting/ScriptLoader.cpp @@ -1291,13 +1291,13 @@ void AddBattlegroundScripts() 
  
 
#ifdef SCRIPTS 
 /* This is where custom scripts' loading functions should be declared. */ 

+    
void Add_SC_Custom_Rates(); 
 
#endif 
  
 
void AddCustomScripts() 
 { 
 
#ifdef SCRIPTS 
     /* This is where custom scripts should be added. */ 

+    
Add_SC_Custom_Rates(); 
 
#endif 
 
diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp 
index 834f02d
..ad26a61 100644 --- a/src/server/game/World/World.cpp +++ b/src/server/game/World/World.cpp @@ -1222,+1222,49 @@ void World::LoadConfigSettings(bool reload
     
m_int_configs[CONFIG_WINTERGRASP_NOBATTLETIME] = sConfigMgr->GetIntDefault("Wintergrasp.NoBattleTimer"150); 
     
m_int_configs[CONFIG_WINTERGRASP_RESTART_AFTER_CRASH] = sConfigMgr->GetIntDefault("Wintergrasp.CrashRestartTimer"10); 
  
+    
// Individual XP/loot rates +    int sec sConfigMgr->GetIntDefault("Player.XpRateSecurity"0); 
+    if (
sec SEC_PLAYER || sec SEC_ADMINISTRATOR
+    { 
+        
TC_LOG_ERROR(LOG_FILTER_SERVER_LOADING"Player.XpRateSecurity has invalid security `%i`, must be between `%i and `%i`, defaulting to 0 ..."
+            
secSEC_PLAYERSEC_ADMINISTRATOR); 
+        
m_int_configs[CONFIG_PLAYER_INDIVIDUAL_XP_RATE_SECURITY] = 0
+    } 
+    else 
+        
m_int_configs[CONFIG_PLAYER_INDIVIDUAL_XP_RATE_SECURITY] = sec

+    
sec sConfigMgr->GetIntDefault("Player.LootRateSecurity"0); 
+    if (
sec SEC_PLAYER || sec SEC_ADMINISTRATOR
+    { 
+        
TC_LOG_ERROR(LOG_FILTER_SERVER_LOADING"Player.LootRateSecurity has invalid security `%i`, must be between `%i and `%i`, defaulting to 0 ..."
+            
secSEC_PLAYERSEC_ADMINISTRATOR); 
+        
m_int_configs[CONFIG_PLAYER_INDIVIDUAL_LOOT_RATE_SECURITY] = 0
+    } 
+    else 
+        
m_int_configs[CONFIG_PLAYER_INDIVIDUAL_LOOT_RATE_SECURITY] = sec

+    
int maxXpRate sConfigMgr->GetIntDefault("Player.MaximumXpRate"1); 
+    if (
maxXpRate 1
+    { 
+        
TC_LOG_ERROR(LOG_FILTER_SERVER_LOADING"Player.MaximumXpRate has too low value `%i`, defaulting to 1 ..."maxXpRate); 
+        
m_int_configs[CONFIG_PLAYER_MAXIMUM_INDIVIDUAL_XP_RATE] = 1
+    } 
+    else 
+        
m_int_configs[CONFIG_PLAYER_MAXIMUM_INDIVIDUAL_XP_RATE] = maxXpRate

+    
maxXpRate sConfigMgr->GetIntDefault("Player.MaximumLootRate"1); 
+    if (
maxXpRate 1
+    { 
+        
TC_LOG_ERROR(LOG_FILTER_SERVER_LOADING"Player.MaximumLootRate has too low value `%i`, defaulting to 1 ..."maxXpRate); 
+        
m_int_configs[CONFIG_PLAYER_MAXIMUM_INDIVIDUAL_LOOT_RATE] = 1
+    } 
+    else 
+        
m_int_configs[CONFIG_PLAYER_MAXIMUM_INDIVIDUAL_LOOT_RATE] = maxXpRate

+    
m_bool_configs[CONFIG_PLAYER_INDIVIDUAL_XP_RATE_SHOW_ON_LOGIN] = sConfigMgr->GetBoolDefault("Player.ShowXpRateOnLogin"true); 
+    
m_bool_configs[CONFIG_PLAYER_INDIVIDUAL_LOOT_RATE_SHOW_ON_LOGIN] = sConfigMgr->GetBoolDefault("Player.ShowLootRateOnLogin"true);


     
// call ScriptMgr if we're reloading the configuration 
     
if (reload
         
sScriptMgr->OnConfigLoad(reload); diff --git a/src/server/game/World/World.h b/src/server/game/World/World.
index 984a170
..0cc53ed 100644 --- a/src/server/game/World/World.+++ b/src/server/game/World/World.@@ -159,+159,@@ enum WorldBoolConfigs 
     CONFIG_WINTERGRASP_ENABLE

     
CONFIG_UI_QUESTLEVELS_IN_DIALOGS,     // Should we add quest levels to the title in the NPC dialogs? 
     
CONFIG_EVENT_ANNOUNCE
+    
CONFIG_PLAYER_INDIVIDUAL_XP_RATE_SHOW_ON_LOGIN
+    
CONFIG_PLAYER_INDIVIDUAL_LOOT_RATE_SHOW_ON_LOGIN
     
BOOL_CONFIG_VALUE_COUNT 
 
}; 
  
@@ -
321,+323,10 @@ enum WorldIntConfigs 
     CONFIG_WINTERGRASP_BATTLETIME

     
CONFIG_WINTERGRASP_NOBATTLETIME
     
CONFIG_WINTERGRASP_RESTART_AFTER_CRASH
+    
CONFIG_PLAYER_INDIVIDUAL_XP_RATE_SECURITY
+    
CONFIG_PLAYER_INDIVIDUAL_LOOT_RATE_SECURITY 
+    
CONFIG_PLAYER_MAXIMUM_INDIVIDUAL_XP_RATE
+    
CONFIG_PLAYER_MAXIMUM_INDIVIDUAL_LOOT_RATE
     
INT_CONFIG_VALUE_COUNT 
 
}; 
  
diff --git a/src/server/scripts/Custom/CMakeLists.txt b/src/server/scripts/Custom/CMakeLists.txt 
index 99cf026
..68795ef 100644 --- a/src/server/scripts/Custom/CMakeLists.txt +++ b/src/server/scripts/Custom/CMakeLists.txt @@ -10,+10,@@ 
  
 
set(scripts_STAT_SRCS 
   
${scripts_STAT_SRCS
+  
Custom/custom_rates.cpp 
 

  
 
message("  -> Prepared: Custom"diff --git a/src/server/shared/Database/Implementation/CharacterDatabase.cpp b/src/server/shared/Database/Implementation/CharacterDatabase.cpp
index 2e6ab10
..7bda067 100644 --- a/src/server/shared/Database/Implementation/CharacterDatabase.cpp +++ b/src/server/shared/Database/Implementation/CharacterDatabase.cpp @@ -592,+592,12 @@ void CharacterDatabaseConnection::DoPrepareStatements() 
     
PrepareStatement(CHAR_UPD_CHAR_PET_SLOT_BY_ID"UPDATE character_pet SET slot = ? WHERE owner = ? AND id = ?"CONNECTION_ASYNC); 
     
PrepareStatement(CHAR_DEL_CHAR_PET_BY_ID"DELETE FROM character_pet WHERE id = ?"CONNECTION_ASYNC); 
     
PrepareStatement(CHAR_DEL_CHAR_PET_BY_SLOT"DELETE FROM character_pet WHERE owner = ? AND (slot = ? OR slot > ?)"CONNECTION_ASYNC); 
+    
PrepareStatement(CHAR_INS_INDIVIDUAL_XP_RATE"INSERT INTO character_xp_rate (guid, xp_rate) VALUES (?, ?)"CONNECTION_ASYNC); 
+    
PrepareStatement(CHAR_DEL_INDIVIDUAL_XP_RATE"DELETE FROM character_xp_rate WHERE guid = ?"CONNECTION_ASYNC); 
+    
PrepareStatement(CHAR_SEL_INDIVIDUAL_XP_RATE"SELECT xp_rate FROM character_xp_rate WHERE guid = ?"CONNECTION_SYNCH); 
+    
PrepareStatement(CHAR_UPD_INDIVIDUAL_XP_RATE"UPDATE character_xp_rate SET xp_rate = ? WHERE guid = ?"CONNECTION_ASYNC); 
+    
PrepareStatement(CHAR_INS_INDIVIDUAL_LOOT_RATE"INSERT INTO character_loot_rate (guid, loot_rate) VALUES (?, ?)"CONNECTION_ASYNC); 
+    
PrepareStatement(CHAR_DEL_INDIVIDUAL_LOOT_RATE"DELETE FROM character_loot_rate WHERE guid = ?"CONNECTION_ASYNC); 
+    
PrepareStatement(CHAR_SEL_INDIVIDUAL_LOOT_RATE"SELECT loot_rate FROM character_loot_rate WHERE guid = ?"CONNECTION_SYNCH); 
+    
PrepareStatement(CHAR_UPD_INDIVIDUAL_LOOT_RATE"UPDATE character_loot_rate SET loot_rate = ? WHERE guid = ?"CONNECTION_ASYNC); 
 } 
diff --git a/src/server/shared/Database/Implementation/CharacterDatabase.h b/src/server/shared/Database/Implementation/CharacterDatabase.
index 59ac159
..46d44ba 100644 --- a/src/server/shared/Database/Implementation/CharacterDatabase.+++ b/src/server/shared/Database/Implementation/CharacterDatabase.@@ -526,+526,16 @@ enum CharacterDatabaseStatements 
     CHAR_DEL_ITEMCONTAINER_MONEY

     
CHAR_INS_ITEMCONTAINER_MONEY
  
+    
CHAR_INS_INDIVIDUAL_XP_RATE
+    
CHAR_DEL_INDIVIDUAL_XP_RATE
+    
CHAR_SEL_INDIVIDUAL_XP_RATE
+    
CHAR_UPD_INDIVIDUAL_XP_RATE

+    
CHAR_INS_INDIVIDUAL_LOOT_RATE
+    
CHAR_DEL_INDIVIDUAL_LOOT_RATE
+    
CHAR_SEL_INDIVIDUAL_LOOT_RATE
+    
CHAR_UPD_INDIVIDUAL_LOOT_RATE

     
MAX_CHARACTERDATABASE_STATEMENTS 
 
}; 
  
diff --git a/src/server/worldserver/worldserver.conf.dist b/src/server/worldserver/worldserver.conf.dist 
index a9b09e5
..7cf5d82 100644 --- a/src/server/worldserver/worldserver.conf.dist +++ b/src/server/worldserver/worldserver.conf.dist @@ -2768,+2768,46 @@ Log.Async.Enable 
  
 

 ################################################################################################### 

+
################################################################################################### +# INDIVIDUAL PLAYER XP RATES ++#    Player.XpRateSecurity +#    Player.LootRateSecurity +#        Description: Minimum security an account must have in order to +#                     use .rate xp / .rate loot command +#        Values     : 0 (player account) +#                     1 (moderator account) +#                     2 (gamemaster account) +#                     3 (administrator account) +#        Default    : 0 (every player can use the commands) +#        Remarks    : Higher security accounts may set xp/loot rate to +#                     lower security level accounts. +
+
Player.XpRateSecurity +Player.LootRateSecurity 
+
#    Player.MaximumXpRate +#    Player.MaximumLootRate +#        Description: Maximum individual XP / loot rate +#        Values     : n (integer, may set xp / loot rate in range [1,n] +#        Default    : 10 +
+
Player.MaximumXpRate 10 +Player.MaximumLootRate 10 
+
#    Player.ShowXpRateOnLogin +#    Player.ShowLootRateOnLogin +#        Description: Shows current XP / loot rate to player on login +#        Values     : 0 - don't show +#                   : 1 - show +#        Default    : 1 +
+
Player.ShowXpRateOnLogin +Player.ShowLootRateOnLogin 
+
+###################################################################################################  
اسکریبت cpp
کد PHP:
#include "ScriptMgr.h" 
#include "Chat.h" 
#include "Language.h" 
class CustomRates 
private: 
    static 
int32 GetRateFromDB(const Player *playerCharacterDatabaseStatements statement
    { 
        
PreparedStatement *stmt CharacterDatabase.GetPreparedStatement(statement); 
        
stmt->setUInt32(0player->GetGUIDLow()); 
        
PreparedQueryResult result CharacterDatabase.Query(stmt); 

        if (
result
            return 
static_cast<int32>((*result)[0].GetUInt32()); 

        return -
1
    } 

    static 
void SaveRateToDB(const Player *playeruint32 ratebool updateCharacterDatabaseStatements uStmtCharacterDatabaseStatements iStmt
    { 
        if (
update
        { 
            
PreparedStatement *stmt CharacterDatabase.GetPreparedStatement(uStmt); 
            
stmt->setUInt32(0rate); 
            
stmt->setUInt32(1player->GetGUIDLow()); 
            
CharacterDatabase.Execute(stmt); 
        } 
        else 
        { 
            
PreparedStatement *stmt CharacterDatabase.GetPreparedStatement(iStmt); 
            
stmt->setUInt32(0player->GetGUIDLow()); 
            
stmt->setUInt32(1rate); 
            
CharacterDatabase.Execute(stmt); 
        } 
    } 
public: 
    static 
void DeleteRateFromDB(uint64 guidCharacterDatabaseStatements statement
    { 
        
PreparedStatement *stmt CharacterDatabase.GetPreparedStatement(statement); 
        
stmt->setUInt32(0GUID_LOPART(guid)); 
        
CharacterDatabase.Execute(stmt); 
    } 

    static 
int32 GetXpRateFromDB(const Player *player
    { 
        return 
GetRateFromDB(playerCHAR_SEL_INDIVIDUAL_XP_RATE); 
    } 

    static 
int32 GetLootRateFromDB(const Player *player
    { 
        return 
GetRateFromDB(playerCHAR_SEL_INDIVIDUAL_LOOT_RATE); 
    } 

    static 
void SaveXpRateToDB(const Player *playeruint32 ratebool update
    { 
        
SaveRateToDB(playerrateupdateCHAR_UPD_INDIVIDUAL_XP_RATECHAR_INS_INDIVIDUAL_XP_RATE); 
    } 

    static 
void SaveLootRateToDB(const Player *playeruint32 ratebool update
    { 
        
SaveRateToDB(playerrateupdateCHAR_UPD_INDIVIDUAL_LOOT_RATECHAR_INS_INDIVIDUAL_LOOT_RATE); 
    } 
}; 

class 
add_del_rates : public PlayerScript 
public: 
    
add_del_rates() : PlayerScript("add_del_rates"
    { 
    } 

    
void OnDelete(uint64 guid
    { 
        
CustomRates::DeleteRateFromDB(guidCHAR_DEL_INDIVIDUAL_XP_RATE); 
        
CustomRates::DeleteRateFromDB(guidCHAR_DEL_INDIVIDUAL_LOOT_RATE); 
    } 

    
void OnLogin(Player *player
    { 
        
// show custom XP rate on login 
        
int32 rate CustomRates::GetXpRateFromDB(player); 

        if (
rate != -&& player->getLevel() != sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL)) 
        { 
            
uint32 uRate static_cast<uint32>(rate); 
            
player->SetCustomXpRate(uRate); 

            if (
sWorld->getBoolConfig(CONFIG_PLAYER_INDIVIDUAL_XP_RATE_SHOW_ON_LOGIN)) 
            { 
                if (
uRate
                    
ChatHandler(player->GetSession()).PSendSysMessage("|CFF7BBEF7[Custom Rates]|r: Your XP rate was set to %u."uRate); 
                else 
                    
ChatHandler(player->GetSession()).SendSysMessage("|CFF7BBEF7[Custom Rates]|r: Your XP rate was set to 0. You won't gain any XP anymore."); 
            } 
        } 

        
// show custom loot rate on login 
        
rate CustomRates::GetLootRateFromDB(player); 
        if (
rate != -1
        { 
            
uint32 uRate static_cast<uint32>(rate); 
            
player->SetCustomLootRate(uRate); 

            if (
sWorld->getBoolConfig(CONFIG_PLAYER_INDIVIDUAL_LOOT_RATE_SHOW_ON_LOGIN)) 
            { 
                if (
uRate
                    
ChatHandler(player->GetSession()).PSendSysMessage("|CFF7BBEF7[Custom Rates]|r: Your loot rate was set to %u."uRate); 
                else 
                    
ChatHandler(player->GetSession()).SendSysMessage("|CFF7BBEF7[Custom Rates]|r: Your loot rate was set to 0. You won't be able to loot anything."); 
            } 
        } 
    } 
}; 

class 
custom_rate_commands : public CommandScript 
private: 
     
public: 
    
custom_rate_commands() : CommandScript("custom_rate_commands"
    { 
    } 

    
ChatCommand *GetCommands() const 
    { 
        static 
ChatCommand rateCommandTable[] = 
        { 
            { 
"xp"SEC_PLAYERfalse, &HandleRateXpCommand""NULL }, 
            { 
"loot"SEC_PLAYERfalse, &HandleRateLootCommand""NULL }, 
            { 
NULLSEC_PLAYERfalseNULL""NULL 
        }; 

        static 
ChatCommand commandTable[] = 
        { 
            { 
"rate"SEC_PLAYERfalseNULL""rateCommandTable }, 
            { 
NULLSEC_PLAYERfalseNULL""NULL 
        }; 

        return 
commandTable
    } 

    static 
bool HandleRateXpCommand(ChatHandler *handler, const char *args
    { 
        
// take a pointer to the player who uses the command 
        
Player *me handler->GetSession() ? handler->GetSession()->GetPlayer() : NULL
        if (!
me
            return 
false

        
// already at max level, no point in using the command at all 
        
if (me->getLevel() == sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL)) 
        { 
            
handler->SendSysMessage("|CFF7BBEF7[Custom Rates]|r: You are already at maximum level."); 
            return 
true
        } 

        
// no arguments, show current XP rate 
        
if (!*args
        { 
            
handler->PSendSysMessage("|CFF7BBEF7[Custom Rates]|r: Your current XP rate is %u."me->GetCustomXpRate()); 
            return 
true
        } 

        
// first, check if I can use the command 
        
if (me->GetSession()->GetSecurity() < (int)sWorld->getIntConfig(CONFIG_PLAYER_INDIVIDUAL_XP_RATE_SECURITY)) 
        { 
            
handler->SendSysMessage(LANG_YOURS_SECURITY_IS_LOW); 
            
handler->SetSentErrorMessage(true); 
            return 
false
        } 

        
// take a pointer to player's selection 
        
Player *target handler->getSelectedPlayer(); 
        if (!
target || !target->GetSession()) 
        { 
            
handler->SendSysMessage(LANG_NO_CHAR_SELECTED); 
            
handler->SetSentErrorMessage(true); 
            return 
false
        } 

        
// extract value 
        
int rate atoi((char *)args); 
        
int maxRate sWorld->getIntConfig(CONFIG_PLAYER_MAXIMUM_INDIVIDUAL_XP_RATE); 
        if (
rate || rate maxRate
        { 
            
handler->PSendSysMessage("|CFF7BBEF7[Custom Rates]|r: Invalid rate specified, must be in interval [0,%i]."maxRate); 
            
handler->SetSentErrorMessage(true); 
            return 
false
        } 

        
// take a pointer to the player we need to set xp rate to 
        // can be either player itself, or his selection, if 
        // selection security is lower than his security 
        
Player *player NULL
        if (
target == me
            
player me
        else 
        { 
            if (
me->GetSession()->GetSecurity() > target->GetSession()->GetSecurity()) 
                
player target
            else 
            { 
                
handler->SendSysMessage(LANG_YOURS_SECURITY_IS_LOW); 
                
handler->SetSentErrorMessage(true); 
                return 
false
            } 
        } 

        
// set player custom XP rate and save it in DB for later use 
        
uint32 uRate static_cast<uint32>(rate); 
        
player->SetCustomXpRate(uRate); 
        
int32 rateFromDB CustomRates::GetXpRateFromDB(player); 
        if (
rateFromDB == -1
            
CustomRates::SaveXpRateToDB(playeruRatefalse); 
        else 
            
CustomRates::SaveXpRateToDB(playeruRatetrue); 

        
// show a message indicating custom XP rate change 
        
if (player == me
            
handler->PSendSysMessage("|CFF7BBEF7[Custom Rates]|r: You have set your XP rate to %u."uRate); 
        else 
        { 
            
handler->PSendSysMessage("|CFF7BBEF7[Custom Rates]|r: You have set %s's XP rate to %u."handler->GetNameLink(player).c_str(), uRate); 
            
ChatHandler(player->GetSession()).PSendSysMessage("|CFF7BBEF7[Custom Rates]|r: %s has set your XP rate to %u."handler->GetNameLink().c_str(), uRate); 
        } 

        return 
true
    } 

    static 
bool HandleRateLootCommand(ChatHandler *handler, const char *args
    { 
        
// take a pointer to the player who uses the command 
        
Player *me handler->GetSession() ? handler->GetSession()->GetPlayer() : NULL
        if (!
me
            return 
false

        
// no arguments, show current loot rate 
        
if (!*args
        { 
            
handler->PSendSysMessage("|CFF7BBEF7[Custom Rates]|r: Your current loot rate is %u."me->GetCustomLootRate()); 
            return 
true
        } 

        
// first, check if I can use the command 
        
if (me->GetSession()->GetSecurity() < (int)sWorld->getIntConfig(CONFIG_PLAYER_INDIVIDUAL_LOOT_RATE_SECURITY)) 
        { 
            
handler->SendSysMessage(LANG_YOURS_SECURITY_IS_LOW); 
            
handler->SetSentErrorMessage(true); 
            return 
false
        } 

        
// take a pointer to player's selection 
        
Player *target handler->getSelectedPlayer(); 
        if (!
target || !target->GetSession()) 
        { 
            
handler->SendSysMessage(LANG_NO_CHAR_SELECTED); 
            
handler->SetSentErrorMessage(true); 
            return 
false
        } 

        
// extract value 
        
int rate atoi((char *)args); 
        
int maxRate sWorld->getIntConfig(CONFIG_PLAYER_MAXIMUM_INDIVIDUAL_LOOT_RATE); 
        if (
rate || rate maxRate
        { 
            
handler->PSendSysMessage("|CFF7BBEF7[Custom Rates]|r: Invalid rate specified, must be in interval [0,%i]."maxRate); 
            
handler->SetSentErrorMessage(true); 
            return 
false
        } 

        
// take a pointer to the player we need to set xp rate to 
        // can be either player itself, or his selection, if 
        // selection security is lower than his security 
        
Player *player NULL
        if (
target == me
            
player me
        else 
        { 
            if (
me->GetSession()->GetSecurity() > target->GetSession()->GetSecurity()) 
                
player target
            else 
            { 
                
handler->SendSysMessage(LANG_YOURS_SECURITY_IS_LOW); 
                
handler->SetSentErrorMessage(true); 
                return 
false
            } 
        } 

        
// set player custom loot rate and save it in DB for later use 
        
uint32 uRate static_cast<uint32>(rate); 
        
player->SetCustomLootRate(uRate); 
        
int32 rateFromDB CustomRates::GetLootRateFromDB(player); 
        if (
rateFromDB == -1
            
CustomRates::SaveLootRateToDB(playeruRatefalse); 
        else 
            
CustomRates::SaveLootRateToDB(playeruRatetrue); 

        
// show a message indicating custom XP rate change 
        
if (player == me
            
handler->PSendSysMessage("|CFF7BBEF7[Custom Rates]|r: You have set your loot rate to %u."uRate); 
        else 
        { 
            
handler->PSendSysMessage("|CFF7BBEF7[Custom Rates]|r: You have set %s's loot rate to %u."handler->GetNameLink(player).c_str(), uRate); 
            
ChatHandler(player->GetSession()).PSendSysMessage("|CFF7BBEF7[Custom Rates]|r: %s has set your loot rate to %u."handler->GetNameLink().c_str(), uRate); 
        } 

        return 
true
    } 
}; 
void Add_SC_Custom_Rates() 

    new 
add_del_rates(); 
    new 
custom_rate_commands(); 
}  
فایل sql
کد PHP:
insert  into `command`(`name`,`security`,`help`) values ('rate xp',0,'Syntax: .rate xp $value\r\nSets your XP multiplier to $value. If no parameter is provided, it will show your current XP rate.'),('rate loot',0,'Syntax: .rate loot $value\r\nSets your loot multiplier to $value. If no parameter is provided, it will show your current loot rate. A $value of 0 means you won\'t be able to loot anything.');  
رو تو database world 
و این 2 تا sql رو
کد PHP:
DROP TABLE IF EXISTS `character_loot_rate`; CREATE TABLE `character_loot_rate` ( 
  `
guidint(10unsigned NOT NULL
  `
loot_rateint(10unsigned NOT NULL DEFAULT '1'
  
PRIMARY KEY (`guid`) 
ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Player Loot Rate System';  
کد PHP:
DROP TABLE IF EXISTS `character_xp_rate`; CREATE TABLE `character_xp_rate` ( 
  `
guidint(10UNSIGNED NOT NULL
  `
xp_rateint(10UNSIGNED NOT NULL DEFAULT '1'
  
PRIMARY KEY (`guid`) 
ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Player XP Rate System';  
را درون database characters بریزید
برای vip کردن کامند rate xp و rate loot 

به database world/command و کامند این 2 تا رو پیدا کنید security رو 1 کنید

منبع : Irancore