Иконка ресурса

FREE ImageAPI : 1.1.0 1.1.0

Нет прав для скачивания
C#:
using Oxide.Core;
using Oxide.Core.Plugins;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text.RegularExpressions;
using UnityEngine;

namespace Oxide.Plugins
{
    [Info("ImageAPI", "15FPS", "1.1.0")]
    [Description("Автоматическая загрузка и автообновление изображений / Automatic image download and auto-update")]
    public class ImageAPI : RustPlugin
    {
        private ImagesCache _imagesCache;

        private void OnServerInitialized()
        {
            _imagesCache = new GameObject("ImagesCache").AddComponent<ImagesCache>();
            UnityEngine.Object.DontDestroyOnLoad(_imagesCache);

            _imagesCache.LoadAllFromData();

            _imagesCache.StartWatching();
            DownloadAllImagesFromPage(SourceUrl);

            Puts("[ImageAPI] Инициализирован. Автообновление изображений включено. / Initialized. Auto image update enabled.");
        }

        private void Unload()
        {
            if (_imagesCache != null)
            {
                _imagesCache.StopWatching();
                UnityEngine.Object.Destroy(_imagesCache.gameObject);
            }
        }

        #region API

        [HookMethod("AddImage")]
        public void AddImage(string name, string path) => _imagesCache.Add(name, path);

        [HookMethod("GetImage")]
        public string GetImage(string name) => _imagesCache.Get(name);

        [HookMethod("RemoveImage")]
        public void RemoveImage(string name) => _imagesCache.Remove(name);

        #endregion

        public class ImagesCache : MonoBehaviour
        {
            private Dictionary<string, string> _images = new Dictionary<string, string>();
            private FileSystemWatcher _watcher;
            private readonly string _basePath = Path.Combine(Interface.Oxide.DataDirectory, "15FPS", "ImageAPI");

            public void Add(string name, string url)
            {
                if (_images.ContainsKey(name))
                    return;

                using (var www = new WWW(url))
                {
                    if (!string.IsNullOrEmpty(www.error))
                    {
                        print($"Image loading fail! Error: {www.error} / Ошибка загрузки изображения: {www.error}");
                        return;
                    }

                    if (www.bytes == null || www.bytes.Length == 0)
                    {
                        Interface.Oxide.LogError($"Failed to add image for {name}. File address possibly invalid / Не удалось добавить изображение {name}, возможно неправильный путь\n {url}");
                        return;
                    }

                    _images[name] = FileStorage.server.Store(www.bytes, FileStorage.Type.png, CommunityEntity.ServerInstance.net.ID).ToString();
                }
            }

            public string Get(string name)
            {
                if (_images.TryGetValue(name, out var id))
                    return id;
                return string.Empty;
            }

            public void Remove(string name)
            {
                if (_images.Remove(name))
                    Interface.Oxide.LogInfo($"[ImagesCache] Удалено изображение: {name} / Removed image: {name}");
            }

            public void LoadAllFromData()
            {
                if (!Directory.Exists(_basePath))
                    Directory.CreateDirectory(_basePath);

                foreach (string file in Directory.GetFiles(_basePath, "*.*", SearchOption.AllDirectories))
                {
                    if (!IsImageFile(file)) continue;
                    string relativePath = file.Substring(_basePath.Length + 1).Replace("\\", "/");
                    Add(relativePath, file);
                }

                Interface.Oxide.LogInfo($"[ImagesCache] Автозагрузка завершена. Загружено {_images.Count} изображений. / Auto-loading completed. {_images.Count} images loaded.");
            }

            public void StartWatching()
            {
                _watcher = new FileSystemWatcher(_basePath)
                {
                    IncludeSubdirectories = true,
                    EnableRaisingEvents = true,
                    NotifyFilter = NotifyFilters.FileName | NotifyFilters.LastWrite | NotifyFilters.Size
                };

                _watcher.Created += OnFileChanged;
                _watcher.Changed += OnFileChanged;
                _watcher.Deleted += OnFileDeleted;
                _watcher.Renamed += OnFileRenamed;

                Interface.Oxide.LogInfo("[ImagesCache] FileSystemWatcher запущен для автообновления изображений. / FileSystemWatcher started for auto image updates.");
            }

