mirror of
https://github.com/EQEmu/Server.git
synced 2026-05-16 18:52:22 +00:00
[Databuckets] Add Account Scoped Databuckets (#4603)
* [Databuckets] Add Account Scoped Databuckets * Add variation * Fix Lua after testing
This commit is contained in:
+49
-1
@@ -402,6 +402,7 @@ Client::~Client() {
|
||||
|
||||
mMovementManager->RemoveClient(this);
|
||||
|
||||
DataBucket::DeleteCachedBuckets(DataBucketLoadType::Account, AccountID());
|
||||
DataBucket::DeleteCachedBuckets(DataBucketLoadType::Client, CharacterID());
|
||||
|
||||
if (RuleB(Bots, Enabled)) {
|
||||
@@ -13172,10 +13173,57 @@ void Client::BroadcastPositionUpdate()
|
||||
|
||||
Group *g = GetGroup();
|
||||
if (g) {
|
||||
for (auto & m : g->members) {
|
||||
for (auto &m: g->members) {
|
||||
if (m && m->IsClient() && m != this) {
|
||||
m->CastToClient()->QueuePacket(&outapp);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::string Client::GetAccountBucket(std::string bucket_name)
|
||||
{
|
||||
DataBucketKey k = {};
|
||||
k.account_id = AccountID();
|
||||
k.key = bucket_name;
|
||||
|
||||
return DataBucket::GetData(k).value;
|
||||
}
|
||||
|
||||
void Client::SetAccountBucket(std::string bucket_name, std::string bucket_value, std::string expiration)
|
||||
{
|
||||
DataBucketKey k = {};
|
||||
k.account_id = AccountID();
|
||||
k.key = bucket_name;
|
||||
k.expires = expiration;
|
||||
k.value = bucket_value;
|
||||
|
||||
DataBucket::SetData(k);
|
||||
}
|
||||
|
||||
void Client::DeleteAccountBucket(std::string bucket_name)
|
||||
{
|
||||
DataBucketKey k = {};
|
||||
k.account_id = AccountID();
|
||||
k.key = bucket_name;
|
||||
|
||||
DataBucket::DeleteData(k);
|
||||
}
|
||||
|
||||
std::string Client::GetAccountBucketExpires(std::string bucket_name)
|
||||
{
|
||||
DataBucketKey k = {};
|
||||
k.account_id = AccountID();
|
||||
k.key = bucket_name;
|
||||
|
||||
return DataBucket::GetDataExpires(k);
|
||||
}
|
||||
|
||||
std::string Client::GetAccountBucketRemaining(std::string bucket_name)
|
||||
{
|
||||
DataBucketKey k = {};
|
||||
k.account_id = AccountID();
|
||||
k.key = bucket_name;
|
||||
|
||||
return DataBucket::GetDataRemaining(k);
|
||||
}
|
||||
|
||||
@@ -1829,6 +1829,13 @@ public:
|
||||
void SendEvolveXPTransferWindow();
|
||||
void SendEvolveTransferResults(const EQ::ItemInstance &inst_from, const EQ::ItemInstance &inst_to, const EQ::ItemInstance &inst_from_new, const EQ::ItemInstance &inst_to_new, const uint32 compatibility, const uint32 max_transfer_level);
|
||||
|
||||
// Account buckets
|
||||
std::string GetAccountBucket(std::string bucket_name);
|
||||
void SetAccountBucket(std::string bucket_name, std::string bucket_value, std::string expiration = "");
|
||||
void DeleteAccountBucket(std::string bucket_name);
|
||||
std::string GetAccountBucketExpires(std::string bucket_name);
|
||||
std::string GetAccountBucketRemaining(std::string bucket_name);
|
||||
|
||||
protected:
|
||||
friend class Mob;
|
||||
void CalcEdibleBonuses(StatBonuses* newbon);
|
||||
|
||||
+37
-12
@@ -16,6 +16,7 @@ void DataBucket::SetData(const std::string &bucket_key, const std::string &bucke
|
||||
.key = bucket_key,
|
||||
.value = bucket_value,
|
||||
.expires = expires_time,
|
||||
.account_id = 0,
|
||||
.character_id = 0,
|
||||
.npc_id = 0,
|
||||
.bot_id = 0
|
||||
@@ -37,6 +38,9 @@ void DataBucket::SetData(const DataBucketKey &k)
|
||||
if (k.character_id > 0) {
|
||||
b.character_id = k.character_id;
|
||||
}
|
||||
else if (k.account_id > 0) {
|
||||
b.account_id = k.account_id;
|
||||
}
|
||||
else if (k.npc_id > 0) {
|
||||
b.npc_id = k.npc_id;
|
||||
}
|
||||
@@ -95,9 +99,10 @@ std::string DataBucket::GetData(const std::string &bucket_key)
|
||||
DataBucketsRepository::DataBuckets DataBucket::GetData(const DataBucketKey &k, bool ignore_misses_cache)
|
||||
{
|
||||
LogDataBuckets(
|
||||
"Getting bucket key [{}] bot_id [{}] character_id [{}] npc_id [{}]",
|
||||
"Getting bucket key [{}] bot_id [{}] account_id [{}] character_id [{}] npc_id [{}]",
|
||||
k.key,
|
||||
k.bot_id,
|
||||
k.account_id,
|
||||
k.character_id,
|
||||
k.npc_id
|
||||
);
|
||||
@@ -151,6 +156,7 @@ DataBucketsRepository::DataBuckets DataBucket::GetData(const DataBucketKey &k, b
|
||||
.key_ = k.key,
|
||||
.value = "",
|
||||
.expires = 0,
|
||||
.account_id = k.account_id,
|
||||
.character_id = k.character_id,
|
||||
.npc_id = k.npc_id,
|
||||
.bot_id = k.bot_id
|
||||
@@ -158,8 +164,9 @@ DataBucketsRepository::DataBuckets DataBucket::GetData(const DataBucketKey &k, b
|
||||
);
|
||||
|
||||
LogDataBuckets(
|
||||
"Key [{}] not found in database, adding to cache as a miss character_id [{}] npc_id [{}] bot_id [{}] cache size before [{}] after [{}]",
|
||||
"Key [{}] not found in database, adding to cache as a miss account_id [{}] character_id [{}] npc_id [{}] bot_id [{}] cache size before [{}] after [{}]",
|
||||
k.key,
|
||||
k.account_id,
|
||||
k.character_id,
|
||||
k.npc_id,
|
||||
k.bot_id,
|
||||
@@ -216,8 +223,6 @@ bool DataBucket::DeleteData(const std::string &bucket_key)
|
||||
// GetDataBuckets bulk loads all data buckets for a mob
|
||||
bool DataBucket::GetDataBuckets(Mob *mob)
|
||||
{
|
||||
DataBucketLoadType::Type t{};
|
||||
|
||||
const uint32 id = mob->GetMobTypeIdentifier();
|
||||
|
||||
if (!id) {
|
||||
@@ -225,14 +230,13 @@ bool DataBucket::GetDataBuckets(Mob *mob)
|
||||
}
|
||||
|
||||
if (mob->IsBot()) {
|
||||
t = DataBucketLoadType::Bot;
|
||||
BulkLoadEntitiesToCache(DataBucketLoadType::Bot, {id});
|
||||
}
|
||||
else if (mob->IsClient()) {
|
||||
t = DataBucketLoadType::Client;
|
||||
BulkLoadEntitiesToCache(DataBucketLoadType::Account, {id});
|
||||
BulkLoadEntitiesToCache(DataBucketLoadType::Client, {id});
|
||||
}
|
||||
|
||||
BulkLoadEntitiesToCache(t, {id});
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -254,9 +258,10 @@ bool DataBucket::DeleteData(const DataBucketKey &k)
|
||||
);
|
||||
|
||||
LogDataBuckets(
|
||||
"Deleting bucket key [{}] bot_id [{}] character_id [{}] npc_id [{}] cache size before [{}] after [{}]",
|
||||
"Deleting bucket key [{}] bot_id [{}] account_id [{}] character_id [{}] npc_id [{}] cache size before [{}] after [{}]",
|
||||
k.key,
|
||||
k.bot_id,
|
||||
k.account_id,
|
||||
k.character_id,
|
||||
k.npc_id,
|
||||
size_before,
|
||||
@@ -277,9 +282,10 @@ bool DataBucket::DeleteData(const DataBucketKey &k)
|
||||
std::string DataBucket::GetDataExpires(const DataBucketKey &k)
|
||||
{
|
||||
LogDataBuckets(
|
||||
"Getting bucket expiration key [{}] bot_id [{}] character_id [{}] npc_id [{}]",
|
||||
"Getting bucket expiration key [{}] bot_id [{}] account_id [{}] character_id [{}] npc_id [{}]",
|
||||
k.key,
|
||||
k.bot_id,
|
||||
k.account_id,
|
||||
k.character_id,
|
||||
k.npc_id
|
||||
);
|
||||
@@ -295,9 +301,10 @@ std::string DataBucket::GetDataExpires(const DataBucketKey &k)
|
||||
std::string DataBucket::GetDataRemaining(const DataBucketKey &k)
|
||||
{
|
||||
LogDataBuckets(
|
||||
"Getting bucket remaining key [{}] bot_id [{}] character_id [{}] npc_id [{}]",
|
||||
"Getting bucket remaining key [{}] bot_id [{}] account_id [{}] character_id [{}] npc_id [{}]",
|
||||
k.key,
|
||||
k.bot_id,
|
||||
k.account_id,
|
||||
k.character_id,
|
||||
k.npc_id
|
||||
);
|
||||
@@ -320,6 +327,13 @@ std::string DataBucket::GetScopedDbFilters(const DataBucketKey &k)
|
||||
query.emplace_back("character_id = 0");
|
||||
}
|
||||
|
||||
if (k.account_id > 0) {
|
||||
query.emplace_back(fmt::format("account_id = {}", k.account_id));
|
||||
}
|
||||
else {
|
||||
query.emplace_back("account_id = 0");
|
||||
}
|
||||
|
||||
if (k.npc_id > 0) {
|
||||
query.emplace_back(fmt::format("npc_id = {}", k.npc_id));
|
||||
}
|
||||
@@ -346,6 +360,7 @@ bool DataBucket::CheckBucketMatch(const DataBucketsRepository::DataBuckets &dbe,
|
||||
return (
|
||||
dbe.key_ == k.key &&
|
||||
dbe.bot_id == k.bot_id &&
|
||||
dbe.account_id == k.account_id &&
|
||||
dbe.character_id == k.character_id &&
|
||||
dbe.npc_id == k.npc_id
|
||||
);
|
||||
@@ -364,6 +379,9 @@ void DataBucket::BulkLoadEntitiesToCache(DataBucketLoadType::Type t, std::vector
|
||||
if (t == DataBucketLoadType::Bot) {
|
||||
has_cache = e.bot_id == ids[0];
|
||||
}
|
||||
else if (t == DataBucketLoadType::Account) {
|
||||
has_cache = e.account_id == ids[0];
|
||||
}
|
||||
else if (t == DataBucketLoadType::Client) {
|
||||
has_cache = e.character_id == ids[0];
|
||||
}
|
||||
@@ -384,6 +402,9 @@ void DataBucket::BulkLoadEntitiesToCache(DataBucketLoadType::Type t, std::vector
|
||||
case DataBucketLoadType::Client:
|
||||
column = "character_id";
|
||||
break;
|
||||
case DataBucketLoadType::Account:
|
||||
column = "account_id";
|
||||
break;
|
||||
default:
|
||||
LogError("Incorrect LoadType [{}]", static_cast<int>(t));
|
||||
break;
|
||||
@@ -442,6 +463,7 @@ void DataBucket::DeleteCachedBuckets(DataBucketLoadType::Type type, uint32 id)
|
||||
[&](DataBucketsRepository::DataBuckets &e) {
|
||||
return (
|
||||
(type == DataBucketLoadType::Bot && e.bot_id == id) ||
|
||||
(type == DataBucketLoadType::Account && e.account_id == id) ||
|
||||
(type == DataBucketLoadType::Client && e.character_id == id)
|
||||
);
|
||||
}
|
||||
@@ -481,6 +503,7 @@ void DataBucket::DeleteFromMissesCache(DataBucketsRepository::DataBuckets e)
|
||||
g_data_bucket_cache.end(),
|
||||
[&](DataBucketsRepository::DataBuckets &ce) {
|
||||
return ce.id == 0 && ce.key_ == e.key_ &&
|
||||
ce.account_id == e.account_id &&
|
||||
ce.character_id == e.character_id &&
|
||||
ce.npc_id == e.npc_id &&
|
||||
ce.bot_id == e.bot_id;
|
||||
@@ -516,6 +539,8 @@ void DataBucket::DeleteFromCache(uint64 id, DataBucketLoadType::Type type)
|
||||
return e.bot_id == id;
|
||||
case DataBucketLoadType::Client:
|
||||
return e.character_id == id;
|
||||
case DataBucketLoadType::Account:
|
||||
return e.account_id == id;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
@@ -539,7 +564,7 @@ void DataBucket::DeleteFromCache(uint64 id, DataBucketLoadType::Type type)
|
||||
// npcs (ids) can be in multiple zones so we can't cache locally to the zone
|
||||
bool DataBucket::CanCache(const DataBucketKey &key)
|
||||
{
|
||||
if (key.character_id > 0 || key.bot_id > 0) {
|
||||
if (key.character_id > 0 || key.account_id > 0 || key.bot_id > 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
+6
-3
@@ -12,20 +12,23 @@ struct DataBucketKey {
|
||||
std::string key;
|
||||
std::string value;
|
||||
std::string expires;
|
||||
int64_t character_id;
|
||||
int64_t npc_id;
|
||||
int64_t bot_id;
|
||||
int64_t account_id = 0;
|
||||
int64_t character_id = 0;
|
||||
int64_t npc_id = 0;
|
||||
int64_t bot_id = 0;
|
||||
};
|
||||
|
||||
namespace DataBucketLoadType {
|
||||
enum Type : uint8 {
|
||||
Bot,
|
||||
Account,
|
||||
Client,
|
||||
MaxType
|
||||
};
|
||||
|
||||
static const std::string Name[Type::MaxType] = {
|
||||
"Bot",
|
||||
"Account",
|
||||
"Client",
|
||||
};
|
||||
}
|
||||
|
||||
@@ -3464,6 +3464,42 @@ void Lua_Client::SetAAEXPPercentage(uint8 percentage)
|
||||
self->SetAAEXPPercentage(percentage);
|
||||
}
|
||||
|
||||
void Lua_Client::SetAccountBucket(std::string bucket_name, std::string bucket_value)
|
||||
{
|
||||
Lua_Safe_Call_Void();
|
||||
self->SetAccountBucket(bucket_name, bucket_value);
|
||||
}
|
||||
|
||||
void Lua_Client::SetAccountBucket(std::string bucket_name, std::string bucket_value, std::string expiration)
|
||||
{
|
||||
Lua_Safe_Call_Void();
|
||||
self->SetAccountBucket(bucket_name, bucket_value, expiration);
|
||||
}
|
||||
|
||||
void Lua_Client::DeleteAccountBucket(std::string bucket_name)
|
||||
{
|
||||
Lua_Safe_Call_Void();
|
||||
self->DeleteAccountBucket(bucket_name);
|
||||
}
|
||||
|
||||
std::string Lua_Client::GetAccountBucket(std::string bucket_name)
|
||||
{
|
||||
Lua_Safe_Call_String();
|
||||
return self->GetAccountBucket(bucket_name);
|
||||
}
|
||||
|
||||
std::string Lua_Client::GetAccountBucketExpires(std::string bucket_name)
|
||||
{
|
||||
Lua_Safe_Call_String();
|
||||
return self->GetAccountBucketExpires(bucket_name);
|
||||
}
|
||||
|
||||
std::string Lua_Client::GetAccountBucketRemaining(std::string bucket_name)
|
||||
{
|
||||
Lua_Safe_Call_String();
|
||||
return self->GetAccountBucketRemaining(bucket_name);
|
||||
}
|
||||
|
||||
luabind::scope lua_register_client() {
|
||||
return luabind::class_<Lua_Client, Lua_Mob>("Client")
|
||||
.def(luabind::constructor<>())
|
||||
@@ -3552,6 +3588,7 @@ luabind::scope lua_register_client() {
|
||||
.def("CreateTaskDynamicZone", &Lua_Client::CreateTaskDynamicZone)
|
||||
.def("DecreaseByID", (bool(Lua_Client::*)(uint32,int))&Lua_Client::DecreaseByID)
|
||||
.def("DescribeSpecialAbilities", (void(Lua_Client::*)(Lua_NPC))&Lua_Client::DescribeSpecialAbilities)
|
||||
.def("DeleteAccountBucket", (void(Lua_Client::*)(std::string))&Lua_Client::DeleteAccountBucket)
|
||||
.def("DeleteBucket", (void(Lua_Client::*)(std::string))&Lua_Client::DeleteBucket)
|
||||
.def("DeleteItemInInventory", (void(Lua_Client::*)(int,int))&Lua_Client::DeleteItemInInventory)
|
||||
.def("DeleteItemInInventory", (void(Lua_Client::*)(int,int,bool))&Lua_Client::DeleteItemInInventory)
|
||||
@@ -3630,6 +3667,9 @@ luabind::scope lua_register_client() {
|
||||
.def("GetBotRequiredLevel", (int(Lua_Client::*)(uint8))&Lua_Client::GetBotRequiredLevel)
|
||||
.def("GetBotSpawnLimit", (int(Lua_Client::*)(void))&Lua_Client::GetBotSpawnLimit)
|
||||
.def("GetBotSpawnLimit", (int(Lua_Client::*)(uint8))&Lua_Client::GetBotSpawnLimit)
|
||||
.def("GetAccountBucket", (std::string(Lua_Client::*)(std::string))&Lua_Client::GetAccountBucket)
|
||||
.def("GetAccountBucketExpires", (std::string(Lua_Client::*)(std::string))&Lua_Client::GetAccountBucketExpires)
|
||||
.def("GetAccountBucketRemaining", (std::string(Lua_Client::*)(std::string))&Lua_Client::GetAccountBucketRemaining)
|
||||
.def("GetBucket", (std::string(Lua_Client::*)(std::string))&Lua_Client::GetBucket)
|
||||
.def("GetBucketExpires", (std::string(Lua_Client::*)(std::string))&Lua_Client::GetBucketExpires)
|
||||
.def("GetBucketRemaining", (std::string(Lua_Client::*)(std::string))&Lua_Client::GetBucketRemaining)
|
||||
@@ -3922,6 +3962,8 @@ luabind::scope lua_register_client() {
|
||||
.def("SetBotRequiredLevel", (void(Lua_Client::*)(int,uint8))&Lua_Client::SetBotRequiredLevel)
|
||||
.def("SetBotSpawnLimit", (void(Lua_Client::*)(int))&Lua_Client::SetBotSpawnLimit)
|
||||
.def("SetBotSpawnLimit", (void(Lua_Client::*)(int,uint8))&Lua_Client::SetBotSpawnLimit)
|
||||
.def("SetAccountBucket", (void(Lua_Client::*)(std::string,std::string))&Lua_Client::SetAccountBucket)
|
||||
.def("SetAccountBucket", (void(Lua_Client::*)(std::string,std::string,std::string))&Lua_Client::SetAccountBucket)
|
||||
.def("SetBucket", (void(Lua_Client::*)(std::string,std::string))&Lua_Client::SetBucket)
|
||||
.def("SetBucket", (void(Lua_Client::*)(std::string,std::string,std::string))&Lua_Client::SetBucket)
|
||||
.def("SetClientMaxLevel", (void(Lua_Client::*)(int))&Lua_Client::SetClientMaxLevel)
|
||||
|
||||
@@ -512,6 +512,14 @@ public:
|
||||
luabind::object GetInventorySlots(lua_State* L);
|
||||
void SetAAEXPPercentage(uint8 percentage);
|
||||
|
||||
// account data buckets
|
||||
void SetAccountBucket(std::string bucket_name, std::string bucket_value);
|
||||
void SetAccountBucket(std::string bucket_name, std::string bucket_value, std::string expiration = "");
|
||||
void DeleteAccountBucket(std::string bucket_name);
|
||||
std::string GetAccountBucket(std::string bucket_name);
|
||||
std::string GetAccountBucketExpires(std::string bucket_name);
|
||||
std::string GetAccountBucketRemaining(std::string bucket_name);
|
||||
|
||||
void ApplySpell(int spell_id);
|
||||
void ApplySpell(int spell_id, int duration);
|
||||
void ApplySpell(int spell_id, int duration, int level);
|
||||
|
||||
@@ -3234,6 +3234,36 @@ void Perl_Client_SetAAEXPPercentage(Client* self, uint8 percentage)
|
||||
self->SetAAEXPPercentage(percentage);
|
||||
}
|
||||
|
||||
void Perl_Client_SetAccountBucket(Client* self, std::string bucket_name, std::string bucket_value)
|
||||
{
|
||||
self->SetAccountBucket(bucket_name, bucket_value);
|
||||
}
|
||||
|
||||
void Perl_Client_SetAccountBucket(Client* self, std::string bucket_name, std::string bucket_value, std::string expiration = "")
|
||||
{
|
||||
self->SetAccountBucket(bucket_name, bucket_value, expiration);
|
||||
}
|
||||
|
||||
void Perl_Client_DeleteAccountBucket(Client* self, std::string bucket_name)
|
||||
{
|
||||
self->DeleteAccountBucket(bucket_name);
|
||||
}
|
||||
|
||||
std::string Perl_Client_GetAccountBucket(Client* self, std::string bucket_name)
|
||||
{
|
||||
return self->GetAccountBucket(bucket_name);
|
||||
}
|
||||
|
||||
std::string Perl_Client_GetAccountBucketExpires(Client* self, std::string bucket_name)
|
||||
{
|
||||
return self->GetAccountBucketExpires(bucket_name);
|
||||
}
|
||||
|
||||
std::string Perl_Client_GetAccountBucketRemaining(Client* self, std::string bucket_name)
|
||||
{
|
||||
return self->GetAccountBucketRemaining(bucket_name);
|
||||
}
|
||||
|
||||
void perl_register_client()
|
||||
{
|
||||
perl::interpreter perl(PERL_GET_THX);
|
||||
@@ -3325,6 +3355,7 @@ void perl_register_client()
|
||||
package.add("CreateTaskDynamicZone", &Perl_Client_CreateTaskDynamicZone);
|
||||
package.add("DecreaseByID", &Perl_Client_DecreaseByID);
|
||||
package.add("DescribeSpecialAbilities", &Perl_Client_DescribeSpecialAbilities);
|
||||
package.add("DeleteAccountBucket", &Perl_Client_DeleteAccountBucket);
|
||||
package.add("DeleteItemInInventory", (void(*)(Client*, int16))&Perl_Client_DeleteItemInInventory);
|
||||
package.add("DeleteItemInInventory", (void(*)(Client*, int16, int16))&Perl_Client_DeleteItemInInventory);
|
||||
package.add("DeleteItemInInventory", (void(*)(Client*, int16, int16, bool))&Perl_Client_DeleteItemInInventory);
|
||||
@@ -3362,6 +3393,9 @@ void perl_register_client()
|
||||
package.add("GetAAPoints", &Perl_Client_GetAAPoints);
|
||||
package.add("GetAFK", &Perl_Client_GetAFK);
|
||||
package.add("GetAccountAge", &Perl_Client_GetAccountAge);
|
||||
package.add("GetAccountBucket", &Perl_Client_GetAccountBucket);
|
||||
package.add("GetAccountBucketExpires", &Perl_Client_GetAccountBucketExpires);
|
||||
package.add("GetGetAccountBucketRemaining", &Perl_Client_GetAccountBucketRemaining);
|
||||
package.add("GetAccountFlag", &Perl_Client_GetAccountFlag);
|
||||
package.add("GetAccountFlags", &Perl_Client_GetAccountFlags);
|
||||
package.add("GetAggroCount", &Perl_Client_GetAggroCount);
|
||||
@@ -3668,6 +3702,8 @@ void perl_register_client()
|
||||
package.add("SetAATitle", (void(*)(Client*, std::string, bool))&Perl_Client_SetAATitle);
|
||||
package.add("SetAFK", &Perl_Client_SetAFK);
|
||||
package.add("SetAccountFlag", &Perl_Client_SetAccountFlag);
|
||||
package.add("SetAccountBucket", (void(*)(Client*, std::string, std::string))&Perl_Client_SetAccountBucket);
|
||||
package.add("SetAccountBucket", (void(*)(Client*, std::string, std::string, std::string))&Perl_Client_SetAccountBucket);
|
||||
package.add("SetAlternateCurrencyValue", &Perl_Client_SetAlternateCurrencyValue);
|
||||
package.add("SetAnon", &Perl_Client_SetAnon);
|
||||
package.add("SetAutoLoginCharacterName", (bool(*)(Client*))&Perl_Client_SetAutoLoginCharacterName);
|
||||
|
||||
Reference in New Issue
Block a user