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

FREE DailyRewards : 1.0.0 1.0.0

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

namespace Oxide.Plugins
{
    [Info("Daily Rewards", "0killrest", "1.0.0")]
    [Description("Daily login rewards with UI and streak system")]
    internal class DailyRewards : RustPlugin
    {
        #region Configuration
        private static ConfigData config;
        
        private class ConfigData
        {
            public bool Enabled { get; set; } = true;
            public bool AutoOpenUIOnJoin { get; set; } = true;
            public string UIButtonColor { get; set; } = "#00ff00";
            public string UIBackgroundColor { get; set; } = "#1a1a1a";
            public List<RewardDay> Rewards { get; set; }

            public ConfigData()
            {
                Rewards = new List<RewardDay>
                {
                    new RewardDay { Day = 1, Items = new List<RewardItem> { new RewardItem { ShortName = "scrap", Amount = 50, Icon = "https://i.imgur.com/3Zv5q8u.png" } }, Title = "Day 1", Description = "Welcome reward!" },
                    new RewardDay { Day = 2, Items = new List<RewardItem> { new RewardItem { ShortName = "scrap", Amount = 75, Icon = "https://i.imgur.com/3Zv5q8u.png" } }, Title = "Day 2", Description = "Keep going!" },
                    new RewardDay { Day = 3, Items = new List<RewardItem> { new RewardItem { ShortName = "metal.refined", Amount = 100, Icon = "https://i.imgur.com/7X5G3Zc.png" } }, Title = "Day 3", Description = "Good streak!" },
                    new RewardDay { Day = 4, Items = new List<RewardItem> { new RewardItem { ShortName = "scrap", Amount = 100, Icon = "https://i.imgur.com/3Zv5q8u.png" } }, Title = "Day 4", Description = "Almost there!" },
                    new RewardDay { Day = 5, Items = new List<RewardItem> { new RewardItem { ShortName = "ammo.rifle", Amount = 50, Icon = "https://i.imgur.com/YlRvM8c.png" } }, Title = "Day 5", Description = "Half way!" },
                    new RewardDay { Day = 6, Items = new List<RewardItem> { new RewardItem { ShortName = "scrap", Amount = 150, Icon = "https://i.imgur.com/3Zv5q8u.png" } }, Title = "Day 6", Description = "Almost max!" },
                    new RewardDay { Day = 7, Items = new List<RewardItem> { new RewardItem { ShortName = "rifle.ak", Amount = 1, Icon = "https://i.imgur.com/tUQpZ7W.png" } }, Title = "Day 7", Description = "JACKPOT! Full week!" }
                };
            }
        }
        
        public class RewardDay
        {
            public int Day { get; set; }
            public string Title { get; set; }
            public string Description { get; set; }
            public List<RewardItem> Items { get; set; }
        }
        
        public class RewardItem
        {
            public string ShortName { get; set; }
            public int Amount { get; set; }
            public string Icon { get; set; }
        }
        
        protected override void LoadConfig()
        {
            base.LoadConfig();
            config = Config.ReadObject<ConfigData>();
            if (config == null)
            {
                LoadDefaultConfig();
            }
        }
        
        protected override void LoadDefaultConfig()
        {
            config = new ConfigData();
            PrintWarning("Default configuration created.Edit it in oxide/config/DailyRewards.json");
            SaveConfig();
        }
        
        protected override void SaveConfig() => Config.WriteObject(config);
        #endregion

        #region Data Storage
        private Dictionary<ulong, PlayerRewardData> playerData;
        
        private class PlayerRewardData
        {
            public int CurrentStreak { get; set; } = 0;
            public int LastClaimDay { get; set; } = 0;
            public DateTime LastClaimDate { get; set; }
            public List<int> ClaimedDays { get; set; } = new List<int>();
            public bool HasClaimedToday { get; set; } = false;
        }
        
        private void LoadData()
        {
            playerData = Interface.Oxide.DataFileSystem.ReadObject<Dictionary<ulong, PlayerRewardData>>("DailyRewards_Data") ?? new Dictionary<ulong, PlayerRewardData>();
        }
        
        private void SaveData()
        {
            Interface.Oxide.DataFileSystem.WriteObject("DailyRewards_Data", playerData);
        }
        #endregion

        #region Hooks
        private void Init()
        {
            LoadData();
            permission.RegisterPermission("dailyrewards.admin", this);
        }
        
