#pragma once #include #include #include #include "worker.h" class UndergroundWorker final: public Worker{ using Row = std::unordered_map; struct HouseConditions { int id; int roof; int floor; int wall; int windowc; }; public: UndergroundWorker(ConnectionPool& pool,MessageBroker& broker):Worker(pool,broker,"UndergroundWorker"){} ~UndergroundWorker() override; protected: void run() override; private: void tick(); std::vector fetchPending(); nlohmann::json executeRow(const Row& r); nlohmann::json handleTask(const std::string& type,int performerId,int victimId,const std::string& paramsJson); nlohmann::json spyIn(int performerId,int victimId,const nlohmann::json& p); nlohmann::json assassin(int performerId,int victimId,const nlohmann::json& p); nlohmann::json sabotage(int performerId,int victimId,const nlohmann::json& p); nlohmann::json corruptPolitician(int performerId,int victimId,const nlohmann::json& p); nlohmann::json rob(int performerId,int victimId,const nlohmann::json& p); void updateResult(int id,const nlohmann::json& result); nlohmann::json sabotageHouse(int performerId,int victimId,const nlohmann::json& p); nlohmann::json sabotageStorage(int performerId,int victimId,const nlohmann::json& p); int getUserIdForCharacter(int characterId); std::optional getHouseByUser(int userId); void updateHouse(const HouseConditions& h); std::vector selectStockByBranch(int branchId); std::vector filterByStockTypes(const std::vector& rows,const std::vector& allowed); void updateStockQty(int id,long long qty); static int randomInt(int lo,int hi); static long long randomLL(long long lo,long long hi); static std::vector randomIndices(size_t n,size_t k); static double randomDouble(double lo,double hi); private: static constexpr const char* Q_SELECT_BY_PERFORMER=R"SQL( SELECT u.id, t.tr AS underground_type, u.performer_id, u.victim_id, to_char(u.created_at,'YYYY-MM-DD"T"HH24:MI:SS"Z"') AS created_at, COALESCE(u.parameters::text,'{}') AS parameters, COALESCE(u.result::text,'null') AS result_text FROM falukant_data.underground u JOIN falukant_type.underground t ON t.tr=u.underground_type_id WHERE u.performer_id=$1 ORDER BY u.created_at DESC )SQL"; static constexpr const char* Q_SELECT_PENDING=R"SQL( SELECT u.id,t.tr AS underground_type,u.performer_id,u.victim_id,COALESCE(u.parameters::text,'{}') AS parameters FROM falukant_data.underground u JOIN falukant_type.underground t ON t.tr=u.underground_type_id WHERE u.result IS NULL AND u.created_at<=NOW()-INTERVAL '1 day' ORDER BY u.created_at ASC LIMIT 200 )SQL"; static constexpr const char* Q_UPDATE_RESULT=R"SQL( UPDATE falukant_data.underground SET result=$2::jsonb,updated_at=NOW() WHERE id=$1 )SQL"; static constexpr const char* Q_SELECT_CHAR_USER=R"SQL( SELECT user_id FROM falukant_data."character" WHERE id=$1 )SQL"; static constexpr const char* Q_SELECT_HOUSE_BY_USER=R"SQL( SELECT id, roof_condition, floor_condition, wall_condition, window_condition FROM falukant_data.user_house WHERE user_id=$1 LIMIT 1 )SQL"; static constexpr const char* Q_UPDATE_HOUSE=R"SQL( UPDATE falukant_data.user_house SET roof_condition=$2, floor_condition=$3, wall_condition=$4, window_condition=$5 WHERE id=$1 )SQL"; static constexpr const char* Q_SELECT_STOCK_BY_BRANCH=R"SQL( SELECT id, stock_type_id, quantity FROM falukant_data.stock WHERE branch_id=$1 ORDER BY quantity DESC )SQL"; static constexpr const char* Q_UPDATE_STOCK_QTY=R"SQL( UPDATE falukant_data.stock SET quantity=$2 WHERE id=$1 )SQL"; static constexpr const char* Q_SELECT_CHAR_HEALTH=R"SQL( SELECT health FROM falukant_data."character" WHERE id=$1 )SQL"; static constexpr const char* Q_UPDATE_CHAR_HEALTH=R"SQL( UPDATE falukant_data."character" SET health=$2, updated_at=NOW() WHERE id=$1 )SQL"; static constexpr const char* Q_SELECT_FALUKANT_USER=R"SQL( SELECT id, money, COALESCE(main_branch_region_id,0) AS main_branch_region_id FROM falukant_data.falukant_user WHERE user_id=$1 LIMIT 1 )SQL"; };