Помогите Нужна помощь по синхронизации сайта с сервером

sanekdark

Автор темы
16 Фев 2025
37
1
2
13
Добрый день может кто подсказать куда копать или мануал где почитать. по синхронизации сайта с сервером типа магазина и баланса с сайта в игру чтоб вводить. я так понимаю через API делать нужно если есть у кого опыт подскажите .
с Уважением sanekdark!
 
Решение
все сайт сделал посадил на движок ))) написал палагины для движка ))) все ок получилось не плохо )) зацените работу)) а еще палагин + к сайту с нуля написал)) магазин оформил так просто так как опыта в UI особо нет
да в принципе понял это нужно делать Палагин на сервере игровом RUST и там указывать API и создавать на сервера сайта обработку
Форматирование JSON ответов:
  • в products.php статус ответа, который указывает на успешное получение данных или ошибку, если товары не найдены.
  • В payment.phpпроверка на существование товара, и если товар не найден, возвращается соответствующее сообщение. типа сделать как на GS сторе палагин в связке с api. уже начал делать посмотрю получится нет))
типа на сайте api/products.php
Код:
<?php

header('Content-Type: application/json');



// Подключение к базе данных

require_once DIR . '/../app/config.php'; // Подключение к конфигурации базы данных

require_once '../app/db.php'; // Подключение к классу Database



// Создаем объект Database и получаем соединение

$database = new Database();

$pdo = $database->getConnection();



// Проверка, что $pdo был успешно инициализирован

if (!$pdo) {

    echo json_encode(["status" => "error", "message" => "Database connection not established"]);

    exit;

}



// Получение списка товаров

$stmt = $pdo->prepare("SELECT id, name, descr, image, price, created_at, category, server, discount, short_description FROM products");

$stmt->execute();

$products = $stmt->fetchAll(PDO::FETCH_ASSOC);



// Проверка, есть ли товары

if ($products) {

    echo json_encode(["status" => "success", "products" => $products]);

} else {

    echo json_encode(["status" => "error", "message" => "No products found"]);

}

?>
самое сложное это Палагин так как опыта с Палагинами нет, писать на С# но думаю изучу разберусь ) движок сайта для раст сервера в принципе уже реализовал почти . с нуля делал) теперь осталось интеграция система платижей и синхронизация магазина с сервером)))
 
вопрос может у кого есть

Telerik JustDecompile​

программка ? помогает вроде для разработки палагинов ) а то с палагином завис вроде написал api проходит все ключи все но не выводит магазин вот хочу разобраться)) если у кого-то есть программка эта, скиньте был бы благодарен)
 
просматривать oxid можно с помощью его 1740731616472.png
DnSpy/ILSpy.
Но VS 22, по умолчанию предоставляет декомпиляцию (как обычный переход к определению) и просмотр структуры (найти так же поля/классы как в dnspy и др)
 
  • Мне нравится
Реакции: sanekdark
DnSpy/ILSpy.
Но VS 22, по умолчанию предоставляет декомпиляцию (как обычный переход к определению) и просмотр структуры (найти так же поля/классы как в dnspy и др)
понял спасибо
 
добрый вечер написал Палагин вроде для своего сайта все проходит товар получает по api теперь? как оформить чтоб выводился магазин с этим товаром и команду выполнял открыл магазин вроде прописал вывод товаров но пишет не такой команды вот код. может кому-то пригодится. может кто подскажет куда дальше копать.

