From 94901112ba6d1d152261402a56756125191b6756 Mon Sep 17 00:00:00 2001 From: Luan Luciano Date: Sun, 7 Jul 2024 21:11:46 -0300 Subject: [PATCH] feat: take screenshot (#2116) --- README.md | 2 +- .../scripts/creaturescripts/player_death.lua | 7 +++++++ .../scripts/actions/rookgaard/rapier_quest.lua | 1 + .../creaturescripts/others/player_death.lua | 7 +++++++ .../creaturescripts/monster/boss_lever_death.lua | 3 +++ src/creatures/players/player.cpp | 14 ++++++++++++++ src/creatures/players/player.hpp | 6 ++++++ src/lua/functions/core/game/lua_enums.cpp | 14 ++++++++++++++ .../creatures/player/player_functions.cpp | 15 +++++++++++++++ .../creatures/player/player_functions.hpp | 4 ++++ src/server/network/protocol/protocolgame.cpp | 11 +++++++++++ src/server/network/protocol/protocolgame.hpp | 1 + src/utils/utils_definitions.hpp | 16 ++++++++++++++++ 13 files changed, 100 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 119850ea7ea..c7cb88e7b32 100644 --- a/README.md +++ b/README.md @@ -77,7 +77,7 @@ Before [creating a pull request](https://github.com/opentibiabr/canary/pulls) pl * our crew (majesty, gpedro, eduardo dantas, foot) * [our contributors](https://github.com/opentibiabr/canary/graphs/contributors) * [fear lucien](https://github.com/FearLucien) -* [cjaker](https://github.com/Eternal-Scripts) +* [cjaker](https://github.com/Cjaker) * [slavidodo](https://github.com/slavidodo) * [mignari and our awesome tools](https://github.com/ottools) * [mattyx14/otxserver](https://github.com/mattyx14/otxserver) and contributors diff --git a/data-canary/scripts/creaturescripts/player_death.lua b/data-canary/scripts/creaturescripts/player_death.lua index 5ac2e70ff99..c30e2e98d99 100644 --- a/data-canary/scripts/creaturescripts/player_death.lua +++ b/data-canary/scripts/creaturescripts/player_death.lua @@ -42,6 +42,12 @@ function playerDeath.onDeath(player, corpse, killer, mostDamageKiller, unjustifi mostDamageName = "field item" end + player:takeScreenshot(byPlayer and SCREENSHOT_TYPE_DEATHPVP or SCREENSHOT_TYPE_DEATHPVE) + + if mostDamageKiller and mostDamageKiller:isPlayer() and killer ~= mostDamageKiller then + mostDamageKiller:takeScreenshot(SCREENSHOT_TYPE_PLAYERKILL) + end + local playerGuid = player:getGuid() db.query( "INSERT INTO `player_deaths` (`player_id`, `time`, `level`, `killed_by`, `is_player`, `mostdamage_by`, `mostdamage_is_player`, `unjustified`, `mostdamage_unjustified`) VALUES (" @@ -83,6 +89,7 @@ function playerDeath.onDeath(player, corpse, killer, mostDamageKiller, unjustifi end if byPlayer == 1 then + killer:takeScreenshot(SCREENSHOT_TYPE_PLAYERKILL) local targetGuild = player:getGuild() targetGuild = targetGuild and targetGuild:getId() or 0 if targetGuild ~= 0 then diff --git a/data-otservbr-global/scripts/actions/rookgaard/rapier_quest.lua b/data-otservbr-global/scripts/actions/rookgaard/rapier_quest.lua index 20e6697d2f7..5d09dcadf86 100644 --- a/data-otservbr-global/scripts/actions/rookgaard/rapier_quest.lua +++ b/data-otservbr-global/scripts/actions/rookgaard/rapier_quest.lua @@ -8,6 +8,7 @@ function rapierQuest.onUse(player, item, fromPosition, target, toPosition, isHot player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You have found a rapier.") player:addItem(rewardId, 1) player:questKV("rapier"):set("completed", true) + player:takeScreenshot(SCREENSHOT_TYPE_TREASUREFOUND) return true end diff --git a/data-otservbr-global/scripts/creaturescripts/others/player_death.lua b/data-otservbr-global/scripts/creaturescripts/others/player_death.lua index b848235ebae..b4756addfee 100644 --- a/data-otservbr-global/scripts/creaturescripts/others/player_death.lua +++ b/data-otservbr-global/scripts/creaturescripts/others/player_death.lua @@ -44,6 +44,12 @@ function playerDeath.onDeath(player, corpse, killer, mostDamageKiller, unjustifi mostDamageName = "field item" end + player:takeScreenshot(byPlayer and SCREENSHOT_TYPE_DEATHPVP or SCREENSHOT_TYPE_DEATHPVE) + + if mostDamageKiller and mostDamageKiller:isPlayer() then + mostDamageKiller:takeScreenshot(SCREENSHOT_TYPE_PLAYERKILL) + end + local playerGuid = player:getGuid() db.query( "INSERT INTO `player_deaths` (`player_id`, `time`, `level`, `killed_by`, `is_player`, `mostdamage_by`, `mostdamage_is_player`, `unjustified`, `mostdamage_unjustified`) VALUES (" @@ -83,6 +89,7 @@ function playerDeath.onDeath(player, corpse, killer, mostDamageKiller, unjustifi end if byPlayer == 1 then + killer:takeScreenshot(SCREENSHOT_TYPE_PLAYERKILL) local targetGuild = player:getGuild() local targetGuildId = targetGuild and targetGuild:getId() or 0 if targetGuildId ~= 0 then diff --git a/data/scripts/creaturescripts/monster/boss_lever_death.lua b/data/scripts/creaturescripts/monster/boss_lever_death.lua index a2c58d1e43b..4e035271623 100644 --- a/data/scripts/creaturescripts/monster/boss_lever_death.lua +++ b/data/scripts/creaturescripts/monster/boss_lever_death.lua @@ -30,6 +30,9 @@ function onBossDeath.onDeath(creature) zn:removePlayers() end, bossLever.timeAfterKill * 1000, zone) end + onDeathForDamagingPlayers(creature, function(creature, player) + player:takeScreenshot(SCREENSHOT_TYPE_BOSSDEFEATED) + end) return true end diff --git a/src/creatures/players/player.cpp b/src/creatures/players/player.cpp index eddffa20ae2..273079873e8 100644 --- a/src/creatures/players/player.cpp +++ b/src/creatures/players/player.cpp @@ -696,6 +696,11 @@ void Player::addSkillAdvance(skills_t skill, uint64_t count) { std::ostringstream ss; ss << "You advanced to " << getSkillName(skill) << " level " << skills[skill].level << '.'; sendTextMessage(MESSAGE_EVENT_ADVANCE, ss.str()); + if (skill == SKILL_LEVEL) { + sendTakeScreenshot(SCREENSHOT_TYPE_LEVELUP); + } else { + sendTakeScreenshot(SCREENSHOT_TYPE_SKILLUP); + } g_creatureEvents().playerAdvance(static_self_cast(), skill, (skills[skill].level - 1), skills[skill].level); @@ -2325,8 +2330,10 @@ void Player::addManaSpent(uint64_t amount) { std::ostringstream ss; ss << "You advanced to magic level " << magLevel << '.'; sendTextMessage(MESSAGE_EVENT_ADVANCE, ss.str()); + sendTakeScreenshot(SCREENSHOT_TYPE_SKILLUP); g_creatureEvents().playerAdvance(static_self_cast(), SKILL_MAGLEVEL, magLevel - 1, magLevel); + sendTakeScreenshot(SCREENSHOT_TYPE_SKILLUP); sendUpdateStats = true; currReqMana = nextReqMana; @@ -2464,6 +2471,7 @@ void Player::addExperience(std::shared_ptr target, uint64_t exp, bool std::ostringstream ss; ss << "You advanced from Level " << prevLevel << " to Level " << level << '.'; sendTextMessage(MESSAGE_EVENT_ADVANCE, ss.str()); + sendTakeScreenshot(SCREENSHOT_TYPE_LEVELUP); } if (nextLevelExp > currLevelExp) { @@ -6010,6 +6018,7 @@ bool Player::addOfflineTrainingTries(skills_t skill, uint64_t tries) { std::ostringstream ss; ss << "You advanced to magic level " << magLevel << '.'; sendTextMessage(MESSAGE_EVENT_ADVANCE, ss.str()); + sendTakeScreenshot(SCREENSHOT_TYPE_SKILLUP); } uint8_t newPercent; @@ -6066,6 +6075,11 @@ bool Player::addOfflineTrainingTries(skills_t skill, uint64_t tries) { std::ostringstream ss; ss << "You advanced to " << getSkillName(skill) << " level " << skills[skill].level << '.'; sendTextMessage(MESSAGE_EVENT_ADVANCE, ss.str()); + if (skill == SKILL_LEVEL) { + sendTakeScreenshot(SCREENSHOT_TYPE_LEVELUP); + } else { + sendTakeScreenshot(SCREENSHOT_TYPE_SKILLUP); + } } uint8_t newPercent; diff --git a/src/creatures/players/player.hpp b/src/creatures/players/player.hpp index 627b640ad93..2c765850f10 100644 --- a/src/creatures/players/player.hpp +++ b/src/creatures/players/player.hpp @@ -1730,6 +1730,12 @@ class Player final : public Creature, public Cylinder, public Bankable { } } + void sendTakeScreenshot(Screenshot_t screenshotType) { + if (client) { + client->sendTakeScreenshot(screenshotType); + } + } + void onThink(uint32_t interval) override; void postAddNotification(std::shared_ptr thing, std::shared_ptr oldParent, int32_t index, CylinderLink_t link = LINK_OWNER) override; diff --git a/src/lua/functions/core/game/lua_enums.cpp b/src/lua/functions/core/game/lua_enums.cpp index 2e3813e0769..d0be72158d6 100644 --- a/src/lua/functions/core/game/lua_enums.cpp +++ b/src/lua/functions/core/game/lua_enums.cpp @@ -214,6 +214,20 @@ void LuaEnums::initOthersEnums(lua_State* L) { registerEnum(L, WEAPON_WAND); registerEnum(L, WEAPON_AMMO); registerEnum(L, WEAPON_MISSILE); + + registerEnum(L, SCREENSHOT_TYPE_NONE); + registerEnum(L, SCREENSHOT_TYPE_ACHIEVEMENT); + registerEnum(L, SCREENSHOT_TYPE_BESTIARYENTRYCOMPLETED); + registerEnum(L, SCREENSHOT_TYPE_BESTIARYENTRYUNLOCKED); + registerEnum(L, SCREENSHOT_TYPE_BOSSDEFEATED); + registerEnum(L, SCREENSHOT_TYPE_DEATHPVE); + registerEnum(L, SCREENSHOT_TYPE_DEATHPVP); + registerEnum(L, SCREENSHOT_TYPE_LEVELUP); + registerEnum(L, SCREENSHOT_TYPE_PLAYERKILLASSIST); + registerEnum(L, SCREENSHOT_TYPE_PLAYERKILL); + registerEnum(L, SCREENSHOT_TYPE_PLAYERATTACKING); + registerEnum(L, SCREENSHOT_TYPE_TREASUREFOUND); + registerEnum(L, SCREENSHOT_TYPE_SKILLUP); } void LuaEnums::initAccountEnums(lua_State* L) { diff --git a/src/lua/functions/creatures/player/player_functions.cpp b/src/lua/functions/creatures/player/player_functions.cpp index 52fd4517f31..609ecbe95e0 100644 --- a/src/lua/functions/creatures/player/player_functions.cpp +++ b/src/lua/functions/creatures/player/player_functions.cpp @@ -4223,6 +4223,7 @@ int PlayerFunctions::luaPlayerAddAchievement(lua_State* L) { achievementId = g_game().getAchievementByName(getString(L, 2)).id; } + player->sendTakeScreenshot(SCREENSHOT_TYPE_ACHIEVEMENT); pushBoolean(L, player->achiev()->add(achievementId, getBoolean(L, 3, true))); return 1; } @@ -4378,3 +4379,17 @@ int PlayerFunctions::luaPlayerCreateTransactionSummary(lua_State* L) { pushBoolean(L, true); return 1; } + +int PlayerFunctions::luaPlayerTakeScreenshot(lua_State* L) { + // player:takeScreenshot(screenshotType) + const auto &player = getUserdataShared(L, 1); + if (!player) { + lua_pushnil(L); + return 1; + } + + auto screenshotType = getNumber(L, 2); + player->sendTakeScreenshot(screenshotType); + pushBoolean(L, true); + return 1; +} diff --git a/src/lua/functions/creatures/player/player_functions.hpp b/src/lua/functions/creatures/player/player_functions.hpp index 281e51ae88f..3912753a1ca 100644 --- a/src/lua/functions/creatures/player/player_functions.hpp +++ b/src/lua/functions/creatures/player/player_functions.hpp @@ -375,6 +375,8 @@ class PlayerFunctions final : LuaScriptInterface { // Store Summary registerMethod(L, "Player", "createTransactionSummary", PlayerFunctions::luaPlayerCreateTransactionSummary); + registerMethod(L, "Player", "takeScreenshot", PlayerFunctions::luaPlayerTakeScreenshot); + GroupFunctions::init(L); GuildFunctions::init(L); MountFunctions::init(L); @@ -737,5 +739,7 @@ class PlayerFunctions final : LuaScriptInterface { static int luaPlayerCreateTransactionSummary(lua_State* L); + static int luaPlayerTakeScreenshot(lua_State* L); + friend class CreatureFunctions; }; diff --git a/src/server/network/protocol/protocolgame.cpp b/src/server/network/protocol/protocolgame.cpp index 18c23fbb1aa..3ac22ac6b77 100644 --- a/src/server/network/protocol/protocolgame.cpp +++ b/src/server/network/protocol/protocolgame.cpp @@ -9156,3 +9156,14 @@ void ProtocolGame::sendHotkeyPreset() { writeToOutputBuffer(msg); } } + +void ProtocolGame::sendTakeScreenshot(Screenshot_t screenshotType) { + if (screenshotType == SCREENSHOT_TYPE_NONE || oldProtocol) { + return; + } + + NetworkMessage msg; + msg.addByte(0x75); + msg.addByte(screenshotType); + writeToOutputBuffer(msg); +} diff --git a/src/server/network/protocol/protocolgame.hpp b/src/server/network/protocol/protocolgame.hpp index 55e9cbfbaea..8e99aa68a54 100644 --- a/src/server/network/protocol/protocolgame.hpp +++ b/src/server/network/protocol/protocolgame.hpp @@ -516,6 +516,7 @@ class ProtocolGame final : public Protocol { void sendDoubleSoundEffect(const Position &pos, SoundEffect_t mainSoundId, SourceEffect_t mainSource, SoundEffect_t secondarySoundId, SourceEffect_t secondarySource); void sendHotkeyPreset(); + void sendTakeScreenshot(Screenshot_t screenshotType); void sendDisableLoginMusic(); uint8_t m_playerDeathTime = 0; diff --git a/src/utils/utils_definitions.hpp b/src/utils/utils_definitions.hpp index 7466c83a8f2..be50fd35b9d 100644 --- a/src/utils/utils_definitions.hpp +++ b/src/utils/utils_definitions.hpp @@ -751,3 +751,19 @@ enum Concoction_t : uint16_t { DeathAmplification = 36741, PhysicalAmplification = 36742, }; + +enum Screenshot_t : uint8_t { + SCREENSHOT_TYPE_NONE = 0, + SCREENSHOT_TYPE_ACHIEVEMENT = 1, + SCREENSHOT_TYPE_BESTIARYENTRYCOMPLETED = 2, + SCREENSHOT_TYPE_BESTIARYENTRYUNLOCKED = 3, + SCREENSHOT_TYPE_BOSSDEFEATED = 4, + SCREENSHOT_TYPE_DEATHPVE = 5, + SCREENSHOT_TYPE_DEATHPVP = 6, + SCREENSHOT_TYPE_LEVELUP = 7, + SCREENSHOT_TYPE_PLAYERKILLASSIST = 8, + SCREENSHOT_TYPE_PLAYERKILL = 9, + SCREENSHOT_TYPE_PLAYERATTACKING = 10, + SCREENSHOT_TYPE_TREASUREFOUND = 11, + SCREENSHOT_TYPE_SKILLUP = 12 +};