Skip to content

Commit

Permalink
feat(Core/Module): improve mod-donate-ips
Browse files Browse the repository at this point in the history
* Rename to normal config option
* Add logger for module
* Add `ips_shop` table
* Add support TaskScheduler
  • Loading branch information
Winfidonarleyan committed Jul 6, 2020
1 parent 28589ae commit 848d8b0
Show file tree
Hide file tree
Showing 3 changed files with 164 additions and 67 deletions.
9 changes: 7 additions & 2 deletions modules/mod-donate-ips/conf/DonateIPS.conf.dist
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,12 @@
[worldserver]

#
# IPS.Donate.Enable
# IPSShop.Enable
# Описание: Систему доната wowka.su
# Значение: 0 - выключить (по умолчанию)
# 1 - включить
#

IPS.Donate.Enable = 1
IPSShop.Enable = 0

#Logger.modules.ips = 6,Modules
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
-- ----------------------------
-- Table structure for ips_shop
-- ----------------------------
DROP TABLE IF EXISTS `ips_shop`;
CREATE TABLE `ips_shop` (
`ID` int(10) NOT NULL DEFAULT 1,
`Type` int(10) NOT NULL DEFAULT 0,
`Value` int(10) NOT NULL,
PRIMARY KEY (`ID`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;

-- ----------------------------
-- Records of ips_shop
-- ----------------------------
INSERT INTO `ips_shop` VALUES (9, 0, 37711);
INSERT INTO `ips_shop` VALUES (10, 1, 0);
206 changes: 141 additions & 65 deletions modules/mod-donate-ips/src/DonateIPS_SC.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,21 +21,28 @@
#include "Chat.h"
#include "Player.h"
#include "ScriptedGossip.h"
#include "TaskScheduler.h"
#include <vector>

enum DonateIPSVariant
enum IPSShopType
{
DONATE_IPS_DONATE_MONETA = 9,
DONATE_IPS_RENAME
IPS_SHOP_TYPE_ITEM, // Item id
IPS_SHOP_TYPE_CHAR_RENAME // Character rename
};

struct IPSShop
{
uint32 ShopID;
IPSShopType Type;
uint32 Value;
};

struct DonateIPSStruct
{
std::string Nickname;
DonateIPSVariant Variant;
uint32 ItemID;
uint32 ItemCount;
uint32 ID;
std::string CharName;
IPSShop* ShopID;
uint32 Value;
};

class DonateIPS
Expand All @@ -49,7 +56,7 @@ class DonateIPS

void LoadDonate()
{
if (!CONF_GET_BOOL("IPS.Donate.Enable"))
if (!CONF_GET_BOOL("IPSShop.Enable"))
return;

_store.clear();
Expand All @@ -61,49 +68,78 @@ class DonateIPS
do
{
Field* fields = result->Fetch();
uint32 ID = fields[0].GetUInt32();
std::string PlayerName = fields[1].GetString();
DonateIPSVariant Variant = static_cast<DonateIPSVariant>(fields[2].GetUInt32());
uint32 Count = fields[3].GetUInt32();
uint32 id = fields[0].GetUInt32();
std::string playerName = fields[1].GetString();
uint32 shopID = fields[2].GetUInt32();
uint32 value = fields[3].GetUInt32();

if (!normalizePlayerName(PlayerName))
if (!normalizePlayerName(playerName))
{
sLog->outErrorDb("> DonateIPS: Некорректное имя персонажа (%s)", PlayerName.c_str());
LOG_ERROR("modules.ips", "> DonateIPS: Некорректное имя персонажа (%s)", playerName.c_str());
continue;
}

uint64 PlayerGuid = sObjectMgr->GetPlayerGUIDByName(PlayerName);
if (!PlayerGuid)
uint64 playerGuid = sObjectMgr->GetPlayerGUIDByName(playerName);
if (!playerGuid)
{
sLog->outErrorDb("> DonateIPS: Неверное имя персонажа (%s)", PlayerName.c_str());
LOG_ERROR("modules.ips", "> DonateIPS: Неверное имя персонажа (%s)", playerName.c_str());
continue;
}

if (!sObjectMgr->GetPlayerNameByGUID(PlayerGuid, PlayerName))
if (!sObjectMgr->GetPlayerNameByGUID(playerGuid, playerName))
{
sLog->outErrorDb("> DonateIPS: Ошибка получения данных о персонаже (%s - %u)", PlayerName.c_str(), PlayerGuid);
LOG_ERROR("modules.ips", "> DonateIPS: Ошибка получения данных о персонаже (%s)", playerName.c_str());
continue;
}

auto _shopID = GetShop(shopID);
if (!_shopID)
continue;

DonateIPSStruct _data;
_data.Nickname = PlayerName;
_data.Variant = Variant;
_data.ID = ID;
_data.ID = id;
_data.CharName = playerName;
_data.ShopID = _shopID;
_data.Value = value;

_store.push_back(_data);

} while (result->NextRow());
}

void LoadShopStore()
{
if (!CONF_GET_BOOL("IPSShop.Enable"))
return;

_store.clear();

QueryResult result = CharacterDatabase.PQuery("SELECT `ID`, `Type`, `Value` FROM `ips_shop` ORDER BY `ID`");
if (!result)
return;

do
{
Field* fields = result->Fetch();

IPSShop _data;
_data.ShopID = fields[0].GetUInt32();
_data.Type = static_cast<IPSShopType>(fields[1].GetUInt32());
_data.Value = fields[2].GetUInt32();

switch (Variant)
if (_data.Type == IPSShopType::IPS_SHOP_TYPE_ITEM)
{
case DONATE_IPS_DONATE_MONETA:
_data.ItemID = 37711;
_data.ItemCount = Count;
break;
case DONATE_IPS_RENAME:
break;
default:
sLog->outErrorDb("> DonateIPS: Неизвестный тип доната (%u)", static_cast<uint32>(Variant));
continue;
ItemTemplate const* itemTemplate = sObjectMgr->GetItemTemplate(_data.Value);
if (!itemTemplate)
{
LOG_ERROR("sql.sql", "> IPS Shop: Предмета под номером %u не существует. Пропуск", _data.Value);
continue;
}
}
else if (_data.Type != IPSShopType::IPS_SHOP_TYPE_ITEM && _data.Value)
LOG_ERROR("sql.sql", "> IPS Shop: Шоп айди (%u) не является предметом, для него не нужно указывать количество. Установлено 0", _data.ShopID);

_store.push_back(_data);
_shopStore.insert(std::make_pair(_data.ShopID, _data));

} while (result->NextRow());
}
Expand All @@ -115,35 +151,64 @@ class DonateIPS
for (auto const& itr : _store)
SendRewardForPlayer(&itr);
}

void SendRewardForPlayer(const DonateIPSStruct* _data)
private:
void SendRewardForPlayer(const DonateIPSStruct* ipsData)
{
std::string ThanksText = "Спасибо за покупку!";
std::string ThanksSubject = "Донат магазин";
auto shopID = ipsData->ShopID;
if (!shopID)
LOG_FATAL("modules.ips", "> DonateIPS: невозможно найти данные шоп айди для номера (%u)", ipsData->ID);

if (_data->Variant == DONATE_IPS_DONATE_MONETA)
switch (shopID->Type)
{
// Add mail item
CharacterDatabase.PExecute("INSERT INTO `mail_external` (PlayerName, Subject, ItemID, ItemCount, Message, CreatureEntry) VALUES ('%s', '%s', %u, %u, '%s', 37688)",
_data->Nickname.c_str(), ThanksSubject.c_str(), _data->ItemID, _data->ItemCount, ThanksText.c_str());
}
else if (_data->Variant == DONATE_IPS_RENAME)
{
uint64 targetGuid = sObjectMgr->GetPlayerGUIDByName(_data->Nickname);
if (!targetGuid)
return;

PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_ADD_AT_LOGIN_FLAG);
stmt->setUInt16(0, uint16(AT_LOGIN_RENAME));
stmt->setUInt32(1, GUID_LOPART(targetGuid));
CharacterDatabase.Execute(stmt);
case IPSShopType::IPS_SHOP_TYPE_ITEM:
SendRewardItem(ipsData->CharName, shopID->Value, ipsData->Value);
break;
case IPSShopType::IPS_SHOP_TYPE_CHAR_RENAME:
SendRewardRename(ipsData->CharName);
break;
default:
LOG_FATAL("modules.ips", "> DonateIPS: Неверый тип шоп айди (%u)", static_cast<uint32>(shopID->Type));
return;
}

CharacterDatabase.PExecute("UPDATE `shop_purchase` SET `flag` = 1 WHERE `id` = %u", _data->ID);
CharacterDatabase.PExecute("UPDATE `shop_purchase` SET `flag` = 1 WHERE `id` = %u", ipsData->ID);
}