Код:
        #region Fields

        [PluginReference] private Plugin GameStoresWipeBlock = null;
        [PluginReference] private Plugin ImageLibrary = null;
        [PluginReference] private Plugin NoEscape = null;

        private Configuration _config;

        #endregion Fields

        #region Config

        private class Configuration
        {
            public APIConfiguration ApiConfig { get; set; } = new APIConfiguration();
            public PluginConfiguration PluginConfig { get; set; } = new PluginConfiguration();
        }

        private class APIConfiguration
        {
            public string StoreID { get; set; } = "";
            public string ServerID { get; set; } = "";
            public string SecretKey { get; set; } = "";
        }

        private class PluginConfiguration
        {
            public List CommandsToOpenStore { get; set; } = new List { "store", "bucket" };
            public bool EnableShowJoiningPlayers { get; set; } = false;
            public bool LoadDefaultImagesOverClient { get; set; } = true;
            public bool UseBuildingBlocked { get; set; } = false;
            public bool UseCombatBlocked { get; set; } = false;
            public bool UseRaidBlocked { get; set; } = false;
            public bool ExecuteInstantCommandsIfPlayerNotOnServer { get; set; } = true;
        }

        protected override void LoadDefaultConfig()
        {
            PrintWarning("Creating a new configuration file with default values.");
            _config = new Configuration();
            SaveConfig();
        }

        private void LoadPluginConfig()
        {
            try
            {
                string configFilePath = Path.Combine(Interface.Oxide.ConfigDirectory, "NSKRUST.json");

                if (File.Exists(configFilePath))
                {
                    var json = File.ReadAllText(configFilePath);
                    var configData = JsonConvert.DeserializeObject(json);

                    if (configData != null)
                    {
                        _config = configData;
                        Puts($"Config loaded successfully: StoreID={_config.ApiConfig.StoreID}, ServerID={_config.ApiConfig.ServerID}");
                    }
                    else
                    {
                        PrintError("Configuration file is missing essential parameters.");
                        LoadDefaultConfig();
                    }
                }
                else
                {
                    PrintError($"Configuration file not found at: {configFilePath}");
                    LoadDefaultConfig();
                }
            }
            catch (Exception ex)
            {
                PrintError("Error while reading config: " + ex.Message);
                LoadDefaultConfig();
            }
        }

        #endregion Config

       #region Initialization

private void Init()
{
    LoadPluginConfig();

    CoroutineHandler.Instance.StartCoroutine(AuthenticateApi(_config.ApiConfig.SecretKey, (success) =>
    {
        if (!success)
        {
            PrintError("Failed to initialize API settings. Please check your configuration.");
            return;
        }

        FetchProducts();
    }));
}

#endregion Initialization

#region Fetch Products

private void FetchProducts()
{
    CoroutineHandler.Instance.StartCoroutine(GetProductsCoroutine());
}

private IEnumerator GetProductsCoroutine()
{
    if (_config == null || _config.ApiConfig == null)
    {
        PrintError("Configuration is not set properly. Please check _config and ApiConfig.");
        yield break;
    }

    string url = $"https://site.ru/api/products.php?storeId={_config.ApiConfig.StoreID}&serverId={_config.ApiConfig.ServerID}";

    using (var request = UnityWebRequest.Get(url)) // Используем UnityWebRequest.Get
    {
        request.SetRequestHeader("User-Agent", "GameStores Plugin");
        request.timeout = 30; // Увеличиваем тайм-аут
        PrintWarning("Sending request to fetch products...");
        yield return request.SendWebRequest();
        PrintWarning("Received response from product request.");

        // Логируем результат запроса
        PrintWarning($"Request result: {request.result}");
        PrintWarning($"Request error: {request.error}");
        PrintWarning($"Response code: {request.responseCode}");

        // Проверяем код ответа
        if (request.responseCode != 200)
        {
            PrintError($"Unexpected response code: {request.responseCode}");
            yield break;
        }

        // Проверяем, инициализирован ли downloadHandler
        if (request.downloadHandler == null)
        {
            PrintError("Download handler is null. Failed to fetch response.");
            yield break;
        }

        // Проверяем, что ответ не пустой
        string jsonResponse = request.downloadHandler.text;
        if (string.IsNullOrEmpty(jsonResponse))
        {
            PrintError("Response is empty or null.");
            yield break;
        }
        PrintWarning($"Raw JSON Response: {jsonResponse}");

        try
        {
            var response = JsonConvert.DeserializeObject(jsonResponse);
            if (response == null)
            {
                PrintError("Failed to deserialize JSON response.");
                yield break;
            }

            if (response.Status != "success")
            {
                PrintError("Error in response: " + response.Message);
                yield break;
            }

            if (response.Products == null)
            {
                PrintError("Products field is null in the response.");
                yield break;
            }

            PrintWarning($"Products field found with count: {response.Count}");
            List products = new List();

            foreach (var product in response.Products)
            {
                if (product == null)
                {
                    PrintError("Product item is null. Skipping...");
                    continue;
                }

                if (product.Price <= 0)
                {
                    PrintError($"Invalid price for product: {product.Name}. Skipping...");
                    continue;
                }

                if (string.IsNullOrEmpty(product.Name))
                {
                    PrintError("Product has null or empty name. Skipping...");
                    continue;
                }

                products.Add(product);
                PrintWarning($"Product added: {product.Name}, Price: {product.Price}, Description: {product.Descr}");
            }

            PrintWarning($"Number of products successfully added: {products.Count}");
        }
        catch (JsonException jsonEx)
        {
            PrintError($"JSON deserialization error: {jsonEx.Message}. Response: {jsonResponse}");
        }
        catch (Exception ex)
        {
            PrintError($"Exception during processing: {ex.Message}");
        }
    }
}

