From f2b67ae969d818a26f61af7c135255d2e34ddcfb Mon Sep 17 00:00:00 2001 From: Alex Date: Tue, 9 Feb 2021 00:06:33 -0500 Subject: [PATCH] [Quest API] Add Mob-based data bucket methods to Perl/Lua. (#1237) * Add Mob-based data bucket methods to Perl/Lua. * Update mob.cpp * Update perl_mob.cpp --- zone/data_bucket.cpp | 23 +++++++++ zone/data_bucket.h | 1 + zone/lua_mob.cpp | 51 ++++++++++++++++++- zone/lua_mob.h | 8 +++ zone/mob.cpp | 49 ++++++++++++++++++ zone/mob.h | 6 +++ zone/perl_mob.cpp | 115 +++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 252 insertions(+), 1 deletion(-) diff --git a/zone/data_bucket.cpp b/zone/data_bucket.cpp index b0d45080b..13dccef66 100644 --- a/zone/data_bucket.cpp +++ b/zone/data_bucket.cpp @@ -102,6 +102,29 @@ std::string DataBucket::GetDataExpires(std::string bucket_key) { return std::string(row[0]); } +std::string DataBucket::GetDataRemaining(std::string bucket_key) { + if (DataBucket::GetDataExpires(bucket_key).empty()) { + return "0"; + } + std::string query = fmt::format( + "SELECT (`expires` - UNIX_TIMESTAMP()) AS `remaining` from `data_buckets` WHERE `key` = '{}' AND (`expires` > {} OR `expires` = 0) LIMIT 1", + bucket_key.c_str(), + (long long) std::time(nullptr) + ); + + auto results = database.QueryDatabase(query); + if (!results.Success()) { + return std::string(); + } + + if (results.RowCount() != 1) + return std::string(); + + auto row = results.begin(); + + return std::string(row[0]); +} + /** * Checks for bucket existence by bucket_name key * @param bucket_key diff --git a/zone/data_bucket.h b/zone/data_bucket.h index 88a344637..51d9c643b 100644 --- a/zone/data_bucket.h +++ b/zone/data_bucket.h @@ -15,6 +15,7 @@ public: static bool DeleteData(std::string bucket_key); static std::string GetData(std::string bucket_key); static std::string GetDataExpires(std::string bucket_key); + static std::string GetDataRemaining(std::string bucket_key); private: static uint64 DoesBucketExist(std::string bucket_key); static uint32 ParseStringTimeToInt(std::string time_string); diff --git a/zone/lua_mob.cpp b/zone/lua_mob.cpp index 53d277b12..600851698 100644 --- a/zone/lua_mob.cpp +++ b/zone/lua_mob.cpp @@ -2267,6 +2267,48 @@ void Lua_Mob::CheckNumHitsRemaining(int type, int32 buff_slot, uint16 spell_id) self->CheckNumHitsRemaining((NumHit)type, buff_slot, spell_id); } +void Lua_Mob::DeleteBucket(std::string bucket_name) +{ + Lua_Safe_Call_Void(); + self->DeleteBucket(bucket_name); +} + +std::string Lua_Mob::GetBucket(std::string bucket_name) +{ + Lua_Safe_Call_String(); + return self->GetBucket(bucket_name); +} + +std::string Lua_Mob::GetBucketExpires(std::string bucket_name) +{ + Lua_Safe_Call_String(); + return self->GetBucketExpires(bucket_name); +} + +std::string Lua_Mob::GetBucketKey() +{ + Lua_Safe_Call_String(); + return self->GetBucketKey(); +} + +std::string Lua_Mob::GetBucketRemaining(std::string bucket_name) +{ + Lua_Safe_Call_String(); + return self->GetBucketRemaining(bucket_name); +} + +void Lua_Mob::SetBucket(std::string bucket_name, std::string bucket_value) +{ + Lua_Safe_Call_Void(); + self->SetBucket(bucket_name, bucket_value); +} + +void Lua_Mob::SetBucket(std::string bucket_name, std::string bucket_value, std::string expiration) +{ + Lua_Safe_Call_Void(); + self->SetBucket(bucket_name, bucket_value, expiration); +} + luabind::scope lua_register_mob() { return luabind::class_("Mob") .def(luabind::constructor<>()) @@ -2657,7 +2699,14 @@ luabind::scope lua_register_mob() { .def("TryFinishingBlow", &Lua_Mob::TryFinishingBlow) .def("GetBodyType", &Lua_Mob::GetBodyType) .def("GetOrigBodyType", &Lua_Mob::GetOrigBodyType) - .def("CheckNumHitsRemaining", &Lua_Mob::CheckNumHitsRemaining); + .def("CheckNumHitsRemaining", &Lua_Mob::CheckNumHitsRemaining) + .def("DeleteBucket", (void(Lua_Mob::*)(std::string))&Lua_Mob::DeleteBucket) + .def("GetBucket", (std::string(Lua_Mob::*)(std::string))&Lua_Mob::GetBucket) + .def("GetBucketExpires", (std::string(Lua_Mob::*)(std::string))&Lua_Mob::GetBucketExpires) + .def("GetBucketKey", (std::string(Lua_Mob::*)(void))&Lua_Mob::GetBucketKey) + .def("GetBucketRemaining", (std::string(Lua_Mob::*)(std::string))&Lua_Mob::GetBucketRemaining) + .def("SetBucket", (void(Lua_Mob::*)(std::string,std::string))&Lua_Mob::SetBucket) + .def("SetBucket", (void(Lua_Mob::*)(std::string,std::string,std::string))&Lua_Mob::SetBucket); } luabind::scope lua_register_special_abilities() { diff --git a/zone/lua_mob.h b/zone/lua_mob.h index 426ac01af..d2994f669 100644 --- a/zone/lua_mob.h +++ b/zone/lua_mob.h @@ -425,6 +425,14 @@ public: int GetBodyType(); int GetOrigBodyType(); void CheckNumHitsRemaining(int type, int32 buff_slot, uint16 spell_id); + + void DeleteBucket(std::string bucket_name); + std::string GetBucket(std::string bucket_name); + std::string GetBucketExpires(std::string bucket_name); + std::string GetBucketKey(); + std::string GetBucketRemaining(std::string bucket_name); + void SetBucket(std::string bucket_name, std::string bucket_value); + void SetBucket(std::string bucket_name, std::string bucket_value, std::string expiration); }; #endif diff --git a/zone/mob.cpp b/zone/mob.cpp index 0fde230a8..751d4d445 100644 --- a/zone/mob.cpp +++ b/zone/mob.cpp @@ -20,6 +20,7 @@ #include "../common/string_util.h" #include "../common/misc_functions.h" +#include "data_bucket.h" #include "quest_parser_collection.h" #include "string_ids.h" #include "worldserver.h" @@ -5972,3 +5973,51 @@ void Mob::SetCanOpenDoors(bool can_open) { m_can_open_doors = can_open; } + +void Mob::DeleteBucket(std::string bucket_name) { + std::string full_bucket_name = fmt::format("{}-{}", GetBucketKey(), bucket_name); + DataBucket::DeleteData(full_bucket_name); +} + +std::string Mob::GetBucket(std::string bucket_name) { + std::string full_bucket_name = fmt::format("{}-{}", GetBucketKey(), bucket_name); + std::string bucket_value = DataBucket::GetData(full_bucket_name); + if (!bucket_value.empty()) { + return bucket_value; + } + return std::string(); +} + +std::string Mob::GetBucketExpires(std::string bucket_name) { + std::string full_bucket_name = fmt::format("{}-{}", GetBucketKey(), bucket_name); + std::string bucket_expiration = DataBucket::GetDataExpires(full_bucket_name); + if (!bucket_expiration.empty()) { + return bucket_expiration; + } + return std::string(); +} + +std::string Mob::GetBucketKey() { + if (IsClient()) { + return fmt::format("character-{}", CastToClient()->CharacterID()); + } else if (IsNPC()) { + return fmt::format("npc-{}", GetNPCTypeID()); + } + return std::string(); +} + +std::string Mob::GetBucketRemaining(std::string bucket_name) { + std::string full_bucket_name = fmt::format("{}-{}", GetBucketKey(), bucket_name); + std::string bucket_remaining = DataBucket::GetDataRemaining(full_bucket_name); + if (!bucket_remaining.empty() && atoi(bucket_remaining.c_str()) > 0) { + return bucket_remaining; + } else if (atoi(bucket_remaining.c_str()) == 0) { + return "0"; + } + return std::string(); +} + +void Mob::SetBucket(std::string bucket_name, std::string bucket_value, std::string expiration) { + std::string full_bucket_name = fmt::format("{}-{}", GetBucketKey(), bucket_name); + DataBucket::SetData(full_bucket_name, bucket_value, expiration); +} diff --git a/zone/mob.h b/zone/mob.h index 0f9325fd8..e3fe058d9 100644 --- a/zone/mob.h +++ b/zone/mob.h @@ -1197,6 +1197,12 @@ public: bool CanOpenDoors() const; void SetCanOpenDoors(bool can_open); + void DeleteBucket(std::string bucket_name); + std::string GetBucket(std::string bucket_name); + std::string GetBucketExpires(std::string bucket_name); + std::string GetBucketKey(); + std::string GetBucketRemaining(std::string bucket_name); + void SetBucket(std::string bucket_name, std::string bucket_value, std::string expiration = ""); #ifdef BOTS // Bots HealRotation methods diff --git a/zone/perl_mob.cpp b/zone/perl_mob.cpp index 9d5401311..da875c7d7 100644 --- a/zone/perl_mob.cpp +++ b/zone/perl_mob.cpp @@ -6071,6 +6071,115 @@ XS(XS_Mob_GetRaceName) { XSRETURN(1); } +XS(XS_Mob_DeleteBucket); +XS(XS_Mob_DeleteBucket) { + dXSARGS; + if (items != 2) + Perl_croak(aTHX_ "Usage: Mob::DeleteBucket(THIS, std::string bucket_name)"); + { + Mob* THIS; + std::string bucket_name = (std::string) SvPV_nolen(ST(1)); + VALIDATE_THIS_IS_MOB; + THIS->DeleteBucket(bucket_name); + } + XSRETURN_EMPTY; +} + +XS(XS_Mob_GetBucket); +XS(XS_Mob_GetBucket) { + dXSARGS; + if (items != 2) + Perl_croak(aTHX_ "Usage: Mob::GetBucket(THIS, std::string bucket_name)"); + { + Mob* THIS; + dXSTARG; + std::string bucket_name = (std::string) SvPV_nolen(ST(1)); + std::string bucket_value; + VALIDATE_THIS_IS_MOB; + bucket_value = THIS->GetBucket(bucket_name); + sv_setpv(TARG, bucket_value.c_str()); + XSprePUSH; + PUSHTARG; + } + XSRETURN(1); +} + +XS(XS_Mob_GetBucketExpires); +XS(XS_Mob_GetBucketExpires) { + dXSARGS; + if (items != 2) + Perl_croak(aTHX_ "Usage: Mob::GetBucketExpires(THIS, std::string bucket_name)"); + { + Mob* THIS; + dXSTARG; + std::string bucket_name = (std::string) SvPV_nolen(ST(1)); + std::string bucket_expiration; + VALIDATE_THIS_IS_MOB; + bucket_expiration = THIS->GetBucketExpires(bucket_name); + sv_setpv(TARG, bucket_expiration.c_str()); + XSprePUSH; + PUSHTARG; + } + XSRETURN(1); +} + +XS(XS_Mob_GetBucketKey); +XS(XS_Mob_GetBucketKey) { + dXSARGS; + if (items != 1) + Perl_croak(aTHX_ "Usage: Mob::GetBucketKey(THIS)"); + { + Mob* THIS; + dXSTARG; + std::string bucket_key; + VALIDATE_THIS_IS_MOB; + bucket_key = THIS->GetBucketKey(); + sv_setpv(TARG, bucket_key.c_str()); + XSprePUSH; + PUSHTARG; + } + XSRETURN(1); +} + +XS(XS_Mob_GetBucketRemaining); +XS(XS_Mob_GetBucketRemaining) { + dXSARGS; + if (items != 2) + Perl_croak(aTHX_ "Usage: Mob::GetBucketRemaining(THIS, std::string bucket_name)"); + { + Mob* THIS; + dXSTARG; + std::string bucket_name = (std::string) SvPV_nolen(ST(1)); + std::string bucket_remaining; + VALIDATE_THIS_IS_MOB; + bucket_remaining = THIS->GetBucketRemaining(bucket_name); + sv_setpv(TARG, bucket_remaining.c_str()); + XSprePUSH; + PUSHTARG; + } + XSRETURN(1); +} + +XS(XS_Mob_SetBucket); +XS(XS_Mob_SetBucket) { + dXSARGS; + if (items < 3 || items > 4) + Perl_croak(aTHX_ "Usage: Mob::SetBucket(THIS, std::string bucket_name, std::string bucket_value, [std::string expiration])"); + { + Mob* THIS; + std::string key = (std::string) SvPV_nolen(ST(1)); + std::string value = (std::string) SvPV_nolen(ST(2)); + std::string expiration; + VALIDATE_THIS_IS_MOB; + if (items == 4) + expiration = (std::string) SvPV_nolen(ST(3)); + + THIS->SetBucket(key, value, expiration); + } + XSRETURN_EMPTY; +} + + #ifdef __cplusplus extern "C" #endif @@ -6410,6 +6519,12 @@ XS(boot_Mob) { newXSproto(strcpy(buf, "IsAmnesiad"), XS_Mob_IsAmnesiad, file, "$"); newXSproto(strcpy(buf, "GetMeleeMitigation"), XS_Mob_GetMeleeMitigation, file, "$"); newXSproto(strcpy(buf, "TryMoveAlong"), XS_Mob_TryMoveAlong, file, "$$$;$"); + newXSproto(strcpy(buf, "DeleteBucket"), XS_Mob_DeleteBucket, file, "$$"); + newXSproto(strcpy(buf, "GetBucket"), XS_Mob_GetBucket, file, "$$"); + newXSproto(strcpy(buf, "GetBucketExpires"), XS_Mob_GetBucketExpires, file, "$$"); + newXSproto(strcpy(buf, "GetBucketKey"), XS_Mob_GetBucketKey, file, "$"); + newXSproto(strcpy(buf, "GetBucketRemaining"), XS_Mob_GetBucketRemaining, file, "$$"); + newXSproto(strcpy(buf, "SetBucket"), XS_Mob_SetBucket, file, "$$$;$"); XSRETURN_YES; }