stabilized app

This commit is contained in:
Torsten Schulz
2025-07-21 14:59:43 +02:00
committed by Torsten (PC)
parent 51fd9fcd13
commit 1451225978
25 changed files with 3590 additions and 228 deletions

374
src/usercharacterworker.h Normal file
View File

@@ -0,0 +1,374 @@
#ifndef USERCHARACTERWORKER_H
#define USERCHARACTERWORKER_H
#include "worker.h"
#include <random>
class UserCharacterWorker : public Worker {
public:
UserCharacterWorker(ConnectionPool &pool, MessageBroker &broker);
~UserCharacterWorker() override;
protected:
void run() override;
private:
struct Character {
int id;
int age;
int health;
};
void processCharacterEvents();
void updateCharacterHealth(Character& character);
void updateCharactersMood();
int calculateHealthChange(int age);
void handleCharacterDeath(int characterId);
void recalculateKnowledge();
void processPregnancies();
void handleCredits();
void setHeir(int characterId);
int getFalukantUserId(int characterId);
int getHeirFromChildren(int deceasedCharacterId);
int getRandomHeir(int deceasedCharacterId);
void setNewCharacter(int falukantUserId, int heirCharacterId);
void setNewMoney(int falukantUserId, double newAmount);
double getHouseValue(int falukantUserId);
double getSettlementValue(int falukantUserId);
double getInventoryValue(int falukantUserId);
double getCreditDebt(int falukantUserId);
double getCurrentMoney(int falukantUserId);
double calculateNewMoney(int falukantUserId, bool hasHeir);
int getChildCount(int deceasedUserId);
std::random_device rd;
std::mt19937 gen;
std::uniform_real_distribution<> dist;
bool didRunToday { false };
static constexpr const char *QUERY_GET_USERS_TO_UPDATE = R"(
SELECT "id", CURRENT_DATE - birthdate::date AS age, "health"
FROM "falukant_data"."character"
WHERE "user_id" IS NOT NULL;
)";
static constexpr const char *QUERY_UPDATE_CHARACTERS_HEALTH = R"(
UPDATE "falukant_data"."character"
SET health = $1
WHERE id = $2
)";
static constexpr const char *QUERY_UPDATE_GET_ITEMS_TO_UPDATE = R"(
SELECT id, product_id, producer_id, quantity
FROM falukant_log.production p
WHERE p.production_timestamp::date < current_date
)";
static constexpr const char *QUERY_UPDATE_GET_CHARACTER_IDS = R"(
select fu.id user_id, c.id character_id, c2.id director_id
from falukant_data.falukant_user fu
join falukant_data."character" c
on c.user_id = fu.id
left join falukant_data.director d
on d.employer_user_id = fu.id
left join falukant_data."character" c2
on c2.id = d.director_character_id
where fu.id = $1
)";
static constexpr const char *QUERY_UPDATE_KNOWLEDGE = R"(
update falukant_data.knowledge
set knowledge = least(knowledge + $3, 100)
where character_id = $1
and product_id = $2
)";
static constexpr const char *QUERY_DELETE_LOG_ENTRY = R"(
delete from falukant_log.production
where id = $1
)";
static constexpr char const* QUERY_GET_PREGNANCY_CANDIDATES = R"(
SELECT
r.character1_id AS father_cid,
r.character2_id AS mother_cid,
c1.title_of_nobility,
c1.last_name,
c1.region_id,
fu1.id AS father_uid,
fu2.id AS mother_uid,
-- Durchschnittsalter in Tagen
((NOW()::date - c1.birthdate::date)
+ (NOW()::date - c2.birthdate::date)) / 2 AS avg_age_days,
-- Angepasste Schwangerschaftswahrscheinlichkeit in Prozent
100.0 /
(1
+ EXP(
0.0647 * (
((NOW()::date - c1.birthdate::date)
+ (NOW()::date - c2.birthdate::date)) / 2
)
- 0.0591
)
) AS prob_pct
FROM falukant_data.relationship r
JOIN falukant_type.relationship r2
ON r2.id = r.relationship_type_id
AND r2.tr = 'married'
JOIN falukant_data."character" c1
ON c1.id = r.character1_id
JOIN falukant_data."character" c2
ON c2.id = r.character2_id
LEFT JOIN falukant_data.falukant_user fu1
ON fu1.id = c1.user_id
LEFT JOIN falukant_data.falukant_user fu2
ON fu2.id = c2.user_id
WHERE random()*100 < (
100.0 /
(1
+ EXP(
0.11166347 * (
((NOW()::date - c1.birthdate::date)
+ (NOW()::date - c2.birthdate::date)) / 2
)
- 2.638267
)
)
);
)";
static constexpr char const* QUERY_INSERT_CHILD = R"(
INSERT INTO falukant_data."character" (
user_id,
region_id,
first_name,
last_name,
birthdate,
gender,
title_of_nobility,
mood_id,
created_at,
updated_at
) VALUES (
NULL,
$1::int, -- region_id
/* zufälliger Vorname passend zum Gender */
(
SELECT id
FROM falukant_predefine.firstname
WHERE gender = $2
ORDER BY RANDOM()
LIMIT 1
),
$3::int, -- last_name (Eltern-Nachname)
NOW(),
$2::varchar, -- gender
$4::int, -- title_of_nobility
/* zufällige Stimmung */
(
SELECT id
FROM falukant_type.mood
ORDER BY RANDOM()
LIMIT 1
),
NOW(),
NOW()
)
RETURNING id AS child_cid
)";
static constexpr char const* QUERY_INSERT_CHILD_RELATION = R"(
-- QUERY_INSERT_CHILD_RELATION
INSERT INTO falukant_data.child_relation (
father_character_id,
mother_character_id,
child_character_id,
name_set,
created_at,
updated_at
)
VALUES (
$1::int, -- father_cid
$2::int, -- mother_cid
$3::int, -- child_cid
false,
NOW(), NOW()
)
RETURNING
father_character_id,
-- Vater-User
(SELECT user_id FROM falukant_data."character" WHERE id = father_character_id) AS father_user_id,
mother_character_id,
-- Mutter-User
(SELECT user_id FROM falukant_data."character" WHERE id = mother_character_id) AS mother_user_id,
child_character_id,
-- Kind-User
(SELECT user_id FROM falukant_data."character" WHERE id = child_character_id) AS child_user_id;
)";
static constexpr char const* QUERY_AUTOBATISM = R"(
update falukant_data.child_relation
set name_set = true
where id in (
select cr.id
from falukant_data.child_relation cr
join falukant_data."character" c
on c.id = cr.child_character_id
where cr.name_set = false
and c.birthdate < current_date - interval '5 days'
)
)";
static constexpr char const* QUERY_UPDATE_MOOD = R"(
UPDATE falukant_data."character" AS c
SET mood_id = falukant_data.get_random_mood_id()
WHERE c.health > 0;
)";
static constexpr char const* QUERY_GET_OPEN_CREDITS = R"(
select c.id credit_id, c.amount, c.remaining_amount, c.interest_rate, fu.id user_id, fu."money", c2.id character_id, dp.created_at debitor_prism_start,
dp.created_at::date < current_date prism_started_previously
from falukant_data.credit c
join falukant_data.falukant_user fu
on fu.id = c.id
join falukant_data."character" c2
on c2.user_id = c.falukant_user_id
left join falukant_data.debtors_prism dp
on dp.character_id = c2.id
where c.remaining_amount > 0
and c.updated_at::date < current_date
)";
static constexpr char const* QUERY_UPDATE_CREDIT = R"(
update falukant_data.credit c
set remaining_amount = $1
where falukant_user_id = $2
)";
static constexpr char const* QUERY_CLEANUP_CREDITS = R"(
delete from falukant_data.credit
where remaining_amount >= 0.01
)";
static constexpr char const* QUERY_ADD_CHARACTER_TO_DEBTORS_PRISM = R"(
insert into falukant_data.debtors_prism (character_id) values ($1)
)";
static constexpr const char* QUERY_GET_HEIR = R"(
SELECT child_character_id
FROM falukant_data.child_relation
WHERE father_character_id = $1
OR mother_character_id = $1
ORDER BY (is_heir IS TRUE) DESC,
updated_at DESC
LIMIT 1
)";
static constexpr const char* QUERY_RANDOM_HEIR = R"(
WITH chosen AS (
SELECT
cr.id AS relation_id,
cr.child_character_id
FROM
falukant_data.child_relation AS cr
JOIN
falukant_data."character" AS ch
ON ch.id = cr.child_character_id
WHERE
(cr.father_character_id = $1 OR cr.mother_character_id = $1)
-- gleicher Wohnort wie der Verstorbene
AND ch.region_id = (
SELECT region_id
FROM falukant_data."character"
WHERE id = $1
)
-- nicht älter als 10 Tage
AND ch.birthdate >= NOW() - INTERVAL '10 days'
-- Titel "noncivil"
AND ch.title_of_nobility = (
SELECT id
FROM falukant_type.title
WHERE label_tr = 'noncivil'
)
ORDER BY RANDOM()
LIMIT 1
)
UPDATE
falukant_data.child_relation AS cr2
SET
is_heir = true,
updated_at = NOW()
FROM
chosen
WHERE
cr2.id = chosen.relation_id
RETURNING
chosen.child_character_id
)";
static constexpr const char* QUERY_SET_CHARACTER_USER = R"(
UPDATE falukant_data."character"
SET user_id = $1,
updated_at = NOW()
WHERE id = $2
)";
static constexpr const char* QUERY_UPDATE_USER_MONEY = R"(
UPDATE falukant_data.falukant_user
SET money = $1,
updated_at = NOW()
WHERE user_id = $2
)";
static constexpr const char* QUERY_GET_FALUKANT_USER_ID = R"(
SELECT user_id
FROM falukant_data."character"
WHERE id = $1
LIMIT 1
)";
// SubQueries
static constexpr const char* QUERY_GET_CURRENT_MONEY = R"(
SELECT COALESCE(money,0) AS sum
FROM falukant_data.falukant_user
WHERE user_id = $1
)";
static constexpr const char* QUERY_HOUSE_VALUE = R"(
SELECT COALESCE(SUM(h.cost),0) AS sum
FROM falukant_data.user_house AS uh
JOIN falukant_type.house AS h ON uh.house_type_id = h.id
WHERE uh.user_id = $1
)";
static constexpr const char* QUERY_SETTLEMENT_VALUE = R"(
SELECT COALESCE(SUM(b.base_cost),0) AS sum
FROM falukant_data.branch AS br
JOIN falukant_type.branch AS b ON br.branch_type_id = b.id
WHERE br.falukant_user_id = $1
)";
static constexpr const char* QUERY_INVENTORY_VALUE = R"(
SELECT COALESCE(SUM(i.quantity * p.sell_cost),0) AS sum
FROM falukant_data.inventory AS i
JOIN falukant_type.product AS p ON i.product_id = p.id
JOIN falukant_data.branch AS br ON i.stock_id = br.id
WHERE br.falukant_user_id = $1
)";
static constexpr const char* QUERY_CREDIT_DEBT = R"(
SELECT COALESCE(SUM(remaining_amount),0) AS sum
FROM falukant_data.credit
WHERE falukant_user_id = $1
)";
static constexpr const char* QUERY_COUNT_CHILDREN = R"(
SELECT COUNT(*) AS cnt
FROM falukant_data.child_relation
WHERE father_character_id = $1
OR mother_character_id = $1
)";
};
#endif // USERCHARACTERWORKER_H