// Модель ответа API
public class ApiResponse
{
    public string Status { get; set; }
    public List Products { get; set; }
    public int Count { get; set; }
    public string Message { get; set; }
}

// Модель продукта
public class Product
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Descr { get; set; }
    public string Image { get; set; }
    public decimal Price { get; set; } // Оставляем как decimal
    public string CreatedAt { get; set; }
    public string Category { get; set; }
    public string Server { get; set; }
    public int Discount { get; set; }
    public string ShortDescription { get; set; }
}
        #endregion Product Model

        #region API Initialization and Authentication

private IEnumerator AuthenticateApi(string secretKey, Action callback)
{
    using (var request = new UnityWebRequest("https://site.ru/api/authenticate.php", "POST"))
    {
        // Создание тела запроса с секретным ключом
        var requestBody = JsonConvert.SerializeObject(new { secret = secretKey });
        byte[] bodyRaw = System.Text.Encoding.UTF8.GetBytes(requestBody);
        request.uploadHandler = new UploadHandlerRaw(bodyRaw);
        request.downloadHandler = new DownloadHandlerBuffer();
        request.SetRequestHeader("Content-Type", "application/json");
        request.SetRequestHeader("User-Agent", "GameStores Plugin");

        request.timeout = 10; // Установите тайм-аут в 10 секунд

        PrintError("Sending authentication request...");

        // Отправляем запрос и ждем завершения
        yield return SendRequest(request, callback);
    }
}

private IEnumerator SendRequest(UnityWebRequest request, Action callback)
{
    yield return request.SendWebRequest(); // Ждем завершения запроса

    // Проверка результата запроса
    if (request.result != UnityWebRequest.Result.Success)
    {
        PrintError("API Authentication failed: " + request.error, "ERROR");
        callback(false);
        yield break; // Выход из корутины
    }

    var jsonResponse = request.downloadHandler.text;
    var response = JsonConvert.DeserializeObject>(jsonResponse);

    PrintError("Response: " + jsonResponse);

    if (response.TryGetValue("status", out var status) && status.ToString() == "success")
    {
        PrintError("API Authentication successful.");
        callback(true);
    }
    else
    {
        PrintError("API Authentication failed: " + response["message"], "ERROR");
        callback(false);
    }
}
        #endregion API Initialization and Authentication

        #region Commands

        [Command("storesrust")]
        private void CmdStoreRUST(IPlayer player, string command, string[] args)
        {
            if (!player.IsAdmin)
            {
                player.Reply("У вас нет прав на использование этой команды.");
                return;
            }

            string pluginInfo = "Плагин StoresRUST v1.0.0\n" +
                                "Команды:\n" +
                                "/storesnskrust fetch - Получить список товаров\n" +
                                "/storesnskrust purchase - Купить товар по ID\n";

            if (args.Length == 0)
            {
                player.Reply(pluginInfo);
                return;
            }

            switch (args[0].ToLower())
            {
                case "fetch":
                    FetchProducts();
                    player.Reply("Список товаров запрошен. Проверьте консоль для вывода.");
                    break;

                case "purchase":
                    if (args.Length < 2 || !int.TryParse(args[1], out int productId))
                    {
                        player.Reply("Использование: /storesrust purchase ");
                        return;
                    }

                    // Вызываем метод для покупки товара
                    CoroutineHandler.Instance.StartCoroutine(PurchaseProduct(productId, success =>
                    {
                        if (success)
                        {
                            player.Reply("Покупка прошла успешно!");
                        }
                        else
                        {
                            player.Reply("Произошла ошибка при покупке товара.");
                        }
                    }));
                    break;

                default:
                    player.Reply(pluginInfo);
                    break;
            }
        }

        #endregion Commands

        #region Purchase Product

        private IEnumerator PurchaseProduct(int productId, Action callback)
        {
            string url = $"https://site.ru/api/purchase.php?productId={productId}&storeId={_config.ApiConfig.StoreID}&serverId={_config.ApiConfig.ServerID}";

            using (var request = new UnityWebRequest(url, UnityWebRequest.kHttpVerbPOST))
            {
                request.SetRequestHeader("User-Agent", "GameStores Plugin");
                request.timeout = 10;

                yield return request.SendWebRequest();

                if (request.result != UnityWebRequest.Result.Success)
                {
                    PrintError("Error while purchasing product: " + request.error);
                    callback(false);
                    yield break; // Выход из корутины
                }

                var jsonResponse = request.downloadHandler.text;
                var response = JsonConvert.DeserializeObject>(jsonResponse);

                if (response.TryGetValue("status", out var status) && status.ToString() == "success")
                {
                    callback(true); // Покупка успешна
                }
                else
                {
                    PrintError("Purchase failed: " + response["message"]);
                    callback(false); // Ошибка при покупке
                }
            }
        }

        #endregion Purchase Product
    }

    // Класс для управления корутинами
    public class CoroutineHandler : MonoBehaviour
    {
        private static CoroutineHandler _instance;

        public static CoroutineHandler Instance
        {
            get
            {
                if (_instance == null)
                {
                    GameObject obj = new GameObject("CoroutineHandler");
                    _instance = obj.AddComponent();
                    UnityEngine.Object.DontDestroyOnLoad(obj);
                }
                return _instance;
            }
        }
    }
}
 