            public void StopWatching()
            {
                if (_watcher != null)
                {
                    _watcher.EnableRaisingEvents = false;
                    _watcher.Dispose();
                    _watcher = null;
                }
            }

            private void OnFileChanged(object sender, FileSystemEventArgs e)
            {
                if (!IsImageFile(e.FullPath)) return;
                string relative = e.FullPath.Substring(_basePath.Length + 1).Replace("\\", "/");
                Interface.Oxide.NextTick(() =>
                {
                    Add(relative, e.FullPath);
                    Interface.Oxide.LogInfo($"[ImagesCache] Обновлено изображение: {relative} / Image updated: {relative}");
                });
            }

            private void OnFileDeleted(object sender, FileSystemEventArgs e)
            {
                string relative = e.FullPath.Substring(_basePath.Length + 1).Replace("\\", "/");
                _images.Remove(relative);
                Interface.Oxide.LogInfo($"[ImagesCache] Удалено изображение: {relative} / Image removed: {relative}");
            }

            private void OnFileRenamed(object sender, RenamedEventArgs e)
            {
                string oldRel = e.OldFullPath.Substring(_basePath.Length + 1).Replace("\\", "/");
                string newRel = e.FullPath.Substring(_basePath.Length + 1).Replace("\\", "/");

                _images.Remove(oldRel);
                if (IsImageFile(e.FullPath))
                    Add(newRel, e.FullPath);
            }

            private static bool IsImageFile(string path)
            {
                string ext = Path.GetExtension(path)?.ToLower();
                return ext == ".png" || ext == ".jpg" || ext == ".jpeg";
            }
        }

        private const string SourceUrl = "https://15fps.top/gallery/";

        private static readonly string SavePath =
            Path.Combine(Interface.Oxide.DataDirectory, "15FPS", "ImageAPI/image");

        private void DownloadAllImagesFromPage(string pageUrl)
        {
            try
            {
                if (!Directory.Exists(SavePath))
                    Directory.CreateDirectory(SavePath);

                using (WebClient wc = new WebClient())
                {
                    Puts($"[AutoImageDownloader] Загружаю HTML: {pageUrl} / Loading HTML: {pageUrl}");
                    string html = wc.DownloadString(pageUrl);

                    var matches = Regex.Matches(
                        html,
                        @"src=['""]([^'""]+\.(png|jpg|jpeg|gif))",
                        RegexOptions.IgnoreCase
                    );

                    if (matches.Count == 0)
                    {
                        Puts("[AutoImageDownloader] На странице нет изображений. / No images found on the page.");
                        return;
                    }

                    Uri baseUri = new Uri(pageUrl);

                    int index = 0;
                    int downloaded = 0;
                    int skipped = 0;

                    foreach (Match m in matches)
                    {
                        string imgUrl = m.Groups[1].Value;

                        if (!imgUrl.StartsWith("http"))
                            imgUrl = new Uri(baseUri, imgUrl).ToString();

                        string fileName = Path.GetFileName(imgUrl);
                        if (string.IsNullOrEmpty(fileName))
                            fileName = $"image_{index}.png";

                        string filePath = Path.Combine(SavePath, fileName);

                        if (File.Exists(filePath))
                        {
                            Puts($"[AutoImageDownloader] Уже существует → {fileName}, пропускаю / Already exists → {fileName}, skipping");
                            skipped++;
                        }
                        else
                        {
                            try
                            {
                                Puts($"[AutoImageDownloader] Скачиваю: {imgUrl} / Downloading: {imgUrl}");
                                wc.DownloadFile(imgUrl, filePath);
                                downloaded++;
                            }
                            catch (Exception ex)
                            {
                                Puts($"[AutoImageDownloader] Ошибка загрузки {imgUrl}: {ex.Message} / Error downloading {imgUrl}: {ex.Message}");
                            }
                        }

                        index++;
                    }

                    Puts($"[AutoImageDownloader] Готово. Новых: {downloaded}, пропущено: {skipped} / Done. New: {downloaded}, skipped: {skipped}");
                }
            }
            catch (Exception ex)
            {
                Puts($"[AutoImageDownloader] Ошибка: {ex.Message} / Error: {ex.Message}");
            }
        }
    }
}

Автор
15FPS
Скачиваний
0
Просмотры
1
Первый выпуск
Обновление
Оценка
0.00 звёзд 0 оценок
Сверху