RPU v2, promo/bank система, админка, оптимизации
— RPU v2: бюджет удачи, потолок (ceiling), комбек после проигрышей, hot/cold анализ, интеграция с promo-фазами — Bank API: mock-банк для карты (депозит/вывод с балансом 1000₽) — Promo-сервис: автогенерация промокодов каждый час, типы (card_to_site, luck_boost, ceiling_boost, free_case, reset_streak) — Promo-фазы: LUCKY/NEUTRAL/UNLUCKY, переключение каждые 1-6ч — Admin: история транзакций (user_history), управление промокодами, управление promo-фазами, API фильтров/коллекций, RPU info — Database: WAL mode, новые поля RPU v2, TransactionLog, карточный баланс, статистики (streaks, ceiling, budget) — Frontend: /deposit, /promo/activate, /withdraw, /card-balance, /online-count, /rpu-info, lifespan вместо startup event — UI: user_history.html, улучшения профиля, кейсов, навигации — Cases: обновление cases.json (1892 строки новых данных) — Achievements: кэш коллекций, оптимизация is_custom проверок — Sounds: дополнительные звуковые эффекты — Upgrade: интеграция с RPU (множители, streaks) — .gitignore: исключены .db, .bak, __pycache__
This commit is contained in:
+183
-204
@@ -5,6 +5,43 @@ from datetime import datetime
|
||||
import json
|
||||
import math
|
||||
|
||||
# Кэш коллекций — строится один раз
|
||||
_COLLECTION_CACHE = None
|
||||
|
||||
def _build_collection_cache():
|
||||
"""Строит кэш: все базовые имена по коллекциям."""
|
||||
global _COLLECTION_CACHE
|
||||
if _COLLECTION_CACHE is not None:
|
||||
return
|
||||
from backend import ALL_ITEMS, COLLECTIONS_INDEX, extract_base_name
|
||||
coll_base_names = {}
|
||||
coll_item_ids = {}
|
||||
for coll_name, item_ids in COLLECTIONS_INDEX.items():
|
||||
base_set = set()
|
||||
clean_ids = [cid for cid in item_ids if cid < len(ALL_ITEMS)]
|
||||
for cid in clean_ids:
|
||||
item = ALL_ITEMS[cid]
|
||||
base = extract_base_name(item.get("market_hash_name", ""))
|
||||
if base:
|
||||
base_set.add(base)
|
||||
if base_set:
|
||||
coll_base_names[coll_name] = base_set
|
||||
coll_item_ids[coll_name] = set(clean_ids)
|
||||
# Кэшируем custom-флаг на каждую коллекцию
|
||||
coll_is_custom = {}
|
||||
for coll_name, item_ids in COLLECTIONS_INDEX.items():
|
||||
is_custom = False
|
||||
for cid in item_ids:
|
||||
if cid < len(ALL_ITEMS) and ALL_ITEMS[cid].get("price_source") == "custom":
|
||||
is_custom = True
|
||||
break
|
||||
coll_is_custom[coll_name] = is_custom
|
||||
_COLLECTION_CACHE = {
|
||||
"base_names": coll_base_names,
|
||||
"item_ids": coll_item_ids,
|
||||
"is_custom": coll_is_custom,
|
||||
}
|
||||
|
||||
# ─── Определения достижений ─────────────────────────────────────────────────
|
||||
|
||||
ACHIEVEMENT_DEFS = [
|
||||
@@ -1803,126 +1840,92 @@ ACHIEVEMENT_DEFS = [
|
||||
# ─── Функции проверки достижений ──────────────────────────────────────────
|
||||
|
||||
def check_collection_achievements(db: Session, user_id: int):
|
||||
"""Проверяет достижения, связанные с коллекциями"""
|
||||
from backend import ALL_ITEMS, COLLECTIONS_INDEX, extract_base_name
|
||||
"""Проверяет достижения, связанные с коллекциями — использует кэш."""
|
||||
from database import InventoryItem
|
||||
_build_collection_cache()
|
||||
cache = _COLLECTION_CACHE
|
||||
coll_base_names = cache["base_names"]
|
||||
coll_item_ids = cache["item_ids"]
|
||||
coll_is_custom = cache["is_custom"]
|
||||
results = []
|
||||
|
||||
# Все предметы пользователя
|
||||
user_inv = db.query(InventoryItem.item_id).filter(
|
||||
# ID предметов пользователя
|
||||
user_ids = {iid for (iid,) in db.query(InventoryItem.item_id).filter(
|
||||
InventoryItem.user_id == user_id
|
||||
).all()
|
||||
user_ids = {iid for (iid,) in user_inv}
|
||||
).all()}
|
||||
|
||||
# Собираем все коллекции, в которых есть предметы пользователя
|
||||
# и уникальные базовые имена предметов из коллекций
|
||||
user_collections = set()
|
||||
user_coll_base_names = {} # collection_name → set of base names owned
|
||||
all_coll_base_names = {} # collection_name → set of all base names in collection
|
||||
|
||||
for coll_name, item_ids in COLLECTIONS_INDEX.items():
|
||||
base_set = set()
|
||||
for cid in item_ids:
|
||||
item = ALL_ITEMS[cid] if cid < len(ALL_ITEMS) else None
|
||||
if item:
|
||||
base = extract_base_name(item.get("market_hash_name", ""))
|
||||
if base:
|
||||
base_set.add(base)
|
||||
if base_set:
|
||||
all_coll_base_names[coll_name] = base_set
|
||||
|
||||
# Check if user owns any item from this collection
|
||||
owned_bases = set()
|
||||
for cid in item_ids:
|
||||
if cid in user_ids:
|
||||
item = ALL_ITEMS[cid] if cid < len(ALL_ITEMS) else None
|
||||
if item:
|
||||
base = extract_base_name(item.get("market_hash_name", ""))
|
||||
# Коллекции пользователя
|
||||
from backend import ALL_ITEMS, COLLECTIONS_INDEX, extract_base_name, RARITY_ORDER
|
||||
user_coll_base_names = {}
|
||||
for coll_name, item_ids_set in coll_item_ids.items():
|
||||
owned = user_ids & item_ids_set
|
||||
if owned:
|
||||
owned_bases = set()
|
||||
for cid in owned:
|
||||
if cid < len(ALL_ITEMS):
|
||||
base = extract_base_name(ALL_ITEMS[cid].get("market_hash_name", ""))
|
||||
if base:
|
||||
owned_bases.add(base)
|
||||
if owned_bases:
|
||||
user_collections.add(coll_name)
|
||||
user_coll_base_names[coll_name] = owned_bases
|
||||
if owned_bases:
|
||||
user_coll_base_names[coll_name] = owned_bases
|
||||
|
||||
# collection_count: unique collections user has items from
|
||||
coll_count = len(user_collections)
|
||||
coll_count = len(user_coll_base_names)
|
||||
for n in ["coll_first", "coll_5", "coll_10", "coll_25", "coll_50", "coll_75", "coll_100"]:
|
||||
r = check_achievement(db, user_id, n, coll_count)
|
||||
if r: results.append(r)
|
||||
|
||||
# collection_items: unique base items from collections owned
|
||||
all_owned_bases = set()
|
||||
for bases in user_coll_base_names.values():
|
||||
all_owned_bases.update(bases)
|
||||
total_unique_items = len(all_owned_bases)
|
||||
total_unique = len(all_owned_bases)
|
||||
for n in ["coll_items_10", "coll_items_50", "coll_items_100", "coll_items_250",
|
||||
"coll_items_500", "coll_items_1000"]:
|
||||
r = check_achievement(db, user_id, n, total_unique_items)
|
||||
r = check_achievement(db, user_id, n, total_unique)
|
||||
if r: results.append(r)
|
||||
|
||||
# collection_complete_count: collections where user owns ALL base items
|
||||
complete_count = 0
|
||||
for coll_name, all_bases in all_coll_base_names.items():
|
||||
owned_bases = user_coll_base_names.get(coll_name, set())
|
||||
if all_bases.issubset(owned_bases):
|
||||
for coll_name, all_bases in coll_base_names.items():
|
||||
owned = user_coll_base_names.get(coll_name, set())
|
||||
if all_bases.issubset(owned):
|
||||
complete_count += 1
|
||||
for n in ["coll_complete_1", "coll_complete_5", "coll_complete_10", "coll_complete_25",
|
||||
"coll_complete_50"]:
|
||||
r = check_achievement(db, user_id, n, complete_count)
|
||||
if r: results.append(r)
|
||||
|
||||
# coll_all_base: all NON-CUSTOM collections complete
|
||||
non_custom_collections = {}
|
||||
for coll_name, item_ids in COLLECTIONS_INDEX.items():
|
||||
# Check if any item in this collection is custom
|
||||
is_custom = False
|
||||
for cid in item_ids:
|
||||
item = ALL_ITEMS[cid] if cid < len(ALL_ITEMS) else None
|
||||
if item and item.get("price_source") == "custom":
|
||||
is_custom = True
|
||||
break
|
||||
if not is_custom and coll_name in all_coll_base_names:
|
||||
non_custom_collections[coll_name] = all_coll_base_names[coll_name]
|
||||
|
||||
all_base_complete = True
|
||||
for coll_name, all_bases in non_custom_collections.items():
|
||||
owned_bases = user_coll_base_names.get(coll_name, set())
|
||||
if not all_bases.issubset(owned_bases):
|
||||
all_base_complete = False
|
||||
break
|
||||
if all_base_complete and non_custom_collections:
|
||||
non_custom = {k: v for k, v in coll_base_names.items() if not coll_is_custom.get(k)}
|
||||
all_base_ok = all(
|
||||
non_custom[c].issubset(user_coll_base_names.get(c, set()))
|
||||
for c in non_custom
|
||||
)
|
||||
if all_base_ok and non_custom:
|
||||
r = check_achievement(db, user_id, "coll_all_base", 1)
|
||||
if r: results.append(r)
|
||||
|
||||
# coll_all: ALL collections complete (including custom)
|
||||
all_complete = True
|
||||
for coll_name, all_bases in all_coll_base_names.items():
|
||||
owned_bases = user_coll_base_names.get(coll_name, set())
|
||||
if not all_bases.issubset(owned_bases):
|
||||
all_complete = False
|
||||
break
|
||||
if all_complete and all_coll_base_names:
|
||||
all_ok = all(
|
||||
coll_base_names[c].issubset(user_coll_base_names.get(c, set()))
|
||||
for c in coll_base_names
|
||||
)
|
||||
if all_ok and coll_base_names:
|
||||
r = check_achievement(db, user_id, "coll_all", 1)
|
||||
if r: results.append(r)
|
||||
|
||||
# coll_rarity_complete: complete all items of specific rarity tiers in any collection
|
||||
from backend import RARITY_ORDER
|
||||
rarity_collectors = [
|
||||
("coll_cheap_collector", {0}), # Consumer Grade
|
||||
("coll_mid_collector", {2}), # Mil-Spec / Mil-Spec Grade
|
||||
("coll_rare_collector", {3, 4, 5, 6, 7, 8}), # Restricted+
|
||||
("coll_covert_collector", {5}), # Covert
|
||||
("coll_cheap_collector", {0}),
|
||||
("coll_mid_collector", {2}),
|
||||
("coll_rare_collector", {3, 4, 5, 6, 7, 8}),
|
||||
("coll_covert_collector", {5}),
|
||||
]
|
||||
for ach_name, target_levels in rarity_collectors:
|
||||
found = False
|
||||
for coll_name in all_coll_base_names:
|
||||
# Collect all items at target rarity levels for this collection
|
||||
for coll_name in coll_base_names:
|
||||
owned = user_coll_base_names.get(coll_name, set())
|
||||
all_target = set()
|
||||
owned_target = set()
|
||||
for cid in COLLECTIONS_INDEX.get(coll_name, []):
|
||||
item = ALL_ITEMS[cid] if cid < len(ALL_ITEMS) else None
|
||||
if not item:
|
||||
if cid >= len(ALL_ITEMS):
|
||||
continue
|
||||
item = ALL_ITEMS[cid]
|
||||
base = extract_base_name(item.get("market_hash_name", ""))
|
||||
if not base:
|
||||
continue
|
||||
@@ -1938,24 +1941,13 @@ def check_collection_achievements(db: Session, user_id: int):
|
||||
r = check_achievement(db, user_id, ach_name, 1)
|
||||
if r: results.append(r)
|
||||
|
||||
# coll_case_complete: complete all items from a case
|
||||
for coll_name, all_bases in all_coll_base_names.items():
|
||||
if not coll_name.startswith("Case:"):
|
||||
continue
|
||||
owned_bases = user_coll_base_names.get(coll_name, set())
|
||||
if all_bases.issubset(owned_bases):
|
||||
r = check_achievement(db, user_id, "coll_full_case", 1)
|
||||
if r: results.append(r)
|
||||
break
|
||||
# Also check non-case named collections
|
||||
for coll_name, all_bases in all_coll_base_names.items():
|
||||
for coll_name in coll_base_names:
|
||||
if coll_name.startswith("Case:"):
|
||||
continue
|
||||
owned_bases = user_coll_base_names.get(coll_name, set())
|
||||
if all_bases.issubset(owned_bases):
|
||||
# This also counts for coll_full_case if user wants case completion
|
||||
pass # Already counted in collection_complete_count above
|
||||
|
||||
owned = user_coll_base_names.get(coll_name, set())
|
||||
if coll_base_names[coll_name].issubset(owned):
|
||||
r = check_achievement(db, user_id, "coll_full_case", 1)
|
||||
if r: results.append(r)
|
||||
break
|
||||
return results
|
||||
|
||||
|
||||
@@ -2009,15 +2001,10 @@ def check_achievement(db: Session, user_id: int, achievement_name: str, current_
|
||||
|
||||
if current_value >= ach.requirement_value:
|
||||
ua.unlocked_at = datetime.utcnow()
|
||||
from database import User
|
||||
user = db.query(User).filter(User.id == user_id).first()
|
||||
if user:
|
||||
user.balance += ach.reward_amount
|
||||
db.commit()
|
||||
|
||||
activity = ActivityFeed(
|
||||
user_id=user_id,
|
||||
username=user.username if user else "unknown",
|
||||
username=f"user_{user_id}",
|
||||
activity_type="achievement",
|
||||
message=f"🏆 Получено достижение: {ach.title}",
|
||||
data_json=json.dumps({
|
||||
@@ -2027,7 +2014,7 @@ def check_achievement(db: Session, user_id: int, achievement_name: str, current_
|
||||
})
|
||||
)
|
||||
db.add(activity)
|
||||
db.commit()
|
||||
db.flush()
|
||||
|
||||
return {
|
||||
"name": ach.name,
|
||||
@@ -2036,10 +2023,11 @@ def check_achievement(db: Session, user_id: int, achievement_name: str, current_
|
||||
"reward": ach.reward_amount
|
||||
}
|
||||
|
||||
db.commit()
|
||||
db.flush()
|
||||
return None
|
||||
|
||||
|
||||
|
||||
# ─── Существующие проверки (расширенные) ───────────────────────────────────
|
||||
|
||||
def check_open_cases_achievements(db: Session, user_id: int):
|
||||
@@ -2110,31 +2098,19 @@ def check_upgrade_risk_achievements(db: Session, user_id: int, item_price: float
|
||||
def check_upgrade_result_achievements(db: Session, user_id: int, success: bool, probability: float, item_price: float):
|
||||
"""Вызывается после завершения апгрейда — проверяет серии, чудеса и т.д."""
|
||||
from database import Upgrade
|
||||
from upgrade import get_upgrade_rpu
|
||||
results = []
|
||||
|
||||
# Consecutive wins/losses
|
||||
all_upgrades = db.query(Upgrade.success).filter(
|
||||
Upgrade.user_id == user_id
|
||||
).order_by(Upgrade.id.desc()).all()
|
||||
# Используем UpgradeRPU.current_win_streak / current_lose_streak вместо загрузки всех апгрейдов
|
||||
rpu = get_upgrade_rpu(db, user_id)
|
||||
|
||||
streak = 0
|
||||
streak_type = None # True = wins, False = losses
|
||||
for (s,) in all_upgrades:
|
||||
if streak_type is None:
|
||||
streak_type = s
|
||||
streak = 1
|
||||
elif s == streak_type:
|
||||
streak += 1
|
||||
else:
|
||||
break
|
||||
|
||||
if streak_type == True:
|
||||
if rpu.current_win_streak > 0:
|
||||
for n in ["upgrade_consecutive_wins_3", "upgrade_consecutive_wins_5", "upgrade_consecutive_wins_10"]:
|
||||
r = check_achievement(db, user_id, n, streak)
|
||||
r = check_achievement(db, user_id, n, rpu.current_win_streak)
|
||||
if r: results.append(r)
|
||||
elif streak_type == False:
|
||||
if rpu.current_lose_streak > 0:
|
||||
for n in ["upgrade_consecutive_losses_5", "upgrade_consecutive_losses_10"]:
|
||||
r = check_achievement(db, user_id, n, streak)
|
||||
r = check_achievement(db, user_id, n, rpu.current_lose_streak)
|
||||
if r: results.append(r)
|
||||
|
||||
# Low value win
|
||||
@@ -2287,108 +2263,115 @@ def check_inventory_achievements(db: Session, user_id: int):
|
||||
return results
|
||||
|
||||
|
||||
# Кэш ID дилдоков (строится один раз через импорт)
|
||||
_DILDO_IDS_CACHE = None
|
||||
|
||||
def _get_dildo_ids():
|
||||
global _DILDO_IDS_CACHE
|
||||
if _DILDO_IDS_CACHE is None:
|
||||
from backend import ALL_ITEMS
|
||||
_DILDO_IDS_CACHE = [i for i, it in enumerate(ALL_ITEMS) if it.get("weapon") == "Dildo"]
|
||||
return _DILDO_IDS_CACHE
|
||||
|
||||
|
||||
def check_dildo_achievements(db: Session, user_id: int):
|
||||
"""Проверяет все Dildo-связанные достижения"""
|
||||
"""Проверяет все Dildo-связанные достижения — инвентарь грузит только IN-запросом."""
|
||||
from database import InventoryItem
|
||||
from backend import ALL_ITEMS
|
||||
from sqlalchemy import func as sa_func
|
||||
results = []
|
||||
|
||||
items = db.query(InventoryItem).filter(InventoryItem.user_id == user_id).all()
|
||||
dildo_items = []
|
||||
for inv_item in items:
|
||||
if inv_item.item_id < len(ALL_ITEMS):
|
||||
item_data = ALL_ITEMS[inv_item.item_id]
|
||||
if item_data.get("weapon") == "Dildo":
|
||||
dildo_items.append((inv_item, item_data))
|
||||
# Загружаем только dildo-предметы через IN-запрос
|
||||
dildo_ids = _get_dildo_ids()
|
||||
if not dildo_ids:
|
||||
dildo_inv = []
|
||||
else:
|
||||
dildo_inv_raw = db.query(InventoryItem).filter(
|
||||
InventoryItem.user_id == user_id,
|
||||
InventoryItem.item_id.in_(dildo_ids)
|
||||
).all()
|
||||
dildo_inv = [(inv, ALL_ITEMS[inv.item_id]) for inv in dildo_inv_raw
|
||||
if inv.item_id < len(ALL_ITEMS)]
|
||||
|
||||
dildo_count = len(dildo_items)
|
||||
dildo_count = len(dildo_inv)
|
||||
|
||||
# Dildo count achievements
|
||||
for n in ["dildo_owned", "dildo_5", "dildo_10", "dildo_25", "dildo_50", "dildo_100"]:
|
||||
r = check_achievement(db, user_id, n, dildo_count)
|
||||
if r: results.append(r)
|
||||
|
||||
# Best item price in inventory
|
||||
best_price = 0
|
||||
for inv_item in items:
|
||||
if inv_item.item_id < len(ALL_ITEMS):
|
||||
p = ALL_ITEMS[inv_item.item_id].get("price_rub", 0)
|
||||
if p > best_price:
|
||||
best_price = p
|
||||
# Best price, total value — через aggregates
|
||||
best_price = db.query(sa_func.max(InventoryItem.price_rub)).filter(
|
||||
InventoryItem.user_id == user_id
|
||||
).scalar() or 0
|
||||
for n in ["item_worth_1m", "item_worth_10m", "item_worth_100m", "item_worth_1b"]:
|
||||
r = check_achievement(db, user_id, n, best_price)
|
||||
if r: results.append(r)
|
||||
|
||||
# Total inventory value
|
||||
total_val = 0
|
||||
for inv_item in items:
|
||||
if inv_item.item_id < len(ALL_ITEMS):
|
||||
total_val += ALL_ITEMS[inv_item.item_id].get("price_rub", 0)
|
||||
total_val = db.query(sa_func.sum(InventoryItem.price_rub)).filter(
|
||||
InventoryItem.user_id == user_id
|
||||
).scalar() or 0
|
||||
for n in ["inventory_value_10m", "inventory_value_100m", "inventory_value_1b"]:
|
||||
r = check_achievement(db, user_id, n, total_val)
|
||||
if r: results.append(r)
|
||||
|
||||
# Dildo float achievements
|
||||
best_float = 1.0
|
||||
for inv_item, item_data in dildo_items:
|
||||
f = inv_item.float_value or 1.0
|
||||
if f < best_float:
|
||||
best_float = f
|
||||
if best_float < 0.01:
|
||||
# Float achievements
|
||||
best_dildo_float = db.query(sa_func.min(InventoryItem.float_value)).filter(
|
||||
InventoryItem.user_id == user_id,
|
||||
InventoryItem.item_id < len(ALL_ITEMS)
|
||||
).filter(
|
||||
InventoryItem.item_id.in_([i for i, d in enumerate(ALL_ITEMS) if d.get("weapon") == "Dildo"])
|
||||
).scalar() or 1.0
|
||||
if best_dildo_float < 0.01:
|
||||
r = check_achievement(db, user_id, "dildo_float_001", 1)
|
||||
if r: results.append(r)
|
||||
if best_float < 0.005:
|
||||
if best_dildo_float < 0.005:
|
||||
r = check_achievement(db, user_id, "dildo_float_0005", 2)
|
||||
if r: results.append(r)
|
||||
|
||||
# Ultra rare float (any item)
|
||||
ultra_rare = 1.0
|
||||
for inv_item in items:
|
||||
f = inv_item.float_value or 1.0
|
||||
if f < ultra_rare:
|
||||
ultra_rare = f
|
||||
ultra_rare = db.query(sa_func.min(InventoryItem.float_value)).filter(
|
||||
InventoryItem.user_id == user_id
|
||||
).scalar() or 1.0
|
||||
if ultra_rare < 0.001:
|
||||
r = check_achievement(db, user_id, "ultra_rare_float", 0.001)
|
||||
if r: results.append(r)
|
||||
|
||||
# Secret: exact float 0.001 (or close)
|
||||
for inv_item in items:
|
||||
f = inv_item.float_value or 0
|
||||
if abs(f - 0.001) < 0.0001:
|
||||
r = check_achievement(db, user_id, "secret_exact_float", 1)
|
||||
if r: results.append(r)
|
||||
break
|
||||
|
||||
# Dildo all rarities
|
||||
dildo_rarities = set()
|
||||
for inv_item, item_data in dildo_items:
|
||||
dildo_rarities.add(item_data.get("rarity"))
|
||||
if len(dildo_rarities) >= 5: # Consumer, Industrial, Mil-Spec, Restricted, Classified, Covert
|
||||
r = check_achievement(db, user_id, "dildo_all_rarities", 1)
|
||||
# Secret float
|
||||
secret_float = db.query(InventoryItem).filter(
|
||||
InventoryItem.user_id == user_id,
|
||||
sa_func.abs(InventoryItem.float_value - 0.001) < 0.0001
|
||||
).first()
|
||||
if secret_float:
|
||||
r = check_achievement(db, user_id, "secret_exact_float", 1)
|
||||
if r: results.append(r)
|
||||
|
||||
# Dildo unique count (by pattern/name)
|
||||
unique_patterns = set()
|
||||
for inv_item, item_data in dildo_items:
|
||||
name = item_data.get("market_hash_name", "")
|
||||
unique_patterns.add(name)
|
||||
r = check_achievement(db, user_id, "dildo_full_set", len(unique_patterns))
|
||||
if r: results.append(r)
|
||||
# Dildo rarities & unique patterns & total value — из dildo_inv (уже загружено)
|
||||
if dildo_inv:
|
||||
dildo_rarities = set()
|
||||
unique_patterns = set()
|
||||
dildo_total = 0
|
||||
for inv_item, item_data in dildo_inv:
|
||||
dildo_rarities.add(item_data.get("rarity"))
|
||||
unique_patterns.add(item_data.get("market_hash_name", ""))
|
||||
dildo_total += item_data.get("price_rub", 0)
|
||||
|
||||
# Dildo total value
|
||||
dildo_total = 0
|
||||
for inv_item, item_data in dildo_items:
|
||||
dildo_total += item_data.get("price_rub", 0)
|
||||
r = check_achievement(db, user_id, "dildo_worth_100m", dildo_total)
|
||||
if r: results.append(r)
|
||||
|
||||
# Secret: specific dildo name
|
||||
for inv_item, item_data in dildo_items:
|
||||
name = item_data.get("market_hash_name", "")
|
||||
if "Big Black" in name:
|
||||
r = check_achievement(db, user_id, "secret_dildo_specific", 1)
|
||||
if len(dildo_rarities) >= 5:
|
||||
r = check_achievement(db, user_id, "dildo_all_rarities", 1)
|
||||
if r: results.append(r)
|
||||
break
|
||||
|
||||
r = check_achievement(db, user_id, "dildo_full_set", len(unique_patterns))
|
||||
if r: results.append(r)
|
||||
|
||||
r = check_achievement(db, user_id, "dildo_worth_100m", dildo_total)
|
||||
if r: results.append(r)
|
||||
|
||||
# Secret dildo name
|
||||
for inv_item, item_data in dildo_inv:
|
||||
if "Big Black" in item_data.get("market_hash_name", ""):
|
||||
r = check_achievement(db, user_id, "secret_dildo_specific", 1)
|
||||
if r: results.append(r)
|
||||
break
|
||||
|
||||
return results
|
||||
|
||||
@@ -2480,14 +2463,10 @@ def check_achievements_count_achievements(db: Session, user_id: int):
|
||||
|
||||
def check_rare_item_count_achievements(db: Session, user_id: int):
|
||||
from database import InventoryItem
|
||||
from backend import ALL_ITEMS
|
||||
items = db.query(InventoryItem).filter(InventoryItem.user_id == user_id).all()
|
||||
rare_count = 0
|
||||
for inv in items:
|
||||
if inv.item_id < len(ALL_ITEMS):
|
||||
rar = ALL_ITEMS[inv.item_id].get("rarity", "")
|
||||
if rar in ("Covert", "Extraordinary", "Rare Special Item"):
|
||||
rare_count += 1
|
||||
rare_count = db.query(InventoryItem).filter(
|
||||
InventoryItem.user_id == user_id,
|
||||
InventoryItem.rarity.in_(["Covert", "Extraordinary", "Rare Special Item"])
|
||||
).count()
|
||||
results = []
|
||||
for n in ["rare_item_10", "rare_item_50"]:
|
||||
r = check_achievement(db, user_id, n, rare_count)
|
||||
@@ -2498,11 +2477,11 @@ def check_rare_item_count_achievements(db: Session, user_id: int):
|
||||
def check_knife_count_achievements(db: Session, user_id: int):
|
||||
from database import InventoryItem
|
||||
from backend import ALL_ITEMS, is_knife, is_gloves
|
||||
items = db.query(InventoryItem).filter(InventoryItem.user_id == user_id).all()
|
||||
knife_count = 0
|
||||
for inv in items:
|
||||
if inv.item_id < len(ALL_ITEMS):
|
||||
item_data = ALL_ITEMS[inv.item_id]
|
||||
items = db.query(InventoryItem.item_id).filter(InventoryItem.user_id == user_id).all()
|
||||
for (item_id,) in items:
|
||||
if item_id < len(ALL_ITEMS):
|
||||
item_data = ALL_ITEMS[item_id]
|
||||
if is_knife(item_data) or is_gloves(item_data):
|
||||
knife_count += 1
|
||||
results = []
|
||||
|
||||
Reference in New Issue
Block a user