lcy
7 天以前 63ba91cc8c0c99ea489efe31ca9bf8404326c84d
429 【主界面】自动挂机-补充自动挑战自动任务 装备记录部分
6个文件已修改
357 ■■■■ 已修改文件
Main/System/Equip/EquipModel.cs 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Main/AutoFightWin.cs 9 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Main/EquipRecordCell.cs 48 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Main/EquipRecordItem.cs 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Main/EquipRecordManager.cs 237 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Main/EquipRecordWin.cs 37 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Equip/EquipModel.cs
@@ -305,18 +305,20 @@
            Debug.LogWarning("穿戴装备,向服务器请求");
        }
        //在记录销毁或替换前的装备
        //记录销毁或替换前的装备
        if ((opType == 1 || opType == 2) && !itemIndexList.IsNullOrEmpty())
        {
            foreach (var index in itemIndexList)
            {
                var oldEquip = PackManager.Instance.GetItemByIndex(PackType.Equip, index);
                EquipRecordManager.Instance.oldEquipDic[index] = oldEquip;
                ItemModel newEquip = PackManager.Instance.GetItemByIndex(PackType.DropItem, index);
                if (newEquip == null)
                    continue;
                int equipPlace = newEquip.config.EquipPlace - 1;
                ItemModel oldEquip = PackManager.Instance.GetItemByIndex(PackType.Equip, equipPlace);
                EquipRecordManager.Instance.AddRecord(opType, newEquip, oldEquip);
            }
        }
        GameNetSystem.Instance.SendInfo(pack);
    }
    /// <summary>
Main/System/Main/AutoFightWin.cs
@@ -32,7 +32,7 @@
    [SerializeField] Toggle autoFinishTaskToggle;
    [SerializeField] Button autoFinishTaskTipBtn;
    [SerializeField] Button recordBtn;
    bool isOpenCostScroll = false;
    bool isOpenSpeedScroll = false;
    bool isOpenTryChallengeScroll = false;
@@ -49,7 +49,7 @@
        autoFinishTaskTipBtn.AddListener(() =>
        {
            DislayTip("AutoFight16",autoFinishTaskTipBtn.transform.position);
            DislayTip("AutoFight16", autoFinishTaskTipBtn.transform.position);
        });
        changeCostBtn.AddListener(() =>
@@ -119,6 +119,11 @@
            isOpenTryChallengeScroll = false;
            tryChallengeArrow.transform.localRotation = Quaternion.Euler(0, 0, 0);
        });
        recordBtn.SetListener(() =>
        {
            UIManager.Instance.OpenWindow<EquipRecordWin>();
        });
    }
    protected override void OnPreOpen()