        private void OnServerSave() => SaveData();
        private void Unload() => SaveData();
        
        private void OnPlayerInit(BasePlayer player)
        {
            if (!config.Enabled) return;
            
            // Check if player can claim reward
            CheckAndNotifyPlayer(player);
            
            if (config.AutoOpenUIOnJoin)
            {
                // Small delay to let player fully load
                timer.Once(2f, () => ShowRewardUI(player));
            }
        }
        
        private void CheckAndNotifyPlayer(BasePlayer player)
        {
            var data = GetPlayerData(player.userID);
            bool canClaim = CanClaimReward(player);
            
            if (canClaim && !data.HasClaimedToday)
            {
                SendReply(player, $"<color=green>🎁 Daily reward available! Type <color=yellow>/daily</color> to claim!</color>");
                
                // Send notification icon
                player.SendConsoleCommand("gametip.show_tip", "Daily reward available! Type /daily", 5);
            }
        }
        
        private bool CanClaimReward(BasePlayer player)
        {
            var data = GetPlayerData(player.userID);
            
            // First time ever
            if (data.LastClaimDate == DateTime.MinValue)
                return true;
            
            // Check if already claimed today
            if (data.HasClaimedToday)
                return false;
            
            // Check if next day
            TimeSpan difference = DateTime.UtcNow - data.LastClaimDate;
            if (difference.TotalHours >= 20) // Allow 20-24 hour window
            {
                // Reset streak if more than 48 hours passed
                if (difference.TotalHours > 48)
                {
                    data.CurrentStreak = 0;
                    data.ClaimedDays.Clear();
                    SaveData();
                }
                return true;
            }
            
            return false;
        }
        
        private PlayerRewardData GetPlayerData(ulong userId)
        {
            if (!playerData.ContainsKey(userId))
            {
                playerData[userId] = new PlayerRewardData
                {
                    CurrentStreak = 0,
                    LastClaimDate = DateTime.MinValue,
                    ClaimedDays = new List<int>(),
                    HasClaimedToday = false
                };
                SaveData();
            }
            return playerData[userId];
        }
        #endregion