void SendRewardItem(std::string charName, uint32 itemID, uint32 itemCount)
{
// Add mail item
CharacterDatabase.PExecute("INSERT INTO `mail_external` (PlayerName, Subject, ItemID, ItemCount, Message, CreatureEntry) VALUES ('%s', '%s', %u, %u, '%s', 37688)",
charName.c_str(), thanksSubject.c_str(), itemID, itemCount, thanksText.c_str());
}

void SendRewardRename(std::string charName)
{
uint64 targetGuid = sObjectMgr->GetPlayerGUIDByName(charName);
if (!targetGuid)
return;

PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_ADD_AT_LOGIN_FLAG);
stmt->setUInt16(0, uint16(AT_LOGIN_RENAME));
stmt->setUInt32(1, GUID_LOPART(targetGuid));
CharacterDatabase.Execute(stmt);
}

IPSShop* GetShop(uint32 shopID)
{
auto const& itr = _shopStore.find(shopID);
if (itr != _shopStore.end())
return &itr->second;

LOG_FATAL("modules.ips", "> DonateIPS: невозможно найти данные для шоп айди (%u)", shopID);

return nullptr;
}

private:
std::vector<DonateIPSStruct> _store;
std::unordered_map<uint32 /*shop id*/, IPSShop> _shopStore;

