Загрузка...

Скрипт [BOT] - Удобная торговля на куче аккаунтов MARKET.CSGO

Тема в разделе Python создана пользователем убежище 19 апр 2025. 270 просмотров

Загрузка...
  1. убежище
    убежище Автор темы 19 апр 2025 https://t.me/twitchpaty 6162 12 май 2022
    Всем хай. Бот позволяет торговать через апи ключи и платежные пароли.
    отлично подойдет для фермеров. Предметы на продажу выставляются по ценам АВТОБАЯ! Важно!!!!!
    [IMG]
    [IMG]
    [IMG]
    [IMG]
    (этот скриншотик старый, кнопки Удалить нету)​
    Функционал:
    - Добавление аккаунтов через "TOKEN PAY_PASSWORD"
    - Удаление аккаунтов
    - Обновление инвентаря на сайте
    - Быстрая массовая продажа
    - Продажа поштучно (выбираете сами предмет)
    - Автовывод средств на основной аккаунт (для этого нужно будет настроить мейн-акк в боте, далее поясню как работает)
    - Автоподнятие (всегда включайте, ибо маркет раз в 3 минуты будет вырубать продажи, а эта функция включает их снова)
    - Список аккаунтов


    Для корректной работы скрипта - необходимо держать включенным либо на сервере либо на пк - MARKET APP с настроенными mafile's, что бы автоматически отправлялись и подтверждались трейды.

    Автовывод средств на основной аккаунт - это функция которая ВНУТРИ САЙТА переводит бабки на нужный вам аккаунт. Отлично подойдет если вы продали на 1000 аккаунтов по 1 кейсу и хотите вывести кеш :smiledog:
    Python
    import telebot
    import sqlite3
    import time
    import threading
    import logging
    import requests
    from telebot import types
    import json # Импортируем модуль json
    import sys
    import os

    # Замените 'TOKEN' на токен вашего бота
    BOT_TOKEN = 'TOKEN'
    # market.csgo.com API URL
    API_BASE_URL = 'https://market.csgo.com/api/v2'
    # Валюта по умолчанию
    DEFAULT_CURRENCY = 'RUB'

    # Настройка логирования
    logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
    logger = logging.getLogger(__name__)

    # Глобальная переменная для бота
    bot = None

    # Функция для создания подключения к базе данных
    def create_connection():
    """Создает подключение к базе данных SQLite."""
    try:
    conn = sqlite3.connect('csgoflipbot.db')
    return conn
    except Exception as e:
    logger.error(f"Ошибка при подключении к базе данных: {e}")
    return None

    # Функция для создания таблиц в базе данных
    def create_tables():
    """Создает таблицы в базе данных, если они не существуют."""
    conn = create_connection()
    if conn is not None:
    try:
    cursor = conn.cursor()
    # Таблица для хранения информации об аккаунтах
    cursor.execute('''
    CREATE TABLE IF NOT EXISTS accounts (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    api_key TEXT NOT NULL UNIQUE,
    payment_password TEXT NOT NULL,
    auto_ping INTEGER DEFAULT 0,
    account_name TEXT,
    user_id INTEGER NOT NULL,
    is_main INTEGER DEFAULT 0
    )
    ''')
    # Таблица для связи аккаунтов и чатов (для каждого чата свои настройки аккаунтов)
    cursor.execute('''
    CREATE TABLE IF NOT EXISTS chat_accounts (
    chat_id INTEGER NOT NULL,
    account_id INTEGER NOT NULL,
    user_id INTEGER NOT NULL,
    PRIMARY KEY (chat_id, account_id),
    FOREIGN KEY (account_id) REFERENCES accounts (id)
    )
    ''')
    # Таблица для хранения инвентаря
    cursor.execute('''
    CREATE TABLE IF NOT EXISTS inventory (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    account_id INTEGER NOT NULL,
    item_id TEXT NOT NULL,
    market_hash_name TEXT NOT NULL,
    market_price REAL NOT NULL,
    FOREIGN KEY (account_id) REFERENCES accounts (id),
    UNIQUE (account_id, item_id)
    )
    ''')
    conn.commit()
    logger.info("Таблицы базы данных успешно созданы.")
    except Exception as e:
    logger.error(f"Ошибка при создании таблиц: {e}")
    finally:
    conn.close()
    else:
    logger.error("Не удалось подключиться к базе данных.")

    # Функция для добавления аккаунта в базу данных
    def add_account(api_key, payment_password, user_id, account_name=None):
    """Добавляет новый аккаунт в базу данных."""
    conn = create_connection()
    if conn is not None:
    try:
    cursor = conn.cursor()
    cursor.execute(
    "INSERT INTO accounts (api_key, payment_password, account_name, user_id) VALUES (?, ?, ?, ?)",
    (api_key, payment_password, account_name, user_id),
    )
    conn.commit()
    logger.info(f"Аккаунт с API-ключом {api_key} успешно добавлен для пользователя {user_id}.")
    return True
    except sqlite3.IntegrityError:
    logger.warning(f"Аккаунт с API-ключом {api_key} уже существует.")
    return False
    except Exception as e:
    logger.error(f"Ошибка при добавлении аккаунта: {e}")
    return False
    finally:
    conn.close()
    else:
    logger.error("Не удалось подключиться к базе данных.")
    return False

    # Функция для получения списка всех аккаунтов
    def get_all_accounts(user_id=None):
    """Получает список всех аккаунтов из базы данных.
    Если user_id указан, возвращает только аккаунты этого пользователя.
    Если user_id не указан, возвращает все аккаунты в системе."""
    conn = create_connection()
    if conn is not None:
    try:
    cursor = conn.cursor()
    if user_id is not None:
    cursor.execute(
    "SELECT id, api_key, payment_password, auto_ping, account_name FROM accounts WHERE user_id = ?",
    (user_id,)
    )
    else:
    cursor.execute("SELECT id, api_key, payment_password, auto_ping, account_name FROM accounts")
    accounts = cursor.fetchall()
    return accounts
    except Exception as e:
    logger.error(f"Ошибка при получении списка аккаунтов: {e}")
    return []
    finally:
    conn.close()
    else:
    logger.error("Не удалось подключиться к базе данных.")
    return []

    # Функция для получения аккаунта по API-ключу
    def get_account_by_api_key(api_key):
    """Получает аккаунт из базы данных по API-ключу."""
    conn = create_connection()
    if conn is not None:
    try:
    cursor = conn.cursor()
    cursor.execute("SELECT id, api_key, payment_password, auto_ping, account_name FROM accounts WHERE api_key = ?", (api_key,))
    account = cursor.fetchone()
    return account
    except Exception as e:
    logger.error(f"Ошибка при получении аккаунта по API-ключу: {e}")
    return None
    finally:
    conn.close()
    else:
    logger.error("Не удалось подключиться к базе данных.")
    return None

    # Функция для получения главного аккаунта пользователя
    def get_main_account(user_id):
    """Получает главный аккаунт пользователя из базы данных."""
    conn = create_connection()
    if conn is not None:
    try:
    cursor = conn.cursor()
    cursor.execute(
    "SELECT id, api_key, payment_password, auto_ping, account_name FROM accounts WHERE user_id = ? AND is_main = 1",
    (user_id,)
    )
    account = cursor.fetchone()
    return account
    except Exception as e:
    logger.error(f"Ошибка при получении главного аккаунта: {e}")
    return None
    finally:
    conn.close()
    else:
    logger.error("Не удалось подключиться к базе данных.")
    return None

    # Функция для обновления настроек аккаунта
    def update_account_settings(api_key, auto_ping=None, payment_password=None, account_name=None, is_main=None):
    """Обновляет настройки аккаунта в базе данных."""
    conn = create_connection()
    if conn is not None:
    try:
    cursor = conn.cursor()
    # Обновляем только переданные параметры
    updates = []
    values = []
    if auto_ping is not None:
    updates.append("auto_ping = ?")
    values.append(auto_ping)
    if payment_password is not None:
    updates.append("payment_password = ?")
    values.append(payment_password)
    if account_name is not None:
    updates.append("account_name = ?")
    values.append(account_name)
    if is_main is not None:
    # Если устанавливаем новый главный аккаунт, сбрасываем флаг у других аккаунтов этого пользователя
    if is_main == 1:
    account = get_account_by_api_key(api_key)
    if account:
    # Получаем user_id из базы данных
    cursor.execute("SELECT user_id FROM accounts WHERE api_key = ?", (api_key,))
    user_id_result = cursor.fetchone()
    if user_id_result:
    user_id = user_id_result[0]
    cursor.execute(
    "UPDATE accounts SET is_main = 0 WHERE user_id = ? AND api_key != ?",
    (user_id, api_key)
    )
    updates.append("is_main = ?")
    values.append(is_main)
    if not updates:
    return True # Ничего не обновлено

    query = f"UPDATE accounts SET {', '.join(updates)} WHERE api_key = ?"
    values.append(api_key)
    cursor.execute(query, tuple(values))
    conn.commit()
    logger.info(f"Настройки аккаунта с API-ключом {api_key} успешно обновлены.")
    return True
    except Exception as e:
    logger.error(f"Ошибка при обновлении настроек аккаунта: {e}")
    return False
    finally:
    conn.close()
    else:
    logger.error("Не удалось подключиться к базе данных.")
    return False

    # Функция для выполнения запросов к API market.csgo.com
    def make_api_request(api_key, method, params=None, use_post=False):
    """Выполняет запрос к API market.csgo.com с обработкой ошибок."""
    url = f"{API_BASE_URL}/{method}?key={api_key}" # Добавляем api_key в URL
    try:
    if use_post:
    response = requests.post(url, data=params)
    else:
    if params:
    response = requests.get(url, params=params)
    else:
    response = requests.get(url)
    response.raise_for_status() # Поднимает исключение для HTTP ошибок
    return response.json()
    except requests.exceptions.RequestException as e:
    logger.error(f"Ошибка при выполнении запроса {method}: {e}")
    return None
    except json.JSONDecodeError:
    logger.error(f"Ошибка декодирования JSON ответа от {method}")
    return None

    # Функция для получения инвентаря аккаунта
    def get_inventory(api_key):
    """Получает инвентарь аккаунта с использованием API market.csgo.com."""
    return make_api_request(api_key, 'my-inventory')

    def get_bid_ask_price(api_key, market_hash_name, phase=None):
    """Получает актуальные цены bid-ask для предмета."""
    url = f"{API_BASE_URL}/bid-ask"
    params = {
    'key': api_key,
    'hash_name': market_hash_name
    }
    if phase:
    params['phase'] = phase

    try:
    response = requests.get(url, params=params)
    response.raise_for_status()
    data = response.json()

    # Получаем максимальную цену из bid
    if data.get('bid'):
    max_bid = max(float(bid['price']) for bid in data['bid'])
    return max_bid
    return None
    except Exception as e:
    logger.error(f"Ошибка при получении bid-ask цен: {e}")
    return None

    def store_inventory_in_db(api_key, inventory_data):
    """Сохраняет инвентарь в базу данных."""
    conn = create_connection()
    if conn is not None:
    try:
    cursor = conn.cursor()
    account_id = get_account_by_api_key(api_key)[0] # Получаем ID аккаунта

    # Очищаем старые записи для этого аккаунта
    cursor.execute("DELETE FROM inventory WHERE account_id = ?", (account_id,))

    for item in inventory_data.get('items', []):
    item_id = item.get('id')
    market_hash_name = item.get('market_hash_name')
    if item_id and market_hash_name:
    # Получаем актуальную цену через bid-ask
    current_price = get_bid_ask_price(api_key, market_hash_name)
    if current_price is None:
    current_price = item.get('market_price', 0) # Используем старую цену как запасной вариант

    cursor.execute(
    "INSERT INTO inventory (account_id, item_id, market_hash_name, market_price) VALUES (?, ?, ?, ?)",
    (account_id, item_id, market_hash_name, current_price)
    )

    conn.commit()
    logger.info(f"Инвентарь аккаунта {api_key} успешно сохранен в базе данных.")
    except Exception as e:
    logger.error(f"Ошибка при сохранении инвентаря в базу данных: {e}")
    finally:
    conn.close()

    # Функция для выставления предмета на продажу
    def add_to_sale(api_key, item_id, price, currency=DEFAULT_CURRENCY):
    """Выставляет предмет на продажу на market.csgo.com."""
    # Преобразуем цену в копейки (умножаем на 100 и убираем десятичную часть)
    price_in_cents = int(float(price) * 100)
    params = {'id': item_id, 'price': price_in_cents, 'cur': currency}
    logger.info(f"Выставление предмета {item_id} на продажу. Цена в копейках: {price_in_cents}")
    return make_api_request(api_key, 'add-to-sale', params)

    # Функция для получения баланса аккаунта
    def get_balance(api_key):
    """Получает баланс аккаунта."""
    return make_api_request(api_key, 'get-money')

    # Функция для перевода средств
    def transfer_money(api_key, payment_password, amount, user_api_key):
    """Переводит средства с аккаунта."""
    # Преобразуем сумму в копейки (умножаем на 100 и убираем десятичную часть)
    amount_in_cents = int(float(amount) * 100)
    url = f"{API_BASE_URL}/money-send/{amount_in_cents}/{user_api_key}?key={api_key}&pay_pass={payment_password}"
    try:
    response = requests.get(url) # Изменен метод на GET
    response.raise_for_status()
    return response.json()
    except requests.exceptions.RequestException as e:
    logger.error(f"Ошибка при выполнении запроса money-send: {e}")
    return None
    except json.JSONDecodeError:
    logger.error(f"Ошибка декодирования JSON ответа от money-send")
    return None

    # Функция для обновления инвентаря
    def update_inventory(api_key):
    """Запрашивает обновление кеша инвентаря."""
    return make_api_request(api_key, 'update-inventory')

    # Функция для пинга новых предметов
    def ping_new_items(api_key):
    """Отправляет POST запрос на ping-new endpoint."""
    return make_api_request(api_key, 'ping-new', use_post=True)

    # Функция для получения списка аккаунтов, привязанных к чату
    def get_chat_accounts(chat_id, user_id):
    """Получает список API-ключей аккаунтов, привязанных к чату для конкретного пользователя."""
    conn = create_connection()
    if conn is not None:
    try:
    cursor = conn.cursor()
    cursor.execute(
    "SELECT a.api_key FROM accounts a INNER JOIN chat_accounts ca ON a.id = ca.account_id WHERE ca.chat_id = ? AND ca.user_id = ?",
    (chat_id, user_id),
    )
    accounts = [row[0] for row in cursor.fetchall()]
    return accounts
    except Exception as e:
    logger.error(f"Ошибка при получении аккаунтов чата {chat_id}: {e}")
    return []
    finally:
    conn.close()
    else:
    logger.error("Не удалось подключиться к базе данных.")
    return []

    # Функция для привязки аккаунта к чату
    def add_account_to_chat(chat_id, api_key, user_id):
    """Привязывает аккаунт к чату для конкретного пользователя."""
    conn = create_connection()
    if conn is not None:
    try:
    cursor = conn.cursor()
    account_id = get_account_by_api_key(api_key)[0]
    cursor.execute(
    "INSERT INTO chat_accounts (chat_id, account_id, user_id) VALUES (?, ?, ?)",
    (chat_id, account_id, user_id),
    )
    conn.commit()
    logger.info(f"Аккаунт {api_key} привязан к чату {chat_id} для пользователя {user_id}.")
    return True
    except Exception as e:
    logger.error(f"Ошибка при привязке аккаунта к чату: {e}")
    return False
    finally:
    conn.close()
    else:
    logger.error("Не удалось подключиться к базе данных.")
    return False

    # Функция для отвязки аккаунта от чата
    def remove_account_from_chat(chat_id, api_key, user_id):
    """Отвязывает аккаунт от чата для конкретного пользователя."""
    conn = create_connection()
    if conn is not None:
    try:
    cursor = conn.cursor()
    account_id = get_account_by_api_key(api_key)[0]
    cursor.execute(
    "DELETE FROM chat_accounts WHERE chat_id = ? AND account_id = ? AND user_id = ?",
    (chat_id, account_id, user_id),
    )
    conn.commit()
    logger.info(f"Аккаунт {api_key} отвязан от чата {chat_id} для пользователя {user_id}.")
    return True
    except Exception as e:
    logger.error(f"Ошибка при отвязке аккаунта от чата: {e}")
    return False
    finally:
    conn.close()
    else:
    logger.error("Не удалось подключиться к базе данных.")
    return False

    # Функция для запуска пинга новых предметов для всех аккаунтов с auto_ping = 1
    def start_auto_ping(bot):
    """Запускает периодический пинг новых предметов для аккаунтов с auto_ping = 1."""
    def ping_loop():
    while True:
    accounts = get_all_accounts()
    for account in accounts:
    account_id, api_key, _, auto_ping, _ = account
    if auto_ping == 1:
    try:
    response = ping_new_items(api_key)
    if response:
    logger.info(f"Успешно отправлен ping-new для аккаунта {api_key}.")
    else:
    logger.warning(f"Не удалось отправить ping-new для аккаунта {api_key}.")
    except Exception as e:
    logger.error(f"Ошибка при выполнении ping-new для аккаунта {api_key}: {e}")
    time.sleep(180) # Интервал 3 минуты (180 секунд)

    # Запускаем пинг в отдельном потоке
    threading.Thread(target=ping_loop, daemon=True).start()

    def get_main_menu_keyboard():
    """Создает основную клавиатуру меню."""
    markup = types.InlineKeyboardMarkup(row_width=2)
    buttons = [
    types.InlineKeyboardButton("Добавить аккаунт", callback_data="add_account"),
    types.InlineKeyboardButton("Список аккаунтов", callback_data="list_accounts"),
    types.InlineKeyboardButton("Установить главный аккаунт", callback_data="set_main_account"),
    types.InlineKeyboardButton("Вывод средств", callback_data="show_balance"),
    types.InlineKeyboardButton("Выставить предметы", callback_data="add_to_sale"),
    types.InlineKeyboardButton("Обновить инвентарь", callback_data="update_inventory"),
    types.InlineKeyboardButton("Включить автоподнятие", callback_data="enable_ping"),
    types.InlineKeyboardButton("Выключить автоподнятие", callback_data="disable_ping"),
    types.InlineKeyboardButton("Удалить аккаунт", callback_data="delete_account")
    ]
    markup.add(*buttons)
    return markup

    def get_cancel_keyboard():
    """Создает инлайн клавиатуру с кнопкой отмены."""
    markup = types.InlineKeyboardMarkup()
    cancel_button = types.InlineKeyboardButton("Отменить", callback_data="cancel")
    delete_account_button = types.InlineKeyboardButton("Удалить аккаунт", callback_data="delete_account")
    markup.add(cancel_button, delete_account_button)
    return markup

    def handle_enable_auto_ping(message):
    """Обрабатывает включение автоподнятия для аккаунта."""
    global bot
    chat_id = message.chat.id
    api_key = message.text
    logger.info(f"Попытка включения автоподнятия для аккаунта {api_key}")

    # Проверяем существование аккаунта
    account = get_account_by_api_key(api_key)
    if not account:
    logger.warning(f"Аккаунт с API ключом {api_key} не найден")
    bot.send_message(chat_id, "Аккаунт с таким API-ключом не найден.")
    return

    # Обновляем настройки аккаунта
    if update_account_settings(api_key, auto_ping=1):
    logger.info(f"Автоподнятие успешно включено для аккаунта {api_key}")
    bot.send_message(chat_id, "Автоподнятие успешно включено.")
    else:
    logger.error(f"Не удалось включить автоподнятие для аккаунта {api_key}")
    bot.send_message(chat_id, "Не удалось включить автоподнятие.")

    def handle_update_inventory(message):
    """Обрабатывает запрос на обновление инвентаря."""
    global bot
    chat_id = message.chat.id
    api_key = message.text
    logger.info(f"Попытка обновления инвентаря для аккаунта {api_key}")

    # Проверяем существование аккаунта
    account = get_account_by_api_key(api_key)
    if not account:
    logger.warning(f"Аккаунт с API ключом {api_key} не найден")
    bot.send_message(chat_id, "Аккаунт с таким API-ключом не найден.")
    return

    # Обновляем инвентарь
    result = update_inventory(api_key)
    if result and result.get('success'):
    logger.info(f"Инвентарь успешно обновлен для аккаунта {api_key}")
    bot.send_message(chat_id, "Инвентарь успешно обновлен.")
    else:
    logger.error(f"Не удалось обновить инвентарь для аккаунта {api_key}")
    bot.send_message(chat_id, "Не удалось обновить инвентарь.")

    def handle_disable_auto_ping(message):
    """Обрабатывает выключение автоподнятия для аккаунта."""
    global bot
    chat_id = message.chat.id
    api_key = message.text
    logger.info(f"Попытка выключения автоподнятия для аккаунта {api_key}")

    # Проверяем существование аккаунта
    account = get_account_by_api_key(api_key)
    if not account:
    logger.warning(f"Аккаунт с API ключом {api_key} не найден")
    bot.send_message(chat_id, "Аккаунт с таким API-ключом не найден.")
    return

    # Обновляем настройки аккаунта
    if update_account_settings(api_key, auto_ping=0):
    logger.info(f"Автоподнятие успешно выключено для аккаунта {api_key}")
    bot.send_message(chat_id, "Автоподнятие успешно выключено.")
    else:
    logger.error(f"Не удалось выключить автоподнятие для аккаунта {api_key}")
    bot.send_message(chat_id, "Не удалось выключить автоподнятие.")

    def handle_bind_account(message):
    """Обрабатывает привязку аккаунта к чату."""
    global bot
    chat_id = message.chat.id
    user_id = message.from_user.id
    api_key = message.text
    logger.info(f"Попытка привязки аккаунта {api_key} к чату {chat_id}")

    # Проверяем существование аккаунта
    account = get_account_by_api_key(api_key)
    if not account:
    logger.warning(f"Аккаунт с API ключом {api_key} не найден")
    bot.send_message(chat_id, "Аккаунт с таким API-ключом не найден.")
    return

    # Привязываем аккаунт к чату
    if add_account_to_chat(chat_id, api_key, user_id):
    logger.info(f"Аккаунт {api_key} успешно привязан к чату {chat_id}")
    bot.send_message(chat_id, "Аккаунт успешно привязан к чату.")
    else:
    logger.error(f"Не удалось привязать аккаунт {api_key} к чату {chat_id}")
    bot.send_message(chat_id, "Не удалось привязать аккаунт к чату.")

    def handle_unbind_account(message):
    """Отвязывает аккаунт от чата."""
    chat_id = message.chat.id
    api_key = message.text
    if remove_account_from_chat(chat_id, api_key):
    bot.send_message(chat_id, "Аккаунт успешно отвязан от чата.")
    else:
    bot.send_message(chat_id, "Не удалось отвязать аккаунт от чата.")

    def handle_list_chat_accounts(message):
    """Выводит список аккаунтов, привязанных к чату."""
    chat_id = message.chat.id
    accounts = get_chat_accounts(chat_id)
    if accounts:
    message_text = "Аккаунты, привязанные к этому чату:\n"
    for api_key in accounts:
    message_text += f"- {api_key}\n"
    bot.send_message(chat_id, message_text)
    else:
    bot.send_message(chat_id, "К этому чату не привязаны аккаунты.")

    def handle_transfer_confirmation(message, account_balances):
    """Обрабатывает подтверждение перевода средств."""
    chat_id = message.chat.id
    user_id = message.from_user.id
    text = message.text
    if text == "Подтвердить":
    # Получаем главный аккаунт пользователя
    main_account = get_main_account(user_id)
    if not main_account:
    bot.send_message(chat_id, "Сначала установите главный аккаунт.")
    return

    main_api_key = main_account[1] # api_key is at index 1
    for api_key, balance in account_balances:
    if api_key != main_api_key: # Пропускаем главный аккаунт
    account = get_account_by_api_key(api_key)
    if account:
    payment_password = account[2]
    transfer_result = transfer_money(api_key, payment_password, balance, main_api_key)
    if transfer_result and transfer_result.get('success'):
    bot.send_message(chat_id, f"Средства ({balance} {DEFAULT_CURRENCY}) успешно переведены с аккаунта {api_key}.")
    else:
    bot.send_message(chat_id, f"Не удалось перевести средства с аккаунта {api_key}.")
    else:
    pyTelegramBotAPI>=4.14.0
    requests>=2.31.0

    используем Python 3.10
     
  2. PowerDevil
    PowerDevil 19 апр 2025 12 076 27 авг 2022

    Ну.. сомнительно но сойдет
     
    1. Посмотреть предыдущие комментарии (12)
    2. панан
      убежище, тебе интересно? Ну ладно, очень удивлен
  3. cedro
    cedro 19 апр 2025 A clear conscience is a soft pillow. 740 25 июн 2020
    Уж слишком много комментариев, пахнет злым роботом
     
    1. Посмотреть предыдущие комментарии (1)
    2. cedro
      убежище, не увидел)
      ну софт супер полезный для нужных людей :dance:
    3. убежище Автор темы
      cedro, с учетом того как маркет долго инвент обновляет если делать все руками - это еще и экономия времени в сотню раз
      19 апр 2025 Изменено
  4. fivfiv1338
    не полный код
     
Top