        #region UI System
        private void ShowRewardUI(BasePlayer player)
        {
            var data = GetPlayerData(player.userID);
            int nextDay = Math.Min(data.CurrentStreak + 1, config.Rewards.Count);
            var nextReward = config.Rewards.FirstOrDefault(r => r.Day == nextDay);
            
            if (nextReward == null) return;
            
            bool canClaim = CanClaimReward(player);
            
            // Build UI
            CuiHelper.DestroyUi(player, "DailyRewardsUI");
            
            CuiElementContainer container = new CuiElementContainer();
            
            // Main panel background
            string mainPanel = container.Add(new CuiPanel
            {
                Image = { Color = "0 0 0 0.95" },
                RectTransform = { AnchorMin = "0.25 0.3", AnchorMax = "0.75 0.7" },
                CursorEnabled = true
            }, "Overlay", "DailyRewardsUI");
            
            // Title bar
            string titleBar = container.Add(new CuiPanel
            {
                Image = { Color = HexToRGBA(config.UIButtonColor, 0.8f) },
                RectTransform = { AnchorMin = "0 0.85", AnchorMax = "1 1" }
            }, mainPanel);
            
            container.Add(new CuiText
            {
                Text = { Text = "🎁 DAILY REWARD", FontSize = 24, Align = TextAnchor.MiddleCenter, Color = "1 1 1 1" },
                RectTransform = { AnchorMin = "0 0", AnchorMax = "1 1" }
            }, titleBar);
            
            // Close button
            string closeBtn = container.Add(new CuiButton
            {
                Button = { Color = "1 0.2 0.2 0.8", Command = "dailyreward.close" },
                RectTransform = { AnchorMin = "0.92 0.86", AnchorMax = "0.98 0.98" },
                Text = { Text = "✖", FontSize = 18, Align = TextAnchor.MiddleCenter, Color = "1 1 1 1" }
            }, mainPanel);
            
            // Day info
            string dayText = canClaim ? $"Day {nextDay} - Ready to claim!" : $"Day {nextDay} - Already claimed today";
            string dayColor = canClaim ? "0 1 0 1" : "1 1 0 1";
            
            container.Add(new CuiText
            {
                Text = { Text = dayText, FontSize = 20, Align = TextAnchor.MiddleCenter, Color = dayColor },
                RectTransform = { AnchorMin = "0 0.7", AnchorMax = "1 0.85" }
            }, mainPanel);
            
            container.Add(new CuiText
            {
                Text = { Text = nextReward.Description, FontSize = 14, Align = TextAnchor.MiddleCenter, Color = "0.8 0.8 0.8 1" },
                RectTransform = { AnchorMin = "0 0.6", AnchorMax = "1 0.7" }
            }, mainPanel);
            
            // Streak info
            container.Add(new CuiText
            {
                Text = { Text = $"🔥 Current streak: {data.CurrentStreak} days", FontSize = 14, Align = TextAnchor.MiddleCenter, Color = "1 0.6 0 1" },
                RectTransform = { AnchorMin = "0 0.52", AnchorMax = "1 0.6" }
            }, mainPanel);
            
            // Rewards list
            float startY = 0.35f;
            float itemHeight = 0.12f;
            
            for (int i = 0; i < nextReward.Items.Count; i++)
            {
                var item = nextReward.Items[i];
                float yPos = startY - (i * itemHeight);
                
                string itemPanel = container.Add(new CuiPanel
                {
                    Image = { Color = HexToRGBA(config.UIBackgroundColor, 0.8f) },
                    RectTransform = { AnchorMin = $"0.1 {yPos}", AnchorMax = $"0.9 {yPos + itemHeight - 0.01f}" }
                }, mainPanel);
                
                // Item icon
                container.Add(new CuiElement
                {
                    Parent = itemPanel,
                    Components = {
                        new CuiRawImageComponent { Png = GetItemIcon(item.ShortName), Color = "1 1 1 1" },
                        new CuiRectTransformComponent { AnchorMin = "0.02 0.1", AnchorMax = "0.2 0.9" }
                    }
                });
                
                // Item name and amount
                string displayName = GetItemDisplayName(item.ShortName);
                container.Add(new CuiText
                {
                    Text = { Text = $"{displayName} x{item.Amount}", FontSize = 16, Align = TextAnchor.MiddleLeft, Color = "1 1 1 1" },
                    RectTransform = { AnchorMin = "0.22 0", AnchorMax = "0.8 1" }
                }, itemPanel);
            }
            
            // Claim button
            if (canClaim)
            {
                string claimBtn = container.Add(new CuiButton
                {
                    Button = { Color = HexToRGBA(config.UIButtonColor, 0.9f), Command = "dailyreward.claim" },
                    RectTransform = { AnchorMin = "0.3 0.05", AnchorMax = "0.7 0.2" },
                    Text = { Text = "🎁 CLAIM REWARD", FontSize = 18, Align = TextAnchor.MiddleCenter, Color = "1 1 1 1" }
                }, mainPanel);
            }
            else
            {
                container.Add(new CuiText
                {
                    Text = { Text = "⏰ Already claimed today! Come back tomorrow.", FontSize = 14, Align = TextAnchor.MiddleCenter, Color = "1 0.5 0 1" },
                    RectTransform = { AnchorMin = "0.2 0.05", AnchorMax = "0.8 0.2" }
                }, mainPanel);
            }
            
            CuiHelper.AddUi(player, container);
        }
        
        private string HexToRGBA(string hex, float alpha = 1f)
        {
            if (string.IsNullOrEmpty(hex)) hex = "#ffffff";
            hex = hex.TrimStart('#');
            float r = int.Parse(hex.Substring(0, 2), System.Globalization.NumberStyles.HexNumber) / 255f;
            float g = int.Parse(hex.Substring(2, 2), System.Globalization.NumberStyles.HexNumber) / 255f;
            float b = int.Parse(hex.Substring(4, 2), System.Globalization.NumberStyles.HexNumber) / 255f;
            return $"{r} {g} {b} {alpha}";
        }
        
        private string GetItemIcon(string shortName)
        {
            // Return icon URL for item
            return $"https://rust.wiki/images/thumb/{shortName}.png/64px-{shortName}.png";
        }
        
        private string GetItemDisplayName(string shortName)
        {
            var itemDef = ItemManager.FindItemDefinition(shortName);
            return itemDef != null ? itemDef.displayName.english : shortName;
        }
        #endregion

