#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;
}
}
}
}