478 lines
18 KiB
C#
478 lines
18 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using asap.core;
|
|
using cfg;
|
|
using DataCenter;
|
|
using game;
|
|
using GameCore;
|
|
using Newtonsoft.Json;
|
|
using TMPro;
|
|
using UniRx;
|
|
using UnityEngine;
|
|
|
|
|
|
using EventPartnerGatherDetail = EventPartnerGatherRequests.EventPartnerGatherDetail;
|
|
using EventBuildBotInfo = EventPartnerData.EventBuildBotInfo;
|
|
using ScrollViewItemInfo = EventPartnerScrollViewItem.ScrollViewItemInfo;
|
|
|
|
|
|
namespace EventPartnerGather
|
|
{
|
|
// 存储Cache
|
|
|
|
public class PartnerInfoManager : IDisposable
|
|
{
|
|
// [Inject]
|
|
private static Tables _tables { get; set; } = GContext.container.Resolve<Tables>();
|
|
private FriendService _friendService { get; set; } = GContext.container.Resolve<FriendService>();
|
|
private IUserService _userService { get; } = GContext.container.Resolve<IUserService>();
|
|
|
|
// private bool _lock = false;
|
|
|
|
// private bool _whole = false;
|
|
|
|
// 缓存
|
|
private string _playerPreferenceKey;
|
|
//
|
|
private CompositeDisposable disposables;
|
|
|
|
// EventId
|
|
public int EventId { get; set; }
|
|
|
|
//
|
|
public static readonly int BuilderCapacity = _tables.TbEventPartnerConfig.InvitationCount[1];
|
|
|
|
public readonly BuildPartner[] BuildPartners = new BuildPartner[BuilderCapacity];
|
|
//
|
|
public bool IsFullyMatched => BuildPartners.All(b => b != null && b.IsValid());
|
|
|
|
public int ActiveFriendCountThreshold => _tables.TbEventPartnerConfig.FriendRecommendParam1[0];
|
|
|
|
// 当前用户的build数据
|
|
public bool HasRequestPartners => EventBuildInfo is { RequestPartners: {Count: > 0} } && !IsFullyMatched;
|
|
|
|
public bool HasMoreScore => BuildPartners.Any(b => b != null && b.IsValid() && b.GetExtraScore() > 0);
|
|
|
|
//
|
|
public EventPartnerGatherDetail EventBuildInfo { get; set; }
|
|
|
|
// 积分
|
|
private Dictionary<int, Dictionary<string, int>> Scores { get; set; }
|
|
|
|
//
|
|
public EventPartnerGatherCache Cache { get; set; } = new();
|
|
|
|
|
|
private static void LogError(object t)
|
|
{
|
|
Debug.LogError($"<color=red>PartnerInfoManager-> {t} </color>");
|
|
}
|
|
|
|
private static void Log(object t)
|
|
{
|
|
Debug.Log($"<color=cyan>PartnerInfoManager-> {t} </color>");
|
|
}
|
|
|
|
private static void ELog(object t)
|
|
{
|
|
#if UNITY_EDITOR
|
|
Debug.Log($"<color=cyan>PartnerInfoManager-> {t} </color>");
|
|
#endif
|
|
}
|
|
|
|
private static void LogWarning(object t)
|
|
{
|
|
Debug.LogWarning($"<color=yellow>PartnerInfoManager-> {t} </color>");
|
|
}
|
|
|
|
public void Init()
|
|
{
|
|
ELog($"Init eventId={EventId}");
|
|
// 获取一下缓存数据
|
|
GetPlayerCache();
|
|
|
|
if (disposables != null)
|
|
{
|
|
disposables.Dispose();
|
|
disposables = null;
|
|
}
|
|
|
|
for (int i = 0;i < BuildPartners.Length;++i)
|
|
{
|
|
BuildPartners[i] = null;
|
|
}
|
|
|
|
// BuildPartner
|
|
|
|
disposables = new CompositeDisposable();
|
|
//
|
|
GContext.OnEvent<EventSavePartnerInfoCache>().Subscribe(OnEventSaveData).AddTo(disposables);
|
|
}
|
|
|
|
public void Dispose()
|
|
{
|
|
disposables?.Dispose();
|
|
disposables = null;
|
|
}
|
|
|
|
// 注册时间
|
|
public void OnEventSaveData(EventSavePartnerInfoCache evt)
|
|
{
|
|
ELog($"OnEventSaveData eventId={EventId}");
|
|
//
|
|
SavePlayerPreferenceData();
|
|
// Cache.Save
|
|
//ToPlayfabData().Save();
|
|
}
|
|
public void LoadBuildInfo(EventPartnerGatherDetail detail, Dictionary<int, EventBuildBotInfo> bots)
|
|
{
|
|
EventBuildInfo = detail;
|
|
EventBuildInfo.Partners ??= new List<PlayerInfo>();
|
|
var partners = detail.Partners;
|
|
|
|
// // FIX Load 删除的时候保证起作用
|
|
// for (var i = 0; i < BuilderCapacity; ++i)
|
|
// {
|
|
// BuildPartners[i] = new BuildPartner();
|
|
// }
|
|
// BuildPartners[index]
|
|
if (partners != null)
|
|
{
|
|
for (int slotId = 0; slotId < partners.Count; slotId++)
|
|
{
|
|
ResolveBuildInfoData(slotId, partners[slotId], bots);
|
|
}
|
|
}
|
|
// 为空的话初始话
|
|
// EventBuildInfo.RefusedPartnerIds ??= new List<string>();
|
|
|
|
if (EventBuildInfo.RequestPartners == null)
|
|
EventBuildInfo.RequestPartners = new List<PlayerInfo>();
|
|
if (EventBuildInfo.InvitePartners == null)
|
|
EventBuildInfo.InvitePartners = new List<PlayerInfo>();
|
|
|
|
|
|
var refusedPartnerIds = Cache.RefusedPartnerIds;
|
|
if (refusedPartnerIds is { Count: > 0 })
|
|
{
|
|
EventBuildInfo.RequestPartners.RemoveAll(item => refusedPartnerIds.Contains(item.PlayFabId));
|
|
EventBuildInfo.InvitePartners.RemoveAll(item => refusedPartnerIds.Contains(item.PlayFabId));
|
|
}
|
|
|
|
|
|
}
|
|
private void GetPlayerCache()
|
|
{
|
|
_playerPreferenceKey = "EventPartnerGatherRecommendCache" + _userService?.UserId + EventId;
|
|
var cacheString = PlayerPrefs.GetString(_playerPreferenceKey, "");
|
|
if (cacheString == "")
|
|
{
|
|
Cache = new EventPartnerGatherCache
|
|
{
|
|
ActionQ = new Dictionary<int, Queue<EventPartnerData.EventBuildBotAddScoreAction>>(),
|
|
// ListInvitedBy = new List<ScrollViewItemInfo>(),
|
|
RefusedPartnerIds = new List<string>()
|
|
};
|
|
}
|
|
else
|
|
{
|
|
ELog($"LoadCache eventId={EventId} cacheLength={cacheString?.Length ?? 0}");
|
|
try
|
|
{
|
|
Cache = JsonConvert.DeserializeObject<EventPartnerGatherCache>(cacheString);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
LogError($"LoadCacheFailed eventId={EventId} error={ex.Message}");
|
|
throw;
|
|
}
|
|
|
|
ELog($"LoadCacheDone eventId={EventId}");
|
|
}
|
|
}
|
|
|
|
// 有可能是机器人,需要获得
|
|
private void ResolveBuildInfoData(int index, PlayerInfo playerInfo, Dictionary<int, EventBuildBotInfo> bots)
|
|
{
|
|
if (index >= BuildPartners.Length)
|
|
{
|
|
return;
|
|
}
|
|
var buildPartner = BuildPartners[index] ?? new BuildPartner();
|
|
// Get display info
|
|
buildPartner.Cache = Cache;
|
|
ResolveDisplayInfo(index, playerInfo, buildPartner, bots);
|
|
BuildPartners[index] = buildPartner;
|
|
|
|
}
|
|
|
|
private void ResolveDisplayInfo(int idx, PlayerInfo playerInfo, BuildPartner buildPartner, Dictionary<int, EventBuildBotInfo> bots)
|
|
{
|
|
buildPartner.SlotId = idx;
|
|
var partnerId = playerInfo.PlayFabId;
|
|
buildPartner.PartnerId = partnerId;
|
|
|
|
if (partnerId.EndsWith(EventPartnerBot.RobotIdentifier))
|
|
{
|
|
EventPartnerGatherBot.GetBotDisplayInfo(partnerId, out buildPartner.AvatarUrl, out buildPartner.DisplayName);
|
|
|
|
var botRes = false;
|
|
EventBuildBotInfo botInfo = null;
|
|
if (bots != null)
|
|
{
|
|
botRes = bots.TryGetValue(idx, out botInfo);
|
|
}
|
|
// var botInfo =
|
|
|
|
if (botRes && botInfo != null)
|
|
{
|
|
buildPartner.BotTargetScore = botInfo.TargetScore;
|
|
buildPartner.WakeStartTime = botInfo.WakeStartTime;
|
|
buildPartner.WakingSeconds = botInfo.WakingSeconds;
|
|
buildPartner.BotGrade = botInfo.Grade;
|
|
}
|
|
else
|
|
{
|
|
botInfo = new EventBuildBotInfo
|
|
{
|
|
Id = buildPartner.PartnerId,
|
|
TargetScore = 0,
|
|
WakeStartTime = ZZTimeHelper.UtcNow(),
|
|
WakingSeconds = UnityEngine.Random.Range(_tables.TbEventPartnerConfig.RobotDailyActiveTimeWindow[0],
|
|
_tables.TbEventPartnerConfig.RobotDailyActiveTimeWindow[1]),
|
|
Grade = FtUtils.GetRandomIdxFromWeightList(_tables.TbEventPartnerRobot.DataList.Select(r => r.Weight))
|
|
};
|
|
LogWarning($"BotInfoMissing eventId={EventId} slotId={idx} followup=ScheduleBot");
|
|
|
|
var manager = GContext.container.Resolve<EventPartnerGatherManager>();
|
|
manager.SaveBotInfo(idx, botInfo);
|
|
buildPartner.BotTargetScore = botInfo.TargetScore;
|
|
buildPartner.WakeStartTime = botInfo.WakeStartTime;
|
|
buildPartner.WakingSeconds = botInfo.WakingSeconds;
|
|
buildPartner.BotGrade = botInfo.Grade;
|
|
|
|
// buildPartner.BotTargetScore = 0;
|
|
// buildPartner.WakeStartTime = ZZTimeHelper.UtcNow();
|
|
// buildPartner.WakingSeconds = UnityEngine.Random.Range( _tables.TbEventPartnerConfig.RobotDailyActiveTimeWindow[0],
|
|
// _tables.TbEventPartnerConfig.RobotDailyActiveTimeWindow[1]);
|
|
// buildPartner.BotGrade = FtUtils.GetRandomIdxFromWeightList( _tables.TbEventPartnerRobot.DataList.Select(r => r.Weight));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// buildPartner.PartnerId = partner;
|
|
// // var partnerInfo = _userService.GetPlayInfo(buildPartner.PartnerId);
|
|
buildPartner.AvatarUrl = playerInfo.AvatarUrl;
|
|
buildPartner.DisplayName = playerInfo.DisplayName;
|
|
}
|
|
}
|
|
|
|
public List<string> GetExcludeList()
|
|
{
|
|
var excludeSet = new HashSet<string>();
|
|
// 添加自己
|
|
excludeSet.Add(_userService?.UserId);
|
|
if (EventBuildInfo.RequestPartners != null)
|
|
foreach (var requestPartner in EventBuildInfo.RequestPartners)
|
|
excludeSet.Add(requestPartner.PlayFabId);
|
|
// Exclude friends
|
|
foreach (var friend in _friendService.FriendList)
|
|
excludeSet.Add(friend.playFabId);
|
|
// Exclude refused ones
|
|
if (Cache.RefusedPartnerIds is not null)
|
|
foreach (var id in Cache.RefusedPartnerIds)
|
|
excludeSet.Add(id);
|
|
|
|
// Exclude ones that player already invited
|
|
if (EventBuildInfo.InvitePartners is not null)
|
|
foreach (var p in EventBuildInfo.InvitePartners)
|
|
excludeSet.Add(p.PlayFabId);
|
|
return new List<string>(excludeSet);
|
|
}
|
|
|
|
public int GetRecommendCount()
|
|
{
|
|
var friendCount = _friendService.FriendList.Count;
|
|
if (friendCount < ActiveFriendCountThreshold)
|
|
{
|
|
return _tables.TbEventPartnerConfig.FriendRecommendParam2[0];
|
|
}
|
|
|
|
return _tables.TbEventPartnerConfig.FriendRecommendParam2[1];
|
|
}
|
|
|
|
//
|
|
public void AddRefusePartner(string partnerId)
|
|
{
|
|
Cache.RefusedPartnerIds.Add(partnerId);
|
|
|
|
// OnNoLongerUsedPartner(partnerId);
|
|
}
|
|
|
|
public void SavePlayerPreferenceData()
|
|
{
|
|
// LogError("SavePlayerPreferenceData-> ");
|
|
|
|
var cache = JsonConvert.SerializeObject(Cache);
|
|
Log($"SaveCache eventId={EventId} cacheLength={cache?.Length ?? 0}");
|
|
PlayerPrefs.SetString(_playerPreferenceKey, cache);
|
|
}
|
|
|
|
|
|
public BuildPartner GetPartnerById(string partnerId)
|
|
{
|
|
return BuildPartners.FirstOrDefault(buildPartner => buildPartner.PartnerId.Equals(partnerId));
|
|
}
|
|
|
|
public bool UpdatePartnerScore(string partnerId, int eScore)
|
|
{
|
|
var builder = GetPartnerById(partnerId);
|
|
if (builder != null)
|
|
{
|
|
builder.ScorePartnerActual = eScore;
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
public void LoadScore(List<Dictionary<string, int>> respScores,
|
|
List<(int myScore, int FriendScore)> buildPartnerScore)
|
|
{
|
|
if (respScores != null)
|
|
Scores = respScores.Select((x, i) => (x, i)).ToDictionary(kv => kv.i, kv => kv.x);
|
|
else
|
|
Scores = new Dictionary<int, Dictionary<string, int>>();
|
|
for (int i = 0; i < BuildPartners.Length; ++i)
|
|
{
|
|
var buildPartner = BuildPartners?[i];
|
|
var (myScore, partnerScore) = buildPartnerScore[i];
|
|
if (buildPartner is { IsPartnerRobot: true })
|
|
{
|
|
buildPartner.ScoreSelfActual = myScore;
|
|
buildPartner.ScorePartnerActual = partnerScore;
|
|
}
|
|
}
|
|
|
|
foreach (var (idx, value) in Scores)
|
|
{
|
|
if (idx >= BuildPartners?.Length)
|
|
{
|
|
continue;
|
|
}
|
|
var buildPartner = BuildPartners?[idx];
|
|
|
|
if (buildPartner != null)
|
|
{
|
|
var ret = value.TryGetValue(buildPartner.PartnerId, out var partnerScore);
|
|
if (ret)
|
|
{
|
|
buildPartner.ScorePartnerActual = partnerScore;
|
|
}
|
|
|
|
ret = value.TryGetValue(_userService.UserId, out var selfScore);
|
|
if (ret)
|
|
{
|
|
buildPartner.ScoreSelfActual = selfScore;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public void AddRequestPartner(PlayerInfo partnerInfo)
|
|
{
|
|
EventBuildInfo.RequestPartners.Add(partnerInfo);
|
|
}
|
|
|
|
public bool AddBuildPartner(BuildPartner buildPartner)
|
|
{
|
|
var index = buildPartner.SlotId;
|
|
if (index >= BuilderCapacity)
|
|
{
|
|
LogWarning($"AddBuildPartnerFailed eventId={EventId} reason=SlotOutOfRange slotId={index} capacity={BuilderCapacity}");
|
|
return false;
|
|
}
|
|
|
|
if (BuildPartners[index] != null && BuildPartners[index].IsValid())
|
|
{
|
|
LogWarning($"AddBuildPartnerFailed eventId={EventId} reason=SlotOccupied slotId={index}");
|
|
return false;
|
|
}
|
|
|
|
var manager = GContext.container.Resolve<EventPartnerGatherManager>();
|
|
var maxScore = manager.NodeCumulativeSteps[^1];
|
|
buildPartner.MaxScore = maxScore;
|
|
buildPartner.Cache = Cache;
|
|
BuildPartners[index] = buildPartner;
|
|
manager.ResetBuildPartner(buildPartner.SlotId);
|
|
manager.SavePartnerInfo(buildPartner.SlotId);
|
|
|
|
GContext.container.Resolve<IUserService>().SetPlayInfo(buildPartner.PartnerId, buildPartner.DisplayName, buildPartner.AvatarUrl);
|
|
|
|
return true;
|
|
}
|
|
|
|
public void RemoveInvitePartner(string partnerInfoPlayFabId)
|
|
{
|
|
if (string.IsNullOrEmpty(partnerInfoPlayFabId))
|
|
return;
|
|
EventBuildInfo.InvitePartners.RemoveAll(item => item.PlayFabId.Equals(partnerInfoPlayFabId));
|
|
}
|
|
|
|
|
|
// 添加之后的删除与整理,不在出现在邀请和和推荐
|
|
public void OnNoLongerUsedPartner(string playFabId)
|
|
{
|
|
|
|
if(EventBuildInfo.RequestPartners is {Count: > 0})
|
|
{
|
|
EventBuildInfo.RequestPartners.RemoveAll(p => p.PlayFabId == playFabId);
|
|
}
|
|
// SavePlayerPreferenceData();
|
|
}
|
|
|
|
public bool AddInvitationInfo(ScrollViewItemInfo invitationInfo)
|
|
{
|
|
var buildInfo = EventBuildInfo;
|
|
var partnerId = invitationInfo.PlayfabId;
|
|
if (buildInfo.InvitePartners.Select(p => p.PlayFabId).Contains(partnerId))
|
|
return false;
|
|
invitationInfo.Type = EventPartnerScrollViewItem.EScrollViewType.MyInvitation;
|
|
buildInfo.InvitePartners.Add(PlayerInfo.FromScrollViewItem(invitationInfo));
|
|
|
|
return true;
|
|
}
|
|
|
|
public void SyncGatherData(EventPartnerGatherManager manager)
|
|
{
|
|
var gatherData = manager.GatherData;
|
|
ELog($"SyncGatherData eventId={EventId} hasData={gatherData != null}");
|
|
var buildScore = gatherData.BuilderPartnerScore;
|
|
for (var i = 0; i < buildScore.Count; ++i)
|
|
{
|
|
var (myScore, partnerScore) = buildScore[i];
|
|
if (i > BuildPartners.Length - 1)
|
|
continue;
|
|
BuildPartners[i] ??= new BuildPartner();
|
|
var builder = BuildPartners[i];
|
|
if (builder != null)
|
|
{
|
|
builder.ScoreSelfDisplay = myScore;
|
|
builder.ScorePartnerDisplay = partnerScore;
|
|
builder.MaxScore = manager.NodeCumulativeSteps[^1];
|
|
builder.Cache = Cache;
|
|
}
|
|
}
|
|
}
|
|
|
|
public void SyncToGatherData()
|
|
{
|
|
// Log($"SyncGatherData-> {gatherData}");
|
|
// var manager = GContext.container.Resolve<EventPartnerGatherManager>();
|
|
// manager.SyncFromPartnerInfo(this);
|
|
}
|
|
|
|
|
|
}
|
|
|
|
} |