Main/System/Main/EquipRecordCell.cs
@@ -1,13 +1,57 @@
using System.Collections.Generic;
using UnityEngine;
using System;
public class EquipRecordCell : MonoBehaviour
{
    [SerializeField] EquipRecordItem fromEquip;
    [SerializeField] EquipRecordItem toEquip;
    [SerializeField] ImageEx imgWear;
    [SerializeField] ImageEx imgDecompose;
    public void Display(int index)
    [SerializeField] TextEx txtFightPoint;
    [SerializeField] TextEx txtTime;
    public void Display(int index, List<EquipRecordManager.EquipRecordData> list)
    {
        if (list == null || index >= list.Count || index < 0)
            return;
        var data = list[index];
        int state = GetState(data);
        if (state == 0)
        {
            fromEquip.SetActive(false);
            toEquip.SetActive(false);
            imgWear.SetActive(false);
            imgDecompose.SetActive(false);
        }
        else
        {
            fromEquip.SetActive(state == 1 || state == 2 || state == 3);
            toEquip.SetActive(state == 1);
            imgDecompose.SetActive(state == 2);
            imgWear.SetActive(state == 3);
            fromEquip.Display(state == 1 ? data.oldEquip : data.newEquip);
            toEquip.Display(data.newEquip);
        }
        txtFightPoint.text = StringUtility.Concat("+", UIHelper.ReplaceLargeNum(data.fightPower));
        txtTime.text = GetTime(data.timestamp);
    }
    // 0-不显示 1-交换 2-分解 3-首次穿装备
    private int GetState(EquipRecordManager.EquipRecordData data)
    {
        if (data == null || data.newEquip == null)
            return 0;
        if (data.oldEquip == null)
            return 3;
        if (data.recordType == (int)EquipRecordManager.EquipOPType.Equip)
            return 1;
        if (data.recordType == (int)EquipRecordManager.EquipOPType.Decompose)
            return 2;
        return 0;
    }
    private string GetTime(int timestamp)
    {
        DateTime dateTime = TimeUtility.GetTime((uint)timestamp);
        return dateTime.ToString("MM-dd HH:mm:ss");
    }
}
Main/System/Main/EquipRecordItem.cs
@@ -11,6 +11,20 @@
    [SerializeField] TextEx txtLV;
    public void Display(EquipRecordManager.EquipDetail detail)
    {
        if (detail == null || !ItemConfig.HasKey(detail.itemId))
            return;
        var config = ItemConfig.Get(detail.itemId);
        string name = config.ItemName;
        int quality = config.ItemColor;
        string IconKey = config.IconKey;
        imgEquip.SetOrgSprite(IconKey);
        txtName.text = UIHelper.AppendColor(quality, name, true, 1);
        txtQualityName.text = UIHelper.GetQualityNameWithColor(quality, Language.Get("L1039"));
        itemNameOutline.OutlineColor = UIHelper.GetUIOutlineColor(quality);
        qualityNameOutline.OutlineColor = UIHelper.GetUIOutlineColor(quality);
        txtLV.text = Language.Get("L1113", detail.lv);
        imgQuality.SetSprite("equipQuality" + quality);
    }
}
Main/System/Main/EquipRecordManager.cs
@@ -6,64 +6,11 @@
public class EquipRecordManager : GameSystemManager<EquipRecordManager>
{
    private List<EquipRecordData> recordList = new List<EquipRecordData>();
    public Dictionary<int, ItemModel> oldEquipDic = new Dictionary<int, ItemModel>();
    /// <summary>
    /// 调试用:遍历输出所有装备记录的详细信息(单条Log)
    /// </summary>
    public void DebugLogAllRecords()
    {
        var sb = new System.Text.StringBuilder();
        sb.AppendLine($"=== 装备记录总数: {recordList.Count} | 旧装备字典条目数: {oldEquipDic.Count} ===");
        for (int i = 0; i < recordList.Count; i++)
        {
            var record = recordList[i];
            sb.AppendLine($"--- 记录 {i + 1} ---");
            sb.AppendLine($"记录ID: {record.recordId} | 时间: {TimeUtility.GetTime((uint)record.timestamp)} | 类型: {record.recordType}");
            // 新装备详情
            if (record.newEquip != null)
            {
                sb.AppendLine($"[新装备] ID:{record.newEquip.itemId} | 名称:{record.newEquip.itemName} | 强化:{record.newEquip.level} | 评分:{record.newEquip.score} | 部位:{record.newEquip.equipPlace} | 战力:{record.newEquip.fightPower} | GUID:{record.newEquip.guid}");
            }
            else
            {
                sb.AppendLine($"[新装备] 无数据");
            }
            // 旧装备详情
            if (record.oldEquip != null)
            {
                sb.AppendLine($"[旧装备] ID:{record.oldEquip.itemId} | 名称:{record.oldEquip.itemName} | 强化:{record.oldEquip.level} | 评分:{record.oldEquip.score} | 部位:{record.oldEquip.equipPlace} | 战力:{record.oldEquip.fightPower} | GUID:{record.oldEquip.guid}");
            }
            else
            {
                sb.AppendLine($"[旧装备] 无数据");
            }
            sb.AppendLine(); // 空行分隔
        }
        // 旧装备字典
        sb.AppendLine("=== 旧装备字典详情 ===");
        foreach (var kvp in oldEquipDic)
        {
            sb.AppendLine($"Key:{kvp.Key} | Value:ItemModel(itemId={kvp.Value?.itemId}, guid={kvp.Value?.guid})");
        }
        UnityEngine.Debug.Log(sb.ToString());
    }
    private int maxCnt;
    public int maxCnt;
    public override void Init()
    {
        DTC0102_tagCDBPlayer.beforePlayerDataInitializeEventOnRelogin += OnBeforePlayerDataInitializeEventOnRelogin;
        DTC0403_tagPlayerLoginLoadOK.playerLoginOkEvent += OnPlayerLoginOk;
        // 监听装备操作结果
        EquipModel.Instance.OnEquipOPResultAction += OnEquipOPResult;
        var config = FuncConfigConfig.Get("AutoGuaji1");
        maxCnt = int.Parse(config.Numerical5);
@@ -73,14 +20,12 @@
    {
        DTC0102_tagCDBPlayer.beforePlayerDataInitializeEventOnRelogin -= OnBeforePlayerDataInitializeEventOnRelogin;
        DTC0403_tagPlayerLoginLoadOK.playerLoginOkEvent -= OnPlayerLoginOk;
        EquipModel.Instance.OnEquipOPResultAction -= OnEquipOPResult;
    }
    private void OnBeforePlayerDataInitializeEventOnRelogin()
    {
    }
    private void OnPlayerLoginOk()
@@ -99,28 +44,29 @@
    private void LoadRecords()
    {
        var json = LocalSave.GetString(Key);
        if (!string.IsNullOrEmpty(json))
        if (string.IsNullOrEmpty(json))
        {
            recordList = new List<EquipRecordData>();
            return;
        }
        try
        {
            recordList = JsonMapper.ToObject<List<EquipRecordData>>(json);
            // 排序规则:时间戳小的靠前,时间戳相同则索引小的靠前
            recordList.Sort((a, b) =>
            {
                int timeCompare = a.timestamp.CompareTo(b.timestamp);
                if (timeCompare != 0)
                    return timeCompare;
                return 0;
            });
        }
    }
    /// <summary>
    /// 装备操作结果回调 - 记录装备变化
    /// </summary>
    /// <param name="isDone">是否成功更换</param>
    /// <param name="equipIndex">装备栏索引</param>
    private void OnEquipOPResult(bool isDone, int equipIndex)
    {
        if (equipIndex < 0) return;
        // 获取新装备和旧装备信息
        var newEquip = PackManager.Instance.GetItemByIndex(PackType.Equip, equipIndex);
        if (newEquip == null) return;
        // 获取被替换的装备(需要从其他地方记录)
        // 这里需要配合 EquipModel 的 OnEquipResult 记录被替换的装备
        // ...
        catch (Exception ex)
        {
            Debug.LogError($"加载装备记录失败: {ex.Message}");
            recordList = new List<EquipRecordData>();
        }
    }
    /// <summary>
@@ -133,43 +79,152 @@
        var detail = new EquipDetail
        {
            itemId = item.itemId,
            level = item.GetUseDataFirstValue(22),
            equipPlace = item.config.EquipPlace,
            lv = item.GetUseDataFirstValue(22),
            guid = item.guid,
        };
        return detail;
    }
    public List<EquipRecordData> GetRecordList(bool isSort = false)
    {
        if (recordList == null)
        {
            return null;
        }
        if (isSort)
        {
            // 排序规则:时间戳小的靠前,时间戳相同则索引小的靠前
            recordList.Sort((a, b) =>
            {
                int timeCompare = a.timestamp.CompareTo(b.timestamp);
                if (timeCompare != 0)
                    return timeCompare;
                return 0;
            });
        }
        return recordList;
    }
    public event Action OnUpdateRecordListEvent;
    public void AddRecord(int recordType, ItemModel newEquip, ItemModel oldEquip)
    {
        if (newEquip == null)
            return;
        long showFightPower = FightPowerManager.Instance.GetFightPowerChange(newEquip);
        // 新装备战力低于旧装备战力,不允许添加
        if (showFightPower <= 0)
            return;
        var newDetail = GetEquipDetail(newEquip);
        var oldDetail = GetEquipDetail(oldEquip);
        if (recordList == null)
            return;
        // 遍历现有记录,检查是否存在匹配的记录(不限制顺序)
        foreach (var existingRecord in recordList)
        {
            if (IsSameRecord(existingRecord, newDetail, oldDetail))
            {
                // 找到匹配的记录,不添加
                return;
            }
        }
        var record = new EquipRecordData
        {
            recordType = (int)recordType,
            newEquip = GetEquipDetail(newEquip),
            oldEquip = GetEquipDetail(oldEquip),
            fightPower = showFightPower,
            timestamp = TimeUtility.AllSeconds,
        };
        if (recordList.Count >= maxCnt)
        {
            // 移除最早加入的记录(排序后第一个)
            recordList.RemoveAt(0);
        }
        recordList.Add(record);
        SaveRecords();
        OnUpdateRecordListEvent?.Invoke();
    }
    /// <summary>
    /// 判断两条记录是否一致(不限制 new/old 顺序)
    /// </summary>
    private bool IsSameRecord(EquipRecordData existingRecord, EquipDetail newDetail, EquipDetail oldDetail)
    {
        // 参数校验
        if (newDetail == null && oldDetail == null)
            return true;
        if (existingRecord == null)
            return true;
        // 计算各字段是否为 null
        bool newIsNull = IsNullOrEmptyGuid(newDetail);
        bool oldIsNull = IsNullOrEmptyGuid(oldDetail);
        bool recordNewIsNull = IsNullOrEmptyGuid(existingRecord.newEquip);
        bool recordOldIsNull = IsNullOrEmptyGuid(existingRecord.oldEquip);
        // 如果两边都为空,则视为相同
        if (newIsNull && oldIsNull && recordNewIsNull && recordOldIsNull)
            return true;
        // 如果只有一边为空,则不同
        if (newIsNull != recordNewIsNull || oldIsNull != recordOldIsNull)
            return false;
        // 检查顺序是否匹配
        bool orderMatch = IsGuidMatch(existingRecord.newEquip, newDetail) &&
                          IsGuidMatch(existingRecord.oldEquip, oldDetail);
        // 检查顺序是否相反
        bool reverseMatch = IsGuidMatch(existingRecord.newEquip, oldDetail) &&
                            IsGuidMatch(existingRecord.oldEquip, newDetail);
        return orderMatch || reverseMatch;
    }
    // 判断装备详情是否为 null 或 guid 为空
    private bool IsNullOrEmptyGuid(EquipDetail detail)
    {
        return detail == null || string.IsNullOrEmpty(detail.guid);
    }
    // 比较两个装备详情的 guid 是否相等(安全比较,避免 null 异常)
    private bool IsGuidMatch(EquipDetail a, EquipDetail b)
    {
        // 任一对象为 null 则不匹配
        if (a == null || b == null)
            return false;
        return a.guid == b.guid;
    }
    // 装备记录数据类型
    public class EquipRecordData
    {
        public string recordId;              // 记录唯一ID
        public long timestamp;               // 时间戳
        public RecordType recordType;        // 记录类型
        public int recordType;        // 记录类型
        public EquipDetail newEquip;         // 新装备详情
        public EquipDetail oldEquip;         // 旧装备详情
        public long fightPower;                 // 战力差
        public int timestamp;               // 时间戳
    }
    public class EquipDetail
    {
        public int itemId;                   // 物品配置ID
        public string itemName;              // 物品名称
        public int level;                    // 强化等级
        public int score;                    // 装备评分
        public int equipPlace;               // 装备部位
        public long fightPower;              // 战力
        public string guid;                  // 装备唯一ID
        public string guid;                     // 装备唯一ID
        public int itemId;                      // 物品ID
        public int lv;                          // 等级
    }
    public enum RecordType
    public enum EquipOPType
    {
        Equip = 0,        // 装备
        Decompose = 1     // 分解
        Decompose = 1,     // 分解
        Equip = 2,        // 装备
    }
}
Main/System/Main/EquipRecordWin.cs
@@ -1,33 +1,56 @@
using System;
using System.Collections.Generic;
using UnityEngine;
public class EquipRecordWin : UIBase
{
    [SerializeField] ScrollerController scroller;
    [SerializeField] TextEx txtTip;
    EquipRecordManager manager { get { return EquipRecordManager.Instance; } }
    protected override void OnPreOpen()
    {
        scroller.OnRefreshCell += OnRefreshCell;
        CreateScroller();
        manager.OnUpdateRecordListEvent += OnUpdateRecordListEvent;
        txtTip.text = Language.Get("AutoFight17", manager.maxCnt);
        scroller.lockType = EnhanceLockType.KeepVertical;
        CreateScroller(isSort: true, isjump: true);
    }
    protected override void OnPreClose()
    {
        scroller.OnRefreshCell -= OnRefreshCell;
        manager.OnUpdateRecordListEvent -= OnUpdateRecordListEvent;
    }
    private void OnUpdateRecordListEvent()
    {
        CreateScroller();
    }
    private void OnRefreshCell(ScrollerDataType type, CellView cell)
    {
        var _cell = cell.GetComponent<EquipRecordCell>();
        _cell?.Display(cell.index);
        _cell?.Display(cell.index, list);
    }
    private void CreateScroller()
    List<EquipRecordManager.EquipRecordData> list;
    private void CreateScroller(bool isSort = false, bool isjump = false)
    {
        scroller.Refresh();
        for (int i = 0; i < 20; i++)
        list = manager.GetRecordList(isSort);
        if (list != null)
        {
            scroller.AddCell(ScrollerDataType.Header, i);
            for (int i = list.Count - 1; i >= 0; i--)
            {
                scroller.AddCell(ScrollerDataType.Header, i);
            }
        }
        scroller.Restart();
        if (isjump)
        {
            scroller.JumpIndex(0);
        }
    }
}