добрый день всем! вроде разобрался сделал палагин чтоб через api работал сайтом моим и выводит товары и баланс. сегодня буду разбираться теперь с покупкой и выдачей думаю за пару дней разберусь )) осталось еще дизайн магазина палагина оформить через GUI изучу думаю сделаю ))) а то все в первый раз делаю)
 
Добрый день ! нужен совет по Палагину ! 1)добился по APi загрузка товара и выводит как магазин товара и баланс сайта в игре но проблема щас стала покупки и выдачи items и привилегий вип например. может у кого есть опыт кто хоть подсказать может . я уже в базе данных товара в таблицу добавил comand думаю щас как-то может при покупки чтоб выполнялась это команда типа выдачи випки или итемс . но чет пока не могу понять как . может есть кто сталкивался с этим и подсказать может или ману где курнуть)) по этой теме))
 
все разобрался сам! сделал все сайт+ палагин с магазином работает по api . движок сайта с нуля писал)) и палагин тоже. единственое осталось ссайта на сервер игры еще реализовать когда покупают на сайте чтоб в игру отправлялись данные. щас работает уменя в игре пополняю на сайте по апи выводит все))
1742594805366.webp
как то так магазин сайт сам вот дизайн еще думаю сменить надо
1742594862076.webp
строго не судите)) первый раз делал вникал))) вопрос еще может ктото подскажет как на сервере раст api сделать чтоб принимал запрос ссайта . может опыт есть?
 
в принципе все сделал обошелся без API ))) все тему можно закрыть) если кому-то интересно будет могу в принципе даже и продать сайт+ Палагин)) если цену норм предложите))
 
все сайт сделал посадил на движок ))) написал палагины для движка ))) все ок получилось не плохо )) зацените работу)) а еще палагин + к сайту с нуля написал)) магазин оформил так просто так как опыта в UI особо нет
 

Вложения

  • Снимок экрана_29-3-2025_181028_nskrust.ru.webp
    Снимок экрана_29-3-2025_181028_nskrust.ru.webp
    77.9 KB · Просмотры: 17
  • Снимок экрана_29-3-2025_181119_nskrust.ru.webp
    Снимок экрана_29-3-2025_181119_nskrust.ru.webp
    105.6 KB · Просмотры: 15
  • Снимок экрана_29-3-2025_181150_nskrust.ru.webp
    Снимок экрана_29-3-2025_181150_nskrust.ru.webp
    62.8 KB · Просмотры: 14
  • Без имени-2.webp
    Без имени-2.webp
    160.7 KB · Просмотры: 10

Похожие темы