diff --git a/modules/game_blessing/blessing.html b/modules/game_blessing/blessing.html
new file mode 100644
index 0000000000..688a6b3e18
--- /dev/null
+++ b/modules/game_blessing/blessing.html
@@ -0,0 +1,97 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/modules/game_blessing/blessing.lua b/modules/game_blessing/blessing.lua
new file mode 100644
index 0000000000..788d18250a
--- /dev/null
+++ b/modules/game_blessing/blessing.lua
@@ -0,0 +1,136 @@
+BlessingController = Controller:new()
+
+function BlessingController:onInit()
+end
+
+function BlessingController:onTerminate()
+ -- BlessingController:findWidget("#main"):destroy()
+end
+
+function BlessingController:onGameStart()
+ g_ui.importStyle("style.otui")
+ BlessingController:loadHtml('blessing.html', g_ui.getRootWidget())
+
+ BlessingController:registerEvents(g_game, {
+ onUpdateBlessDialog = onUpdateBlessDialog
+ })
+ BlessingController.ui:hide()
+end
+
+function BlessingController:onGameEnd()
+ if BlessingController.ui:isVisible() then
+ BlessingController.ui:hide()
+ end
+end
+
+function BlessingController:close()
+ hide()
+end
+
+function BlessingController:showHistory()
+ if BlessingController.ui.blessingHistory:isVisible() then
+ setBlessing()
+ else
+ setHistory()
+ end
+end
+
+function setHistory()
+ local ui = BlessingController.ui
+ ui.test:hide()
+ ui.promotionStatus2:hide()
+ ui.promotionStatus:hide()
+ ui.blessingHistory:show()
+ ui.historyButton:setText("Back")
+end
+
+function setBlessing()
+ local ui = BlessingController.ui
+ ui.test:show()
+ ui.promotionStatus2:show()
+ ui.promotionStatus:show()
+ ui.blessingHistory:hide()
+ ui.historyButton:setText("History")
+end
+
+function toggle()
+ if not BlessingController.ui then
+ return
+ end
+
+ if BlessingController.ui:isVisible() then
+ return hide()
+ end
+ show()
+end
+
+function hide()
+ if not BlessingController.ui then
+ return
+ end
+ BlessingController.ui:hide()
+end
+
+function show()
+ if not BlessingController.ui then
+ return
+ end
+ g_game.requestBless()
+ BlessingController.ui:show()
+ BlessingController.ui:raise()
+ BlessingController.ui:focus()
+ setBlessing()
+end
+
+function onUpdateBlessDialog(data)
+ BlessingController.ui.test:destroyChildren()
+
+ for i, entry in ipairs(data.blesses) do
+ local label = g_ui.createWidget("blessingTEST", BlessingController.ui.test)
+ local totalCount = entry.playerBlessCount + entry.store
+ label.text:setText(entry.playerBlessCount .. " (" .. entry.store .. ")")
+ if totalCount >= 1 then
+ label.enabled:setImageSource("images/" .. i .. "_on")
+ end
+ end
+
+ if (data.promotion ~= 0) then
+ BlessingController.ui.promotionStatus2.premium_only:setOn(false)
+ BlessingController.ui.promotionStatus2.rank:setColoredText(
+ "Your character is promoted and your account has Premium\nstatus. As a result, your XP loss is reduced by {30%, #f75f5f}.")
+ else
+ BlessingController.ui.promotionStatus2.rank:setColoredText(
+ "Your character is promoted and your account has Premium\nstatus. As a result, your XP loss is reduced by {0%, #f75f5f}.")
+ BlessingController.ui.promotionStatus2.premium_only:setOn(true)
+ end
+
+ BlessingController.ui.promotionStatus.fightRules:setColoredText(
+ "- Depending on the fair fight rules, you will lose between {" .. data.pvpMinXpLoss .. ", #f75f5f} and {" ..
+ data.pvpMaxXpLoss .. "%, #f75f5f} less XP and skill points \nupon your next PvP death.")
+
+ BlessingController.ui.promotionStatus.expLoss:setColoredText(
+ "- You will lose {" .. data.pveExpLoss .. "%, #f75f5f}% less XP and skill points upon your next PvE death.")
+
+ BlessingController.ui.promotionStatus.containerLoss:setColoredText(
+ "- There is a {" .. data.equipPvpLoss ..
+ "%, #f75f5f} chance that you will lose your equipped container on your next death.")
+
+ BlessingController.ui.promotionStatus.equipmentLoss:setColoredText(
+ "- There is a {" .. data.equipPveLoss .. "%, #f75f5f} chance that you will lose items upon your next death.")
+
+ BlessingController.ui.blessingHistory:getChildByIndex(1):destroyChildren()
+ local row2 = g_ui.createWidget("historyData", BlessingController.ui.blessingHistory:getChildByIndex(1))
+ row2:setBackgroundColor("#363636")
+ row2.rank:setText("date")
+ row2.name:setText("Event")
+ row2.rank:setColor("#c0c0c0")
+ row2.name:setColor("#c0c0c0")
+
+ for index, entry in ipairs(data.logs) do
+ local row = g_ui.createWidget("historyData", BlessingController.ui.blessingHistory:getChildByIndex(1))
+ local date = os.date("%Y-%m-%d, %H:%M:%S", entry.timestamp)
+ row:setBackgroundColor(index % 2 == 0 and "#ffffff12" or "#00000012")
+ row.rank:setText(date)
+ row.name:setText(entry.historyMessage)
+ end
+end
diff --git a/modules/game_blessing/blessing.otmod b/modules/game_blessing/blessing.otmod
new file mode 100644
index 0000000000..a5b55cbeef
--- /dev/null
+++ b/modules/game_blessing/blessing.otmod
@@ -0,0 +1,9 @@
+Module
+ name: game_blessing
+ description: game_blessing
+ author: game_blessing
+ website: game_blessing
+ scripts: [ blessing.lua ]
+ sandboxed: true
+ @onLoad: BlessingController:init()
+ @onUnload: BlessingController:terminate()
\ No newline at end of file
diff --git a/modules/game_blessing/images/1.png b/modules/game_blessing/images/1.png
new file mode 100644
index 0000000000..5e65bf2648
Binary files /dev/null and b/modules/game_blessing/images/1.png differ
diff --git a/modules/game_blessing/images/1_on.png b/modules/game_blessing/images/1_on.png
new file mode 100644
index 0000000000..6bba7a551e
Binary files /dev/null and b/modules/game_blessing/images/1_on.png differ
diff --git a/modules/game_blessing/images/2.png b/modules/game_blessing/images/2.png
new file mode 100644
index 0000000000..2fe31822cf
Binary files /dev/null and b/modules/game_blessing/images/2.png differ
diff --git a/modules/game_blessing/images/2_on.png b/modules/game_blessing/images/2_on.png
new file mode 100644
index 0000000000..6b46a4623e
Binary files /dev/null and b/modules/game_blessing/images/2_on.png differ
diff --git a/modules/game_blessing/images/3.png b/modules/game_blessing/images/3.png
new file mode 100644
index 0000000000..5163bf7f60
Binary files /dev/null and b/modules/game_blessing/images/3.png differ
diff --git a/modules/game_blessing/images/3_on.png b/modules/game_blessing/images/3_on.png
new file mode 100644
index 0000000000..c5fc6e5e53
Binary files /dev/null and b/modules/game_blessing/images/3_on.png differ
diff --git a/modules/game_blessing/images/4.png b/modules/game_blessing/images/4.png
new file mode 100644
index 0000000000..ac0c7d30cc
Binary files /dev/null and b/modules/game_blessing/images/4.png differ
diff --git a/modules/game_blessing/images/4_on.png b/modules/game_blessing/images/4_on.png
new file mode 100644
index 0000000000..f5de21c2c1
Binary files /dev/null and b/modules/game_blessing/images/4_on.png differ
diff --git a/modules/game_blessing/images/5.png b/modules/game_blessing/images/5.png
new file mode 100644
index 0000000000..a08dc9eb91
Binary files /dev/null and b/modules/game_blessing/images/5.png differ
diff --git a/modules/game_blessing/images/5_on.png b/modules/game_blessing/images/5_on.png
new file mode 100644
index 0000000000..88b9018144
Binary files /dev/null and b/modules/game_blessing/images/5_on.png differ
diff --git a/modules/game_blessing/images/6.png b/modules/game_blessing/images/6.png
new file mode 100644
index 0000000000..fad669126b
Binary files /dev/null and b/modules/game_blessing/images/6.png differ
diff --git a/modules/game_blessing/images/6_on.png b/modules/game_blessing/images/6_on.png
new file mode 100644
index 0000000000..34c4f07651
Binary files /dev/null and b/modules/game_blessing/images/6_on.png differ
diff --git a/modules/game_blessing/images/7.png b/modules/game_blessing/images/7.png
new file mode 100644
index 0000000000..37ebb68538
Binary files /dev/null and b/modules/game_blessing/images/7.png differ
diff --git a/modules/game_blessing/images/7_on.png b/modules/game_blessing/images/7_on.png
new file mode 100644
index 0000000000..2b3e7ab681
Binary files /dev/null and b/modules/game_blessing/images/7_on.png differ
diff --git a/modules/game_blessing/images/8.png b/modules/game_blessing/images/8.png
new file mode 100644
index 0000000000..a3de881dc9
Binary files /dev/null and b/modules/game_blessing/images/8.png differ
diff --git a/modules/game_blessing/images/8_on.png b/modules/game_blessing/images/8_on.png
new file mode 100644
index 0000000000..069505c3dc
Binary files /dev/null and b/modules/game_blessing/images/8_on.png differ
diff --git a/modules/game_blessing/images/blessingContainer.png b/modules/game_blessing/images/blessingContainer.png
new file mode 100644
index 0000000000..2199237070
Binary files /dev/null and b/modules/game_blessing/images/blessingContainer.png differ
diff --git a/modules/game_blessing/images/getpremium.png b/modules/game_blessing/images/getpremium.png
new file mode 100644
index 0000000000..14566df045
Binary files /dev/null and b/modules/game_blessing/images/getpremium.png differ
diff --git a/modules/game_blessing/style.otui b/modules/game_blessing/style.otui
new file mode 100644
index 0000000000..b4cc028234
--- /dev/null
+++ b/modules/game_blessing/style.otui
@@ -0,0 +1,74 @@
+historyData < UIWidget
+ height: 16
+ Label
+ anchors.top: parent.top
+ anchors.left: parent.left
+ anchors.bottom : parent.bottom
+ id: rank
+ width: 150
+ !text: tr('1')
+ text-align: center
+ color: #dfdfdfcf
+ phantom: false
+ margin-left: 4
+
+ VerticalSeparator
+ id: separator
+ anchors.top: parent.top
+ anchors.left: parent.left
+ anchors.bottom: parent.bottom
+ margin-top: -1
+ margin-bottom: -1
+ margin-left: 155
+
+ Label
+ anchors.top: parent.top
+ anchors.left: prev.right
+ anchors.bottom : parent.bottom
+ id: name
+ width: 216
+ !text: tr('-')
+ text-align: left
+ color: #ff0000cf
+ phantom: true
+ margin-left: 5
+
+blessingTEST < UIWidget
+ background-color: alpha
+ height: 62
+ width: 70
+ focusable: true
+ text-align: left
+ UIWidget
+ id: enabled
+ anchors.left: parent.left
+ anchors.verticalCenter: parent.verticalCenter
+ margin-top: -10
+ margin-left: 3
+ Label
+ id: text
+ !text: tr('loooooong text')
+ text-align: center
+ margin-top: 5
+ width: 65
+ anchors.left: prev.left
+ anchors.top: prev.bottom
+
+ image-source: /game_blessing/images/blessingContainer
+ focusable: false
+
+BlessingButton < UIButton
+ size: 128 37
+ image-source: /game_blessing/images/getpremium
+ image-clip: 0 0 128 37
+ image-border: 3
+ @onClick: modules.game_shop.toggle()
+
+ $pressed:
+ image-clip: 0 37 128 37
+ $!on:
+ image-clip: 0 74 128 37
+ $disabled:
+ color: #dfdfdf88
+ opacity: 0.8
+
diff --git a/modules/game_interface/interface.otmod b/modules/game_interface/interface.otmod
index 4a5ef51aae..2f3cdb1698 100644
--- a/modules/game_interface/interface.otmod
+++ b/modules/game_interface/interface.otmod
@@ -42,8 +42,8 @@ Module
- game_shop
- game_screenshot
- game_highscore
+ - game_blessing
- game_store
- game_quickloot
-
@onLoad: init()
@onUnload: terminate()
diff --git a/modules/game_inventory/inventory.otui b/modules/game_inventory/inventory.otui
index 3d87c9c130..9718a44264 100644
--- a/modules/game_inventory/inventory.otui
+++ b/modules/game_inventory/inventory.otui
@@ -68,7 +68,7 @@ PhantomMiniWindow
anchors.left: changeSize.right
margin-left: 3
size: 12 12
-
+ @onClick: modules.game_blessing.toggle()
$pressed !disabled:
image-clip: 12 0 12 12
@@ -556,7 +556,7 @@ PhantomMiniWindow
anchors.left: changeSize.left
margin-top: 3
size: 12 12
-
+ @onClick: modules.game_blessing.toggle()
$pressed !disabled:
image-clip: 12 0 12 12
diff --git a/src/client/game.cpp b/src/client/game.cpp
index c26a3e3766..ccf0e20c1f 100644
--- a/src/client/game.cpp
+++ b/src/client/game.cpp
@@ -1726,6 +1726,13 @@ void Game::imbuementDurations(bool isOpen)
m_protocolGame->sendImbuementDurations(isOpen);
}
+void Game::requestBless()
+{
+ if (!canPerformGameAction())
+ return;
+
+ m_protocolGame->sendRequestBless();
+
void Game::requestQuickLootBlackWhiteList(uint8_t filter, uint16_t size, const std::vector& listedItems)
{
m_denyBotCall = false;
@@ -1733,9 +1740,10 @@ void Game::requestQuickLootBlackWhiteList(uint8_t filter, uint16_t size, const s
m_denyBotCall = true;
}
-void Game::openContainerQuickLoot(uint8_t action, uint8_t category, const Position& pos, uint16_t itemId, uint8_t stackpos, bool useMainAsFallback)
+void Game::openContainerQuickLoot(uint8_t action, uint8_t category, const Position& pos, uint16_t itemId, uint8_t stackpos, bool use]AsFallback)
{
m_denyBotCall = false;
m_protocolGame->openContainerQuickLoot(action, category, pos, itemId, stackpos, useMainAsFallback);
m_denyBotCall = true;
+
}
diff --git a/src/client/game.h b/src/client/game.h
index 73929c2511..cc00d11732 100644
--- a/src/client/game.h
+++ b/src/client/game.h
@@ -53,6 +53,36 @@ struct UnjustifiedPoints
uint8_t skullTime;
};
+struct BlessData
+{
+ uint16_t blessBitwise;
+ uint8_t playerBlessCount;
+ uint8_t store;
+};
+
+struct LogData
+{
+ uint32_t timestamp;
+ uint8_t colorMessage;
+ std::string_view historyMessage;
+};
+
+struct BlessDialogData
+{
+ uint8_t totalBless;
+ std::vector blesses;
+ uint8_t premium;
+ uint8_t promotion;
+ uint8_t pvpMinXpLoss;
+ uint8_t pvpMaxXpLoss;
+ uint8_t pveExpLoss;
+ uint8_t equipPvpLoss;
+ uint8_t equipPveLoss;
+ uint8_t skull;
+ uint8_t aol;
+ std::vector logs;
+};
+
using Vip = std::tuple;
struct StoreCategory
@@ -483,6 +513,7 @@ class Game
const std::vector>& highscores, uint32_t entriesTs);
void imbuementDurations(bool isOpen = false);
+ void requestBless();
void requestQuickLootBlackWhiteList(uint8_t filter, uint16_t size, const std::vector& listedItems);
void openContainerQuickLoot(uint8_t action, uint8_t category, const Position& pos, uint16_t itemId, uint8_t stackpos, bool useMainAsFallback);
diff --git a/src/client/luafunctions.cpp b/src/client/luafunctions.cpp
index 196f08f44d..aa51091128 100644
--- a/src/client/luafunctions.cpp
+++ b/src/client/luafunctions.cpp
@@ -362,6 +362,7 @@ void Client::registerLuaFunctions()
g_lua.bindSingletonFunction("g_game", "stashWithdraw", &Game::stashWithdraw, &g_game);
g_lua.bindSingletonFunction("g_game", "requestHighscore", &Game::requestHighscore, &g_game);
g_lua.bindSingletonFunction("g_game", "imbuementDurations", &Game::imbuementDurations, &g_game);
+ g_lua.bindSingletonFunction("g_game", "requestBless", &Game::requestBless, &g_game);
g_lua.bindSingletonFunction("g_game", "requestQuickLootBlackWhiteList", &Game::requestQuickLootBlackWhiteList, &g_game);
g_lua.bindSingletonFunction("g_game", "openContainerQuickLoot", &Game::openContainerQuickLoot, &g_game);
diff --git a/src/client/luavaluecasts_client.cpp b/src/client/luavaluecasts_client.cpp
index 72a0d81b2a..8493811e0b 100644
--- a/src/client/luavaluecasts_client.cpp
+++ b/src/client/luavaluecasts_client.cpp
@@ -289,6 +289,66 @@ bool luavalue_cast(int index, UnjustifiedPoints& unjustifiedPoints)
return true;
}
+int push_luavalue(const BlessData& bless) {
+ g_lua.createTable(0, 3);
+ g_lua.pushInteger(bless.blessBitwise);
+ g_lua.setField("blessBitwise");
+ g_lua.pushInteger(bless.playerBlessCount);
+ g_lua.setField("playerBlessCount");
+ g_lua.pushInteger(bless.store);
+ g_lua.setField("store");
+ return 1;
+}
+
+int push_luavalue(const LogData& log) {
+ g_lua.createTable(0, 3);
+ g_lua.pushInteger(log.timestamp);
+ g_lua.setField("timestamp");
+ g_lua.pushInteger(log.colorMessage);
+ g_lua.setField("colorMessage");
+ g_lua.pushString(log.historyMessage);
+ g_lua.setField("historyMessage");
+ return 1;
+}
+
+int push_luavalue(const BlessDialogData& data) {
+ g_lua.createTable(0, 11);
+ g_lua.pushInteger(data.totalBless);
+ g_lua.setField("totalBless");
+
+ g_lua.createTable(data.blesses.size(), 0);
+ for (size_t i = 0; i < data.blesses.size(); ++i) {
+ push_luavalue(data.blesses[i]);
+ g_lua.rawSeti(i + 1);
+ }
+ g_lua.setField("blesses");
+
+ g_lua.pushInteger(data.premium);
+ g_lua.setField("premium");
+ g_lua.pushInteger(data.promotion);
+ g_lua.setField("promotion");
+ g_lua.pushInteger(data.pvpMinXpLoss);
+ g_lua.setField("pvpMinXpLoss");
+ g_lua.pushInteger(data.pvpMaxXpLoss);
+ g_lua.setField("pvpMaxXpLoss");
+ g_lua.pushInteger(data.pveExpLoss);
+ g_lua.setField("pveExpLoss");
+ g_lua.pushInteger(data.equipPvpLoss);
+ g_lua.setField("equipPvpLoss");
+ g_lua.pushInteger(data.equipPveLoss);
+ g_lua.setField("equipPveLoss");
+ g_lua.pushInteger(data.skull);
+ g_lua.setField("skull");
+ g_lua.pushInteger(data.aol);
+ g_lua.setField("aol");
+
+ g_lua.createTable(data.logs.size(), 0);
+ for (size_t i = 0; i < data.logs.size(); ++i) {
+ push_luavalue(data.logs[i]);
+ g_lua.rawSeti(i + 1);
+ }
+ g_lua.setField("logs");
+
int push_luavalue(const StoreCategory& category) {
g_lua.createTable(0, 5);
g_lua.pushString(category.name);
diff --git a/src/client/luavaluecasts_client.h b/src/client/luavaluecasts_client.h
index c5f99b3300..368988d81c 100644
--- a/src/client/luavaluecasts_client.h
+++ b/src/client/luavaluecasts_client.h
@@ -49,6 +49,10 @@ bool luavalue_cast(int index, UnjustifiedPoints& unjustifiedPoints);
int push_luavalue(const Imbuement& i);
int push_luavalue(const ImbuementTrackerItem& i);
+// Bless
+int push_luavalue(const BlessData& bless);
+int push_luavalue(const LogData& log);
+int push_luavalue(const BlessDialogData& data);
int push_luavalue(const StoreCategory& category);
int push_luavalue(const SubOffer& subOffer);
int push_luavalue(const StoreOffer& offer);
diff --git a/src/client/protocolcodes.h b/src/client/protocolcodes.h
index 6fceffe808..0f90cd8a58 100644
--- a/src/client/protocolcodes.h
+++ b/src/client/protocolcodes.h
@@ -298,6 +298,7 @@ namespace Proto
ClientRefreshContainer = 202,
ClientBrowseField = 203,
ClientSeekInContainer = 204,
+ ClientRequestBless = 207,
ClientRequestOutfit = 210,
ClientChangeOutfit = 211,
ClientMount = 212, // 870
diff --git a/src/client/protocolgame.h b/src/client/protocolgame.h
index 4cc427834b..b81996bca8 100644
--- a/src/client/protocolgame.h
+++ b/src/client/protocolgame.h
@@ -97,6 +97,7 @@ class ProtocolGame : public Protocol
void sendExcludeFromOwnChannel(const std::string_view name);
void sendCancelAttackAndFollow();
void sendRefreshContainer(int containerId);
+ void sendRequestBless();
void sendRequestOutfit();
void sendChangeOutfit(const Outfit& outfit);
void sendTyping(bool typing);
diff --git a/src/client/protocolgameparse.cpp b/src/client/protocolgameparse.cpp
index 0274eb49a5..11a7fb90b3 100644
--- a/src/client/protocolgameparse.cpp
+++ b/src/client/protocolgameparse.cpp
@@ -3703,36 +3703,37 @@ void ProtocolGame::parseGameNews(const InputMessagePtr& msg)
void ProtocolGame::parseBlessDialog(const InputMessagePtr& msg)
{
- // parse bless amount
- const uint8_t totalBless = msg->getU8(); // total bless
-
- // parse each bless
- for (auto i = 0; i < totalBless; ++i) {
- msg->getU16(); // bless bit wise
- msg->getU8(); // player bless count
- msg->getU8(); // store?
- }
-
- // parse general info
- msg->getU8(); // premium
- msg->getU8(); // promotion
- msg->getU8(); // pvp min xp loss
- msg->getU8(); // pvp max xp loss
- msg->getU8(); // pve exp loss
- msg->getU8(); // equip pvp loss
- msg->getU8(); // equip pve loss
- msg->getU8(); // skull
- msg->getU8(); // aol
-
- // parse log
- const uint8_t logCount = msg->getU8(); // log count
+ BlessDialogData data;
+ data.totalBless = msg->getU8();
+
+ for (auto i = 0; i < data.totalBless; ++i) {
+ BlessData bless;
+ bless.blessBitwise = msg->getU16();
+ bless.playerBlessCount = msg->getU8();
+ bless.store = msg->getU8();
+ data.blesses.emplace_back(bless);
+ }
+
+ data.premium = msg->getU8();
+ data.promotion = msg->getU8();
+ data.pvpMinXpLoss = msg->getU8();
+ data.pvpMaxXpLoss = msg->getU8();
+ data.pveExpLoss = msg->getU8();
+ data.equipPvpLoss = msg->getU8();
+ data.equipPveLoss = msg->getU8();
+ data.skull = msg->getU8();
+ data.aol = msg->getU8();
+
+ const uint8_t logCount = msg->getU8();
for (auto i = 0; i < logCount; ++i) {
- msg->getU32(); // timestamp
- msg->getU8(); // color message (0 = white loss, 1 = red)
- msg->getString(); // history message
+ LogData log;
+ log.timestamp = msg->getU32();
+ log.colorMessage = msg->getU8();
+ log.historyMessage = msg->getString();
+ data.logs.emplace_back(log);
}
- // TODO: implement bless dialog usage
+ g_lua.callGlobalField("g_game", "onUpdateBlessDialog", data);
}
void ProtocolGame::parseRestingAreaState(const InputMessagePtr& msg)
diff --git a/src/client/protocolgamesend.cpp b/src/client/protocolgamesend.cpp
index f165cd71ad..eb3219f542 100644
--- a/src/client/protocolgamesend.cpp
+++ b/src/client/protocolgamesend.cpp
@@ -725,6 +725,13 @@ void ProtocolGame::sendRefreshContainer(int containerId)
send(msg);
}
+void ProtocolGame::sendRequestBless()
+{
+ const auto& msg = std::make_shared();
+ msg->addU8(Proto::ClientRequestBless);
+ send(msg);
+}
+
void ProtocolGame::sendRequestOutfit()
{
const auto& msg = std::make_shared();