std::string const thanksSubject = "Донат магазин";
std::string const thanksText = "Спасибо за покупку!";
};

#define sDonateIPS DonateIPS::instance()
Expand All @@ -155,25 +220,36 @@ class DonateIPS_World : public WorldScript

void OnAfterConfigLoad(bool /*reload*/) override
{
sGameConfig->AddBoolConfig("IPS.Donate.Enable");
sGameConfig->AddBoolConfig("IPSShop.Enable");
}

void OnUpdate(uint32 Diff) override
void OnStartup() override
{
if (!CONF_GET_BOOL("IPS.Donate.Enable"))
if (!CONF_GET_BOOL("IPSShop.Enable"))
return;

if (CheckTimeInterval < Diff)

sDonateIPS->LoadShopStore();

scheduler.Schedule(15s, [this](TaskContext context)
{
LOG_TRACE("modules.ips", "> DonateIPS: SendDonate");

sDonateIPS->SendDonate();
CheckTimeInterval = TimeInterval;
}
else
CheckTimeInterval -= Diff;

context.Repeat();
});
}

void OnUpdate(uint32 diff) override
{
if (!CONF_GET_BOOL("IPSShop.Enable"))
return;

scheduler.Update(diff);
}

private:
uint32 TimeInterval = 15 * IN_MILLISECONDS;
uint32 CheckTimeInterval = TimeInterval;
TaskScheduler scheduler;
};

// Group all custom scripts
Expand Down

0 comments on commit 848d8b0

Please sign in to comment.