mirror of
https://github.com/araxiaonline/TrinityCore.git
synced 2026-06-13 03:32:28 -04:00
Lots of small changes to server stuff
This commit is contained in:
@@ -69,7 +69,7 @@ The Event Bus is a ZeroMQ-based real-time event system that publishes game event
|
||||
|
||||
### Quick Test
|
||||
```bash
|
||||
cd /opt/trinitycore/TrinityCore/src/araxiaonline/tools
|
||||
cd /opt/trinitycore/araxia-content-tools/scripts/zeromq
|
||||
source .venv/bin/activate
|
||||
python zmq_subscriber.py
|
||||
```
|
||||
@@ -103,7 +103,7 @@ Scarletseer can trigger events for the ZeroMQ event bus:
|
||||
- **Loot events**: item looted
|
||||
- **Encounter events**: start, wipe, end (requires dungeon/raid)
|
||||
|
||||
Monitor events with: `python /opt/trinitycore/TrinityCore/src/araxiaonline/tools/zmq_subscriber.py`
|
||||
Monitor events with: `python /opt/trinitycore/araxia-content-tools/scripts/zeromq/zmq_subscriber.py`
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -148,10 +148,35 @@ Araxia.EventBus.EnableGuildEvents = 1
|
||||
# When disabled, uses HTTP transport.
|
||||
# Default: 1 (stdio mode)
|
||||
#
|
||||
# Araxia.MCP.Enable
|
||||
# Enable the embedded MCP server for AI assistant integration.
|
||||
# Default: 0 (disabled)
|
||||
#
|
||||
# Araxia.MCP.Port
|
||||
# Port for the MCP HTTP server.
|
||||
# Default: 8765
|
||||
#
|
||||
# Araxia.MCP.AuthToken
|
||||
# Bearer token for authentication. Leave empty for no auth (development only!).
|
||||
# Default: "" (no auth)
|
||||
#
|
||||
# Araxia.MCP.AllowRemote
|
||||
# Allow connections from non-localhost addresses.
|
||||
# Default: 0 (localhost only)
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
Araxia.MCP.Enable = 1
|
||||
Araxia.MCP.StdioMode = 1
|
||||
Araxia.MCP.Enable = 1
|
||||
Araxia.MCP.Port = 8765
|
||||
Araxia.MCP.AuthToken = ""
|
||||
Araxia.MCP.AllowRemote = 1
|
||||
|
||||
# MCP Player Settings
|
||||
Araxia.MCP.Player.MaxSessions = 10
|
||||
Araxia.MCP.Player.DefaultAccountId = 0
|
||||
Araxia.MCP.Player.SessionTimeout = 3600
|
||||
|
||||
###############################################################################
|
||||
#
|
||||
@@ -166,3 +191,4 @@ Araxia.MCP.StdioMode = 1
|
||||
|
||||
Araxia.Eluna.EnableSharedData = 1
|
||||
|
||||
Logger.araxia.eventbus=1,Console Server
|
||||
@@ -29,25 +29,27 @@ AraxiaEventBusConfig* AraxiaEventBusConfig::Instance()
|
||||
|
||||
void AraxiaEventBusConfig::LoadConfig()
|
||||
{
|
||||
_publishEndpoint = sConfigMgr->GetStringDefault("Araxia.EventBus.PublishEndpoint"sv, "tcp://*:5555"sv);
|
||||
_subscribeEndpoint = sConfigMgr->GetStringDefault("Araxia.EventBus.SubscribeEndpoint"sv, "tcp://127.0.0.1:5556"sv);
|
||||
_enableSpawnEvents = sConfigMgr->GetBoolDefault("Araxia.EventBus.EnableSpawnEvents"sv, true);
|
||||
_enableEncounterEvents = sConfigMgr->GetBoolDefault("Araxia.EventBus.EnableEncounterEvents"sv, true);
|
||||
_enablePlayerEvents = sConfigMgr->GetBoolDefault("Araxia.EventBus.EnablePlayerEvents"sv, true);
|
||||
_enableCombatEvents = sConfigMgr->GetBoolDefault("Araxia.EventBus.EnableCombatEvents"sv, true);
|
||||
_enableLootEvents = sConfigMgr->GetBoolDefault("Araxia.EventBus.EnableLootEvents"sv, true);
|
||||
_enableQuestEvents = sConfigMgr->GetBoolDefault("Araxia.EventBus.EnableQuestEvents"sv, true);
|
||||
_enableZoneEvents = sConfigMgr->GetBoolDefault("Araxia.EventBus.EnableZoneEvents"sv, true);
|
||||
_enablePartyEvents = sConfigMgr->GetBoolDefault("Araxia.EventBus.EnablePartyEvents"sv, true);
|
||||
_enableItemEvents = sConfigMgr->GetBoolDefault("Araxia.EventBus.EnableItemEvents"sv, true);
|
||||
_enableSpellEvents = sConfigMgr->GetBoolDefault("Araxia.EventBus.EnableSpellEvents"sv, false); // High volume
|
||||
_enableLevelEvents = sConfigMgr->GetBoolDefault("Araxia.EventBus.EnableLevelEvents"sv, true);
|
||||
_enableChatEvents = sConfigMgr->GetBoolDefault("Araxia.EventBus.EnableChatEvents"sv, true);
|
||||
_enableAchievementEvents = sConfigMgr->GetBoolDefault("Araxia.EventBus.EnableAchievementEvents"sv, true);
|
||||
_enableAuctionEvents = sConfigMgr->GetBoolDefault("Araxia.EventBus.EnableAuctionEvents"sv, true);
|
||||
_enableMailEvents = sConfigMgr->GetBoolDefault("Araxia.EventBus.EnableMailEvents"sv, true);
|
||||
_enableTradeEvents = sConfigMgr->GetBoolDefault("Araxia.EventBus.EnableTradeEvents"sv, true);
|
||||
_enableGuildEvents = sConfigMgr->GetBoolDefault("Araxia.EventBus.EnableGuildEvents"sv, true);
|
||||
// Use quiet=true to suppress "Missing name" warnings since we have sensible defaults
|
||||
// Config can be set in worldserver.conf or worldserver.conf.d/*.conf
|
||||
_publishEndpoint = sConfigMgr->GetStringDefault("Araxia.EventBus.PublishEndpoint"sv, "tcp://*:5555"sv, true);
|
||||
_subscribeEndpoint = sConfigMgr->GetStringDefault("Araxia.EventBus.SubscribeEndpoint"sv, "tcp://127.0.0.1:5556"sv, true);
|
||||
_enableSpawnEvents = sConfigMgr->GetBoolDefault("Araxia.EventBus.EnableSpawnEvents"sv, true, true);
|
||||
_enableEncounterEvents = sConfigMgr->GetBoolDefault("Araxia.EventBus.EnableEncounterEvents"sv, true, true);
|
||||
_enablePlayerEvents = sConfigMgr->GetBoolDefault("Araxia.EventBus.EnablePlayerEvents"sv, true, true);
|
||||
_enableCombatEvents = sConfigMgr->GetBoolDefault("Araxia.EventBus.EnableCombatEvents"sv, true, true);
|
||||
_enableLootEvents = sConfigMgr->GetBoolDefault("Araxia.EventBus.EnableLootEvents"sv, true, true);
|
||||
_enableQuestEvents = sConfigMgr->GetBoolDefault("Araxia.EventBus.EnableQuestEvents"sv, true, true);
|
||||
_enableZoneEvents = sConfigMgr->GetBoolDefault("Araxia.EventBus.EnableZoneEvents"sv, true, true);
|
||||
_enablePartyEvents = sConfigMgr->GetBoolDefault("Araxia.EventBus.EnablePartyEvents"sv, true, true);
|
||||
_enableItemEvents = sConfigMgr->GetBoolDefault("Araxia.EventBus.EnableItemEvents"sv, true, true);
|
||||
_enableSpellEvents = sConfigMgr->GetBoolDefault("Araxia.EventBus.EnableSpellEvents"sv, false, true); // High volume - disabled by default
|
||||
_enableLevelEvents = sConfigMgr->GetBoolDefault("Araxia.EventBus.EnableLevelEvents"sv, true, true);
|
||||
_enableChatEvents = sConfigMgr->GetBoolDefault("Araxia.EventBus.EnableChatEvents"sv, true, true);
|
||||
_enableAchievementEvents = sConfigMgr->GetBoolDefault("Araxia.EventBus.EnableAchievementEvents"sv, true, true);
|
||||
_enableAuctionEvents = sConfigMgr->GetBoolDefault("Araxia.EventBus.EnableAuctionEvents"sv, true, true);
|
||||
_enableMailEvents = sConfigMgr->GetBoolDefault("Araxia.EventBus.EnableMailEvents"sv, true, true);
|
||||
_enableTradeEvents = sConfigMgr->GetBoolDefault("Araxia.EventBus.EnableTradeEvents"sv, true, true);
|
||||
_enableGuildEvents = sConfigMgr->GetBoolDefault("Araxia.EventBus.EnableGuildEvents"sv, true, true);
|
||||
|
||||
TC_LOG_INFO("araxia.eventbus", "EventBus config loaded:");
|
||||
TC_LOG_INFO("araxia.eventbus", " PublishEndpoint: {}", _publishEndpoint);
|
||||
|
||||
@@ -881,7 +881,7 @@ bool MCPPlayerManager::CastSpell(uint32 sessionId, uint32 spellId, ObjectGuid ta
|
||||
return player->CastSpell(target, spellId, false) == SPELL_CAST_OK;
|
||||
}
|
||||
|
||||
bool MCPPlayerManager::InteractWith(uint32 sessionId, ObjectGuid targetGuid)
|
||||
bool MCPPlayerManager::InteractWith(uint32 sessionId, ObjectGuid /*targetGuid*/)
|
||||
{
|
||||
Player* player = GetPlayer(sessionId);
|
||||
if (!player)
|
||||
@@ -942,7 +942,7 @@ std::string MCPPlayerManager::ExecuteCommand(uint32 sessionId, const std::string
|
||||
// Perception
|
||||
// ============================================================================
|
||||
|
||||
std::vector<ObjectGuid> MCPPlayerManager::GetNearbyEntities(uint32 sessionId, float range, uint32 typeMask) const
|
||||
std::vector<ObjectGuid> MCPPlayerManager::GetNearbyEntities(uint32 sessionId, float /*range*/, uint32 /*typeMask*/) const
|
||||
{
|
||||
std::vector<ObjectGuid> result;
|
||||
|
||||
@@ -993,7 +993,7 @@ void MCPPlayerManager::CapturePacket(uint32 sessionId, WorldPacket const& packet
|
||||
session->outboundPackets.pop();
|
||||
}
|
||||
|
||||
void MCPPlayerManager::QueueInboundPacket(uint32 sessionId, uint16 opcode, const std::vector<uint8>& data)
|
||||
void MCPPlayerManager::QueueInboundPacket(uint32 /*sessionId*/, uint16 /*opcode*/, const std::vector<uint8>& /*data*/)
|
||||
{
|
||||
// TODO: Implement when we need to inject packets into the session
|
||||
TC_LOG_DEBUG("araxia.mcp", "[MCPPlayerManager] QueueInboundPacket not yet implemented");
|
||||
|
||||
@@ -51,7 +51,12 @@
|
||||
#include "ObjectMgr.h"
|
||||
#include "SmartScriptMgr.h"
|
||||
#include "Chat.h"
|
||||
#include "AraxiaEventBus.h"
|
||||
#include "AuctionHouseMgr.h"
|
||||
#include "Item.h"
|
||||
#include <sstream>
|
||||
#include <algorithm>
|
||||
#include <cwctype>
|
||||
|
||||
namespace Araxia
|
||||
{
|
||||
@@ -719,7 +724,193 @@ void RegisterServerTools()
|
||||
}
|
||||
);
|
||||
|
||||
TC_LOG_INFO("araxia.mcp", "[MCP] Server tools registered (server_info, player_list, gm_command, reload_scripts, log_search, shared_data_*)");
|
||||
// publish_test_event - Publish a test event to the event bus for UI testing
|
||||
// This tool allows AI assistants to test event-driven UIs like the Auction House page
|
||||
// without needing actual in-game activity.
|
||||
sMCPServer->RegisterTool(
|
||||
"publish_test_event",
|
||||
"Publish a test event to the ZeroMQ event bus. Useful for testing event-driven UIs.",
|
||||
{
|
||||
{"type", "object"},
|
||||
{"properties", {
|
||||
{"topic", {{"description", "Event topic (e.g., 'world.auction.create', 'world.player.login')"}, {"type", "string"}}},
|
||||
{"payload", {{"description", "JSON payload object for the event"}, {"type", "object"}}}
|
||||
}},
|
||||
{"required", {"topic", "payload"}}
|
||||
},
|
||||
[](const json& params) -> json {
|
||||
std::string topic = params.value("topic", "");
|
||||
|
||||
if (topic.empty())
|
||||
return {{"success", false}, {"error", "Topic is required"}};
|
||||
|
||||
if (!params.contains("payload"))
|
||||
return {{"success", false}, {"error", "Payload is required"}};
|
||||
|
||||
// Get payload as string
|
||||
std::string payloadStr = params["payload"].dump();
|
||||
|
||||
// Publish to event bus
|
||||
sAraxiaEventBus->Publish(topic, payloadStr);
|
||||
|
||||
TC_LOG_DEBUG("araxia.mcp", "[MCP] Published test event: {} with payload: {}", topic, payloadStr);
|
||||
|
||||
return {
|
||||
{"success", true},
|
||||
{"topic", topic},
|
||||
{"payload", params["payload"]},
|
||||
{"message", "Event published to event bus"}
|
||||
};
|
||||
}
|
||||
);
|
||||
|
||||
// auction_search - Search the auction house using the same bucket system the client uses.
|
||||
// The server stores auctions in "buckets" indexed by item, with pre-computed FullName
|
||||
// arrays for each locale. We search the bucket FullName to match client behavior.
|
||||
// AHBot items are stored in memory, not in item_instance table, so we must query
|
||||
// the server directly rather than the database.
|
||||
sMCPServer->RegisterTool(
|
||||
"auction_search",
|
||||
"Search the auction house using the server's native bucket search (same as game client).",
|
||||
{
|
||||
{"type", "object"},
|
||||
{"properties", {
|
||||
{"name", {{"description", "Item name to search for (partial match, case-insensitive)"}, {"type", "string"}}},
|
||||
{"quality", {{"description", "Minimum quality (0=Poor, 1=Common, 2=Uncommon, 3=Rare, 4=Epic, 5=Legendary)"}, {"type", "integer"}}},
|
||||
{"faction", {{"description", "Faction: 'alliance', 'horde', 'neutral', or 'all' (default)"}, {"type", "string"}}},
|
||||
{"limit", {{"description", "Max results to return (default 50)"}, {"type", "integer"}}}
|
||||
}}
|
||||
},
|
||||
[](const json& params) -> json {
|
||||
std::string nameFilter = params.value("name", "");
|
||||
int qualityFilter = params.value("quality", -1);
|
||||
std::string factionFilter = params.value("faction", "all");
|
||||
int limit = params.value("limit", 50);
|
||||
|
||||
// Convert name filter to wide string for searching bucket FullName
|
||||
// The server uses wide strings for localized names
|
||||
std::wstring wideNameFilter;
|
||||
if (!nameFilter.empty())
|
||||
{
|
||||
// Convert to lowercase wide string for case-insensitive matching
|
||||
for (char c : nameFilter)
|
||||
wideNameFilter += std::towlower(static_cast<wchar_t>(c));
|
||||
}
|
||||
|
||||
json results = json::array();
|
||||
int total = 0;
|
||||
|
||||
// Helper lambda to search an auction house using bucket data
|
||||
auto searchAuctionHouse = [&](AuctionHouseObject* ah, const std::string& faction) {
|
||||
if (!ah) return;
|
||||
|
||||
for (auto itr = ah->GetAuctionsBegin(); itr != ah->GetAuctionsEnd(); ++itr)
|
||||
{
|
||||
AuctionPosting& auction = itr->second;
|
||||
|
||||
// Get bucket data for proper name searching (same as client)
|
||||
if (!auction.Bucket) continue;
|
||||
AuctionsBucketData* bucket = auction.Bucket;
|
||||
|
||||
// Get item info from the first item
|
||||
if (auction.Items.empty()) continue;
|
||||
Item* item = auction.Items[0];
|
||||
if (!item) continue;
|
||||
|
||||
ItemTemplate const* itemTemplate = item->GetTemplate();
|
||||
if (!itemTemplate) continue;
|
||||
|
||||
// Quality filter - check bucket's quality mask
|
||||
if (qualityFilter >= 0 && itemTemplate->GetQuality() < qualityFilter)
|
||||
continue;
|
||||
|
||||
// Name filter using bucket's FullName (same as server's BuildListBuckets)
|
||||
if (!wideNameFilter.empty())
|
||||
{
|
||||
// Get the localized full name from the bucket
|
||||
const std::wstring& fullName = bucket->FullName[LOCALE_enUS];
|
||||
|
||||
// Convert to lowercase for case-insensitive search
|
||||
std::wstring lowerFullName;
|
||||
for (wchar_t wc : fullName)
|
||||
lowerFullName += std::towlower(wc);
|
||||
|
||||
// Search for substring match
|
||||
if (lowerFullName.find(wideNameFilter) == std::wstring::npos)
|
||||
continue;
|
||||
}
|
||||
|
||||
total++;
|
||||
|
||||
if ((int)results.size() < limit)
|
||||
{
|
||||
// Calculate time remaining
|
||||
auto now = GameTime::GetSystemTime();
|
||||
auto remaining = std::chrono::duration_cast<std::chrono::seconds>(auction.EndTime - now).count();
|
||||
std::string timeLeft = "Expired";
|
||||
if (remaining > 0)
|
||||
{
|
||||
if (remaining < 1800) timeLeft = "Short";
|
||||
else if (remaining < 7200) timeLeft = "Medium";
|
||||
else if (remaining < 43200) timeLeft = "Long";
|
||||
else timeLeft = "Very Long";
|
||||
}
|
||||
|
||||
// Convert wide string name back to UTF-8 for JSON
|
||||
std::string itemName;
|
||||
for (wchar_t wc : bucket->FullName[LOCALE_enUS])
|
||||
{
|
||||
if (wc < 128)
|
||||
itemName += static_cast<char>(wc);
|
||||
else
|
||||
itemName += '?'; // Non-ASCII placeholder
|
||||
}
|
||||
|
||||
// Fallback to template name if bucket name is empty
|
||||
if (itemName.empty())
|
||||
itemName = itemTemplate->GetName(LOCALE_enUS);
|
||||
|
||||
// Get item stats from bucket data
|
||||
// RequiredLevel and ItemLevel are stored in the bucket for efficiency
|
||||
uint8 requiredLevel = bucket->RequiredLevel;
|
||||
uint16 itemLevel = bucket->Key.ItemLevel;
|
||||
|
||||
results.push_back({
|
||||
{"auctionId", auction.Id},
|
||||
{"itemId", itemTemplate->GetId()},
|
||||
{"itemName", itemName},
|
||||
{"itemQuality", itemTemplate->GetQuality()},
|
||||
{"itemLevel", itemLevel},
|
||||
{"requiredLevel", requiredLevel},
|
||||
{"count", auction.GetTotalItemCount()},
|
||||
{"buyout", auction.BuyoutOrUnitPrice},
|
||||
{"bid", auction.MinBid},
|
||||
{"currentBid", auction.BidAmount},
|
||||
{"timeLeft", timeLeft},
|
||||
{"faction", faction}
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Search appropriate auction houses based on faction filter
|
||||
if (factionFilter == "all" || factionFilter == "alliance")
|
||||
searchAuctionHouse(sAuctionMgr->GetAuctionsById(2), "alliance");
|
||||
if (factionFilter == "all" || factionFilter == "horde")
|
||||
searchAuctionHouse(sAuctionMgr->GetAuctionsById(6), "horde");
|
||||
if (factionFilter == "all" || factionFilter == "neutral")
|
||||
searchAuctionHouse(sAuctionMgr->GetAuctionsById(7), "neutral");
|
||||
|
||||
return {
|
||||
{"success", true},
|
||||
{"total", total},
|
||||
{"count", results.size()},
|
||||
{"auctions", results}
|
||||
};
|
||||
}
|
||||
);
|
||||
|
||||
TC_LOG_INFO("araxia.mcp", "[MCP] Server tools registered (server_info, player_list, gm_command, reload_scripts, log_search, shared_data_*, publish_test_event, auction_search)");
|
||||
}
|
||||
|
||||
} // namespace Araxia
|
||||
|
||||
@@ -1,69 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
ZeroMQ Event Bus Subscriber - Test Script
|
||||
|
||||
Connects to the worldserver's ZMQ publisher and prints all received events.
|
||||
Use this to verify spawn/encounter/player events are being published.
|
||||
|
||||
Usage:
|
||||
python3 zmq_subscriber.py [endpoint] [topic_filter]
|
||||
|
||||
Examples:
|
||||
python3 zmq_subscriber.py # All events on default endpoint
|
||||
python3 zmq_subscriber.py tcp://localhost:5555 world.spawn
|
||||
python3 zmq_subscriber.py tcp://localhost:5555 dungeon.
|
||||
"""
|
||||
|
||||
import sys
|
||||
import json
|
||||
import zmq
|
||||
from datetime import datetime
|
||||
|
||||
def main():
|
||||
endpoint = sys.argv[1] if len(sys.argv) > 1 else "tcp://localhost:5555"
|
||||
topic_filter = sys.argv[2] if len(sys.argv) > 2 else ""
|
||||
|
||||
context = zmq.Context()
|
||||
socket = context.socket(zmq.SUB)
|
||||
|
||||
print(f"Connecting to {endpoint}...")
|
||||
socket.connect(endpoint)
|
||||
|
||||
# Subscribe to topic filter (empty string = all topics)
|
||||
socket.setsockopt_string(zmq.SUBSCRIBE, topic_filter)
|
||||
print(f"Subscribed to topics: '{topic_filter}*'")
|
||||
print("Waiting for events... (Ctrl+C to quit)\n")
|
||||
|
||||
try:
|
||||
while True:
|
||||
message = socket.recv_string()
|
||||
|
||||
# Parse topic and payload (format: "topic {json}")
|
||||
space_idx = message.find(' ')
|
||||
if space_idx > 0:
|
||||
topic = message[:space_idx]
|
||||
payload = message[space_idx + 1:]
|
||||
|
||||
try:
|
||||
data = json.loads(payload)
|
||||
ts = datetime.fromtimestamp(data.get('ts', 0) / 1000)
|
||||
|
||||
print(f"[{ts.strftime('%H:%M:%S.%f')[:-3]}] {topic}")
|
||||
print(f" Context: map={data.get('context', {}).get('map_id')}, "
|
||||
f"instance={data.get('context', {}).get('instance_id')}, "
|
||||
f"type={data.get('context', {}).get('type')}")
|
||||
print(f" Payload: {json.dumps(data.get('payload', {}), indent=None)}")
|
||||
print()
|
||||
except json.JSONDecodeError:
|
||||
print(f"[RAW] {message}\n")
|
||||
else:
|
||||
print(f"[RAW] {message}\n")
|
||||
|
||||
except KeyboardInterrupt:
|
||||
print("\nShutting down...")
|
||||
finally:
|
||||
socket.close()
|
||||
context.term()
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -1000,6 +1000,8 @@ void AuctionHouseObject::AddAuction(CharacterDatabaseTransaction trans, AuctionP
|
||||
ownerName = owner->GetName();
|
||||
else if (CharacterCacheEntry const* entry = sCharacterCache->GetCharacterCacheByGuid(addedAuction->Owner))
|
||||
ownerName = entry->Name;
|
||||
else if (addedAuction->Owner.GetCounter() == 0)
|
||||
ownerName = "AHBot"; // Auction House Bot auctions have no real owner
|
||||
|
||||
uint32 itemEntry = 0;
|
||||
uint32 itemCount = 0;
|
||||
|
||||
@@ -3882,6 +3882,41 @@ AuctionHouseBot.Class.Key = 1
|
||||
AuctionHouseBot.Class.Misc = 5
|
||||
AuctionHouseBot.Class.Glyph = 3
|
||||
|
||||
#
|
||||
# AuctionHouseBot.Items.Scaling.*
|
||||
# Description: Item level scaling for AHBot items. When enabled, equipment items
|
||||
# posted by AHBot can receive random item level bonuses, allowing
|
||||
# the AH to stock gear suitable for all player progression levels.
|
||||
# Uses the same ItemBonusMgr system as Timewalking/Remix scaling.
|
||||
#
|
||||
# AuctionHouseBot.Items.Scaling.Enabled
|
||||
# Description: Enable item level scaling for AHBot items
|
||||
# Default: 0 - (Disabled, items use base item level)
|
||||
# 1 - (Enabled, items may receive random item level bonuses)
|
||||
#
|
||||
# AuctionHouseBot.Items.Scaling.MinItemLevel
|
||||
# Description: Minimum target item level for scaled items
|
||||
# Default: 0 - (Use item's base level as minimum)
|
||||
#
|
||||
# AuctionHouseBot.Items.Scaling.MaxItemLevel
|
||||
# Description: Maximum target item level for scaled items
|
||||
# Default: 550 - (MoP raid gear level)
|
||||
#
|
||||
# AuctionHouseBot.Items.Scaling.Chance
|
||||
# Description: Percentage chance (0-100) for each item to be scaled
|
||||
# Default: 50 - (50% of eligible items get scaled)
|
||||
#
|
||||
# AuctionHouseBot.Items.Scaling.EquipmentOnly
|
||||
# Description: Only scale equipment (weapons/armor), not consumables/materials
|
||||
# Default: 1 - (Only equipment is scaled)
|
||||
# 0 - (All item types can be scaled)
|
||||
|
||||
AuctionHouseBot.Items.Scaling.Enabled = 1
|
||||
AuctionHouseBot.Items.Scaling.MinItemLevel = 200
|
||||
AuctionHouseBot.Items.Scaling.MaxItemLevel = 550
|
||||
AuctionHouseBot.Items.Scaling.Chance = 75
|
||||
AuctionHouseBot.Items.Scaling.EquipmentOnly = 1
|
||||
|
||||
#
|
||||
###################################################################################################
|
||||
|
||||
@@ -4459,3 +4494,41 @@ Load.Locales = 1
|
||||
|
||||
#
|
||||
###################################################################################################
|
||||
|
||||
###################################################################################################
|
||||
# ELUNA CONFIGURATION
|
||||
###################################################################################################
|
||||
|
||||
# Enable Eluna Lua scripting engine
|
||||
Eluna.Enabled = 1
|
||||
|
||||
# Path to Lua scripts directory
|
||||
Eluna.ScriptPath = "/opt/trinitycore/lua_scripts"
|
||||
|
||||
# Enable unsafe methods
|
||||
Eluna.UseUnsafeMethods = 1
|
||||
|
||||
# Enable deprecated methods for backward compatibility
|
||||
Eluna.UseDeprecatedMethods = 1
|
||||
|
||||
# Enable .reload lua command
|
||||
Eluna.ReloadCommand = 1
|
||||
|
||||
# Minimum account level for .reload lua command (0-3)
|
||||
# 0 = Player, 1 = Moderator, 2 = GameMaster, 3 = Administrator
|
||||
Eluna.ReloadSecurityLevel = 3
|
||||
|
||||
# Enable automatic script reloading on file changes
|
||||
Eluna.ScriptReloader = 0
|
||||
|
||||
# Enable detailed error tracebacks
|
||||
Eluna.TraceBack = 1
|
||||
|
||||
# Only load Eluna on specific maps (comma-separated, empty = all maps)
|
||||
Eluna.OnlyOnMaps =
|
||||
|
||||
# Extra paths for Lua require() function (semicolon-separated)
|
||||
Eluna.RequirePaths =
|
||||
|
||||
# Extra C library paths for Lua require() (semicolon-separated)
|
||||
Eluna.RequireCPaths =
|
||||
|
||||
Reference in New Issue
Block a user