        #region Core Logic
        private void ClaimReward(BasePlayer player)
        {
            var data = GetPlayerData(player.userID);
            
            if (!CanClaimReward(player))
            {
                SendReply(player, "<color=red>You already claimed your daily reward today!</color>");
                ShowRewardUI(player);
                return;
            }
            
            int nextDay = data.CurrentStreak + 1;
            if (nextDay > config.Rewards.Count)
            {
                // Max streak reached, either stop or loop
                SendReply(player, "<color=yellow>You've claimed all rewards! Starting over!</color>");
                data.CurrentStreak = 0;
                data.ClaimedDays.Clear();
                nextDay = 1;
            }
            
            var reward = config.Rewards.FirstOrDefault(r => r.Day == nextDay);
            if (reward == null)
            {
                PrintError($"No reward found for day {nextDay}");
                return;
            }
            
            // Give items
            foreach (var itemReward in reward.Items)
            {
                ItemDefinition itemDef = ItemManager.FindItemDefinition(itemReward.ShortName);
                if (itemDef != null)
                {
                    Item item = ItemManager.Create(itemDef, itemReward.Amount);
                    if (item != null)
                    {
                        player.inventory.GiveItem(item);
                    }
                }
            }
            
            // Update data
            data.CurrentStreak = nextDay;
            data.LastClaimDate = DateTime.UtcNow;
            data.HasClaimedToday = true;
            if (!data.ClaimedDays.Contains(nextDay))
                data.ClaimedDays.Add(nextDay);
            
            SaveData();
            
            // Effects
            Effect.server.Run("assets/prefabs/locks/keylock/effects/lock.code.updated.prefab", player.transform.position, Vector3.zero);
            
            // Success message
            SendReply(player, $"<color=green>🎉 You claimed Day {nextDay} reward! 🎉</color>");
            SendReply(player, $"<color=yellow>🔥 Streak: {data.CurrentStreak} days! Come back tomorrow for more!</color>");
            
            // Close UI and reopen to show next day
            CuiHelper.DestroyUi(player, "DailyRewardsUI");
            timer.Once(1f, () => ShowRewardUI(player));
            
            // Announce to server on big milestones
            if (nextDay == 7 || nextDay == 14 || nextDay == 21 || nextDay == 30)
            {
                Server.Broadcast($"<color=orange>🌟 {player.displayName} reached a {nextDay}-day login streak! 🌟</color>");
            }
        }
        #endregion

        #region Commands
        [ChatCommand("daily")]
        private void cmdDaily(BasePlayer player, string command, string[] args)
        {
            if (args.Length > 0 && args[0].ToLower() == "claim")
            {
                ClaimReward(player);
            }
            else
            {
                ShowRewardUI(player);
            }
        }
        
        [ChatCommand("dailyreset")]
        private void cmdResetStreak(BasePlayer player, string command, string[] args)
        {
            if (!permission.UserHasPermission(player.UserIDString, "dailyrewards.admin"))
            {
                SendReply(player, "No permission");
                return;
            }
            
            if (args.Length == 0)
            {
                SendReply(player, "Usage: /dailyreset <steamID> or 'all'");
                return;
            }
            
            if (args[0].ToLower() == "all")
            {
                foreach (var key in playerData.Keys.ToList())
                {
                    playerData[key] = new PlayerRewardData();
                }
                SaveData();
                SendReply(player, "Reset all player daily rewards");
                return;
            }
            
            if (ulong.TryParse(args[0], out ulong steamId))
            {
                playerData[steamId] = new PlayerRewardData();
                SaveData();
                SendReply(player, $"Reset daily rewards for {steamId}");
            }
        }
        
        [ConsoleCommand("dailyreward.close")]
        private void cmdCloseUI(ConsoleSystem.Arg args)
        {
            BasePlayer player = args.Connection?.player as BasePlayer;
            if (player != null)
            {
                CuiHelper.DestroyUi(player, "DailyRewardsUI");
            }
        }
        
        [ConsoleCommand("dailyreward.claim")]
        private void cmdClaimUI(ConsoleSystem.Arg args)
        {
            BasePlayer player = args.Connection?.player as BasePlayer;
            if (player != null)
            {
                ClaimReward(player);
            }
        }
        
        [ConsoleCommand("dailyrewards.reload")]
        private void cmdReload(ConsoleSystem.Arg args)
        {
            if (args.Connection != null && !permission.UserHasPermission(args.Connection.UserId.ToString(), "dailyrewards.admin"))
            {
                args.ReplyWith("No permission");
                return;
            }
            
            LoadConfig();
            LoadData();
            args.ReplyWith("DailyRewards reloaded");
        }
        #endregion
    }
}

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