163 lines
4.9 KiB
C++
163 lines
4.9 KiB
C++
#pragma once
|
|
|
|
#include "worker.h"
|
|
#include <random>
|
|
#include <unordered_map>
|
|
#include <unordered_set>
|
|
#include <vector>
|
|
#include <string>
|
|
#include <thread>
|
|
#include <atomic>
|
|
|
|
class CharacterCreationWorker : public Worker {
|
|
public:
|
|
CharacterCreationWorker(ConnectionPool &pool, MessageBroker &broker);
|
|
~CharacterCreationWorker() override;
|
|
|
|
protected:
|
|
void run() override;
|
|
|
|
private:
|
|
std::mt19937 gen;
|
|
std::uniform_int_distribution<int> dist;
|
|
std::unordered_map<std::string, std::unordered_set<int>> first_name_cache;
|
|
std::unordered_set<int> last_name_cache;
|
|
std::atomic<bool> deathCheckRunning{true};
|
|
std::thread deathThread;
|
|
|
|
bool isTodayCharacterCreated();
|
|
void createCharactersForToday();
|
|
void createCharactersForRegion(int region_id);
|
|
void createCharacter(int region_id, const std::string &gender, int title_of_nobility);
|
|
std::vector<int> getTownRegionIds();
|
|
void loadNames();
|
|
int getRandomFromSet(const std::unordered_set<int> &name_set);
|
|
void monitorCharacterDeaths();
|
|
void handleCharacterDeath(int characterId);
|
|
void notifyUser(int userId, const std::string &eventType);
|
|
void markCharacterAsDeceased(int characterId);
|
|
bool calculateDeathProbability(int age);
|
|
|
|
static constexpr const char *QUERY_IS_PREVIOUS_DAY_CHARACTER_CREATED = R"(
|
|
SELECT created_at
|
|
FROM falukant_data."character"
|
|
WHERE user_id IS NULL
|
|
AND created_at::date = CURRENT_DATE
|
|
ORDER BY created_at DESC
|
|
LIMIT 1;
|
|
)";
|
|
|
|
static constexpr const char *QUERY_GET_TOWN_REGION_IDS = R"(
|
|
SELECT fdr.id
|
|
FROM falukant_data.region fdr
|
|
JOIN falukant_type.region ftr ON fdr.region_type_id = ftr.id
|
|
WHERE ftr.label_tr = 'city';
|
|
)";
|
|
|
|
static constexpr const char *QUERY_LOAD_FIRST_NAMES = R"(
|
|
SELECT id, gender
|
|
FROM falukant_predefine.firstname;
|
|
)";
|
|
|
|
static constexpr const char *QUERY_LOAD_LAST_NAMES = R"(
|
|
SELECT id
|
|
FROM falukant_predefine.lastname;
|
|
)";
|
|
|
|
static constexpr const char *QUERY_INSERT_CHARACTER = R"(
|
|
INSERT INTO falukant_data."character"(
|
|
user_id, region_id, first_name, last_name,
|
|
birthdate, gender, created_at, updated_at, title_of_nobility
|
|
)
|
|
VALUES (NULL, $1, $2, $3, NOW(), $4, NOW(), NOW(), $5);
|
|
)";
|
|
|
|
static constexpr const char *QUERY_GET_ELIGIBLE_NPC_FOR_DEATH = R"(
|
|
WITH aged AS (
|
|
SELECT
|
|
c.id,
|
|
(current_date - c.birthdate::date) AS age,
|
|
c.user_id
|
|
FROM
|
|
falukant_data."character" c
|
|
WHERE
|
|
c.user_id IS NULL
|
|
AND (current_date - c.birthdate::date) > 60
|
|
),
|
|
always_sel AS (
|
|
-- Immer mitnehmen: alle über 85 Tage
|
|
SELECT *
|
|
FROM aged
|
|
WHERE age > 85
|
|
),
|
|
random_sel AS (
|
|
-- Zufallsstichprobe: alle zwischen 61 und 85 Tagen, hier beispielhaft auf 10 limitiert
|
|
SELECT *
|
|
FROM aged
|
|
WHERE age <= 85
|
|
ORDER BY random()
|
|
LIMIT 10 -- <-- hier die gewünschte Anzahl anpassen
|
|
)
|
|
-- Zusammenführen der beiden Mengen
|
|
SELECT *
|
|
FROM always_sel
|
|
UNION ALL
|
|
SELECT *
|
|
FROM random_sel;
|
|
)";
|
|
|
|
static constexpr const char *QUERY_DELETE_DIRECTOR = R"(
|
|
DELETE FROM falukant_data.director
|
|
WHERE director_character_id = $1
|
|
RETURNING employer_user_id;
|
|
)";
|
|
|
|
static constexpr const char *QUERY_DELETE_RELATIONSHIP = R"(
|
|
WITH deleted AS (
|
|
DELETE FROM falukant_data.relationship
|
|
WHERE character1_id = $1
|
|
OR character2_id = $1
|
|
RETURNING
|
|
CASE
|
|
WHEN character1_id = $1 THEN character2_id
|
|
ELSE character1_id
|
|
END AS related_character_id,
|
|
relationship_type_id
|
|
)
|
|
SELECT
|
|
c.user_id AS related_user_id
|
|
FROM deleted d
|
|
JOIN falukant_data."character" c
|
|
ON c.id = d.related_character_id;
|
|
)";
|
|
|
|
static constexpr const char *QUERY_DELETE_CHILD_RELATION = R"(
|
|
WITH deleted AS (
|
|
DELETE FROM falukant_data.child_relation
|
|
WHERE child_character_id = $1
|
|
RETURNING
|
|
father_character_id,
|
|
mother_character_id
|
|
)
|
|
SELECT
|
|
cf.user_id AS father_user_id,
|
|
cm.user_id AS mother_user_id
|
|
FROM deleted d
|
|
JOIN falukant_data."character" cf
|
|
ON cf.id = d.father_character_id
|
|
JOIN falukant_data."character" cm
|
|
ON cm.id = d.mother_character_id;
|
|
)";
|
|
|
|
static constexpr const char *QUERY_INSERT_NOTIFICATION = R"(
|
|
INSERT INTO falukant_log.notification (user_id, tr, shown, created_at, updated_at)
|
|
VALUES ($1, 'director_death', false, NOW(), NOW());
|
|
)";
|
|
|
|
|
|
static constexpr const char *QUERY_MARK_CHARACTER_DECEASED = R"(
|
|
DELETE FROM falukant_data."character"
|
|
WHERE id = $1;
|
|
)";
|
|
};
|