using asap.core; using cfg; using GameCore; using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using UnityEngine; using Newtonsoft.Json.Linq; namespace game { public class ClubStateChangeEvent { public int state; public bool joinClub; } public class ClubSttingUpdateEvent { } public class GetClubPlayInfoEvent { public string id; public string name; public string avatarUrl; } public class LureDonateData { public DateTime DonateCountTime { get; set; } public int ClubLureDonateCount { get; set; }//时间加次数 public DateTime ClubLureRequestCDEnd { get; set; } } public class ClubService //: IClubService { [Inject] public PlayerDataStorage.IPlayerSaveStore SaveStore { get; set; } // BEGIN B01 fixed prompt owner readonly bool requiresFormalKV; PlayerDataStorage.PlayerKVGameSessionHandle promptOwner; internal PlayerDataStorage.PlayerKVEditResult LastPromptEdit { get; private set; } public ClubService() : this(RequireFrozenSelection()) { } static bool RequireFrozenSelection() { var selection = GContext.container.Resolve(); if (selection == null) throw DefaultSettingService.PromptFailure("IsOpenClubRed: startup selection missing."); return selection.IsKV; } internal ClubService(bool formalKV) { requiresFormalKV = formalKV; } internal ClubService(PlayerDataStorage.PlayerKVGameSessionHandle owner) : this(true) { promptOwner = owner ?? throw new ArgumentNullException(nameof(owner)); RequirePromptOwner(); } // The constructor captures the registered startup selection, never a later mutable config value. internal void PreflightFormalPromptOwner(PlayerDataStorage.PlayerKVGameSessionHandle owner) { if (!requiresFormalKV || owner == null || (promptOwner != null && !ReferenceEquals(promptOwner, owner))) throw DefaultSettingService.PromptFailure("IsOpenClubRed: formal owner mismatch."); var read = KVMgr.ReadKV(owner, "IsOpenClubRed"); if (!read.Success) throw DefaultSettingService.PromptFailure($"IsOpenClubRed owner={owner.OwnerInstanceId}: {read.Error}"); } internal void BindFormalPromptOwner(PlayerDataStorage.PlayerKVGameSessionHandle owner) { PreflightFormalPromptOwner(owner); if (promptOwner == null) promptOwner = owner; RequirePromptOwner(); } internal bool HasFormalPromptOwner(PlayerDataStorage.PlayerKVGameSessionHandle owner) => requiresFormalKV && ReferenceEquals(promptOwner, owner); internal void RequirePromptOwner() { if (promptOwner != null) ReadPrompt(); else if (requiresFormalKV) throw DefaultSettingService.PromptFailure("IsOpenClubRed: formal owner not handed off."); } PlayerDataStorage.PlayerKVKeyReadResult ReadPrompt() { if (LastPromptEdit != null && !LastPromptEdit.Accepted) throw DefaultSettingService.PromptFailure($"IsOpenClubRed owner={promptOwner.OwnerInstanceId}: {LastPromptEdit.StateResult.Error}; uncertain={LastPromptEdit.StateResult.LocalCommitMayHaveSucceeded}"); var read = KVMgr.ReadKV(promptOwner, "IsOpenClubRed"); if (!read.Success) throw DefaultSettingService.PromptFailure($"IsOpenClubRed owner={promptOwner.OwnerInstanceId}: {read.Error}"); return read; } // END B01 fixed prompt owner [Inject] public IUserService userService { get; set; } [Inject] public ICustomServerMgr customServerMgr { get; set; } [Inject] public IChatService chatService { get; set; } public bool IsOpenClubJoined = false; public bool IsOpenClubRed = true; public int socialTipforUnlocked; public ClubInfo myClubInfo { get; private set; } //public bool isAdm { get; private set; } public EMemberRole memberRole { get; private set; } = EMemberRole.Member; public DateTime? signTime { get; private set; } LureDonateData lureDonateData; // KV loading owns these three fields only; membership, transport and chat lifecycle stay untouched. internal static PlayerDataStorage.PlayerKVClubState DecodeForKVLoad(IReadOnlyDictionary raw, PlayerDataStorage.PlayerKVSchemaSnapshot snapshot, PlayerDataStorage.PlayerKVSchemaDiagnostics errors) => PlayerDataStorage.PlayerKVSaveSchema.DecodeClub(raw,snapshot,errors); internal void ResetForKVLoad() { signTime = null; lureDonateData = new LureDonateData(); IsOpenClubRed = true; } internal void ReplaceFromKVDecoded(PlayerDataStorage.PlayerKVClubState state) { if (state == null) throw new ArgumentNullException(nameof(state)); var donation = new LureDonateData { DonateCountTime=state.DonateTime, ClubLureDonateCount=state.DonateCount, ClubLureRequestCDEnd=state.RequestEnd }; signTime = state.SignTime; lureDonateData = donation; IsOpenClubRed = state.OpenRed; } internal PlayerDataStorage.PlayerKVClubState SnapshotForKVValidation() => new PlayerDataStorage.PlayerKVClubState(signTime,lureDonateData.DonateCountTime, lureDonateData.ClubLureDonateCount,lureDonateData.ClubLureRequestCDEnd,IsOpenClubRed); public int ClubLureDonateCount => lureDonateData.ClubLureDonateCount; public DateTime ClubLureRequestCDEnd => lureDonateData.ClubLureRequestCDEnd; public Dictionary internalIdToPlayerId = new Dictionary(); public ClubItemData ClubItemData; public List clubPlayerInfos { get; private set; } public List eventPopupDatas { get; private set; } = new List(); public EventPopupData eventPopupDataClub { get; private set; } public int OpenPanelType = 0; public async void OpenFishingSocialPanel(int type) { OpenPanelType = type; await UIManager.Instance.ShowUI(UITypes.FishingSocialPanel); OpenPanelType = 0; } public bool CanAccepted { get { return memberRole == EMemberRole.Owner || memberRole == EMemberRole.Vice || memberRole == EMemberRole.Elder; } } public bool ApplyState { get; private set; } public bool CanSetting { get { return memberRole == EMemberRole.Owner || memberRole == EMemberRole.Vice; } } public void Init() { if (lureDonateData == null) { lureDonateData = new LureDonateData(); lureDonateData.DonateCountTime = ZZTimeHelper.UtcNow().UtcNowOffset(); lureDonateData.ClubLureDonateCount = 0; lureDonateData.ClubLureRequestCDEnd = ZZTimeHelper.UtcNow().UtcNowOffset(); } if (IsOpenClubJoined) { SetClubRed(); } } void SetClubRed() { if (myClubInfo == null) { RedPointManager.Instance.SetRedPointState(RedPointName.Home_Club, IsOpenClubRed); } else { var timer = ZZTimeHelper.UtcNow().UtcNowOffset(); bool isSign = signTime?.DayOfYear != timer.DayOfYear; bool isCanLure = lureDonateData != null && lureDonateData.ClubLureRequestCDEnd <= timer; RedPointManager.Instance.SetRedPointState(RedPointName.Home_Club, isCanLure || isSign); } } public void SetLureDonateData(string value) { lureDonateData = Newtonsoft.Json.JsonConvert.DeserializeObject(value); } void SaveLureDonateData() { SaveStore.Write("LureDonateData", Newtonsoft.Json.JsonConvert.SerializeObject(lureDonateData)).RequireAccepted(); } //刷新体力求助次数 public void RefreshLureDonate() { if (lureDonateData.DonateCountTime.Date != ZZTimeHelper.UtcNow().UtcNowOffset().Date) { lureDonateData.DonateCountTime = ZZTimeHelper.UtcNow().UtcNowOffset(); lureDonateData.ClubLureDonateCount = 0; SaveLureDonateData(); } } public void SetOpenClubRed() { if (requiresFormalKV && promptOwner == null) RequirePromptOwner(); if (promptOwner != null) { var read = ReadPrompt(); // M14: any present string means read, including "0" and the empty string. if (read.Found != true) { LastPromptEdit = KVMgr.WriteKV(promptOwner, "IsOpenClubRed", "1"); if (!LastPromptEdit.Accepted) throw DefaultSettingService.PromptFailure($"IsOpenClubRed owner={promptOwner.OwnerInstanceId}: {LastPromptEdit.StateResult.Error}; uncertain={LastPromptEdit.StateResult.LocalCommitMayHaveSucceeded}"); } RequirePromptOwner(); IsOpenClubRed = false; SetClubRed(); return; } if (IsOpenClubRed) { IsOpenClubRed = false; SetClubRed(); PlayFabMgr.Instance.UpdateUserDataValue("IsOpenClubRed", "1"); } } public bool IsClubJoined() { return myClubInfo != null; } public void SetClubSignin(string value) { if (string.IsNullOrEmpty(value)) { signTime = null; } else { signTime = DateTime.Parse(value); } } public async void GetSelfClub() { if (!userService.IsAuthorized || string.IsNullOrEmpty(userService.ApiPlayerId)) return; var sessionVersion = customServerMgr.SessionVersion; GetSelfClubRequest getSelfClubRequest = new GetSelfClubRequest() { playerId = userService.ApiPlayerId, }; string json = await customServerMgr.ClubRequest("GetSelfClub", getSelfClubRequest); if (sessionVersion != customServerMgr.SessionVersion) return; if (string.IsNullOrWhiteSpace(json)) return; GetSelfClubResp response; try { var body = JObject.Parse(json); if (!body.TryGetValue("clubInfo", out var club) || (club.Type != JTokenType.Null && club.Type != JTokenType.Object)) return; response = body.ToObject(); if (response == null) return; if (club.Type == JTokenType.Object && (response.clubInfo == null || response.clubInfo.id == 0 || body["role"]?.Type != JTokenType.Integer || !Enum.IsDefined(typeof(EMemberRole), response.role))) return; } catch (Newtonsoft.Json.JsonException) { return; } catch (OverflowException) { return; } myClubInfo = response.clubInfo; memberRole = myClubInfo == null ? EMemberRole.Member : response.role; internalIdToPlayerId = response.playerIDs ?? new Dictionary(); if (myClubInfo != null) { SetClubPlayerProfile(response.clubPlayerProfiles); chatService.GetConversationList((long)myClubInfo.id); } SetClubRed(); MyClubInfoChange(); } void MyClubInfoChange(bool joinClub = false) { GContext.Publish(new ClubStateChangeEvent() { state = 0, joinClub = joinClub }); } public async Task GetOnlineUsers() { HashSet longs = await chatService.GetOnlineUsers(internalIdToPlayerId.Keys.ToList()); return longs == null ? 0 : longs.Count; } public void Refresh() { ClubInfoMap.Clear(); } Dictionary> ClubInfoMap = new Dictionary>(); public async Task> GetClubs(string clubName) { if (ClubInfoMap.ContainsKey(clubName)) { await Awaiters.NextFrame; return ClubInfoMap[clubName]; } GetClubsRequest getClubsRequest = new GetClubsRequest() { clubName = clubName, }; string json = await customServerMgr.ClubRequest("GetClubs", getClubsRequest); if (!string.IsNullOrEmpty(json) && json != "[]") { GetClubsResp clubDatas = Newtonsoft.Json.JsonConvert.DeserializeObject(json); ClubInfoMap[clubName] = clubDatas.clubInfo; return clubDatas.clubInfo; } else { return null; } } private static bool IsDecimalPlayerId(string id) => long.TryParse(id, System.Globalization.NumberStyles.None, System.Globalization.CultureInfo.InvariantCulture, out var number) && number > 0; private bool TryGetClubSession(out string playerId, out int version) { playerId = userService.ApiPlayerId; version = customServerMgr.SessionVersion; return userService.IsAuthorized && IsDecimalPlayerId(playerId); } private bool IsClubSessionCurrent(string playerId, int version) => version == customServerMgr.SessionVersion && userService.IsAuthorized && playerId == userService.ApiPlayerId; private static bool TryReadClubResponse(string json, out T result, params int[] acceptedCodes) where T : class { result = null; if (string.IsNullOrWhiteSpace(json)) return false; try { var body = Newtonsoft.Json.Linq.JObject.Parse(json); var code = body["code"]; if (code?.Type != Newtonsoft.Json.Linq.JTokenType.Integer || !acceptedCodes.Contains(code.Value())) return false; result = body.ToObject(); return result != null; } catch (Newtonsoft.Json.JsonException) { return false; } catch (OverflowException) { return false; } } public async Task> GetClubDetails(ulong clubID, bool applyState = false) { if (!TryGetClubSession(out var apiPlayerId, out var sessionVersion)) return null; ApplyState = false; GetClubDetailsRequest getClubDetailsRequest = new GetClubDetailsRequest() { id = clubID, playerId = apiPlayerId, applyState = applyState, }; string json = await customServerMgr.ClubRequest("GetClubDetails", getClubDetailsRequest); if (!IsClubSessionCurrent(apiPlayerId, sessionVersion)) return null; if (!string.IsNullOrEmpty(json) && json != "[]") { GetClubDetailsResp clubDetails = Newtonsoft.Json.JsonConvert.DeserializeObject(json); if (clubDetails.playerIDs == null) { return null; } List clubPlayerInfos = new List(); if (myClubInfo != null && clubID == myClubInfo.id) { internalIdToPlayerId = clubDetails.playerIDs; //internalIds = clubDetails.internalIds; } List longs1 = clubDetails.playerIDs.Keys.ToList(); HashSet longs = await chatService.GetOnlineUsers(longs1); if (!IsClubSessionCurrent(apiPlayerId, sessionVersion)) return null; List clubPlayerProfiles = clubDetails.clubPlayerProfiles; SetClubPlayerProfile(clubPlayerProfiles); for (int i = 0; i < clubPlayerProfiles.Count; i++) { ClubPlayerProfile clubPlayerProfile = clubPlayerProfiles[i]; SocialInfoItemData clubPlayerInfo = new SocialInfoItemData(); clubPlayerInfo.playFabId = clubPlayerProfile.playerId; userService.GetPlayInfo(clubPlayerInfo.playFabId); clubPlayerInfo.lv = userService.GetPlayerLv(clubPlayerInfo.playFabId); //clubPlayerInfo.rank = i + 1; clubPlayerInfo.isOnline = longs != null && longs.Contains(clubPlayerProfile.internalId); clubPlayerInfo.role = clubPlayerProfile.role; if (clubPlayerProfile.lastLoginTime != null) { clubPlayerInfo.lastLoginTime = (DateTime)clubPlayerProfile.lastLoginTime; } clubPlayerInfos.Add(clubPlayerInfo); } clubPlayerInfos.Sort((x, y) => { //if (y.isOnline != x.isOnline) //{ // return y.isOnline.CompareTo(x.isOnline); //} //else { return y.lv.CompareTo(x.lv); } }); ApplyState = clubDetails.applyState; return clubPlayerInfos; } return null; } public async Task CreateClub(ClubSettingData clubSettingData) { if (!TryGetClubSession(out var apiPlayerId, out var sessionVersion)) return null; var internalId = userService.InternalId; var request = new CreateClubRequest { playerId = apiPlayerId, clubSettingData = clubSettingData }; var json = await customServerMgr.ClubRequest("CreateClub", request); if (!IsClubSessionCurrent(apiPlayerId, sessionVersion)) return null; // Code 1 means already a member; returning a club would charge the create UI again. if (!TryReadClubResponse(json, out var response, 0) || response.clubInfo == null || response.clubInfo.id == 0) return null; memberRole = EMemberRole.Owner; myClubInfo = response.clubInfo; internalIdToPlayerId[internalId] = apiPlayerId; ShowPromote(); chatService.GetConversationList((long)myClubInfo.id); MyClubInfoChange(true); return myClubInfo; } public async void ShowPromote() { if (!TryGetClubSession(out var apiPlayerId, out var sessionVersion)) return; GameObject go = await UIManager.Instance.ShowUI(UITypes.ClubPromoteNoticePopupPanel); if (!IsClubSessionCurrent(apiPlayerId, sessionVersion) || go == null) return; var ClubPromoteNoticePopupPanel = go.GetComponent(); ClubPromoteNoticePopupPanel.SetRole(memberRole); } public async Task UpdateClub(ClubSettingData clubSettingData) { UpdateClubRequest updateClubRequest = new UpdateClubRequest() { id = myClubInfo.id, clubSettingData = clubSettingData, }; string json = await customServerMgr.ClubRequest("UpdateClub", updateClubRequest); if (!string.IsNullOrEmpty(json) && json != "[]") { UpdateClubResp createClubResp = Newtonsoft.Json.JsonConvert.DeserializeObject(json); if (createClubResp.code == 0) { myClubInfo.clubSettingData = clubSettingData; GContext.Publish(new ClubSttingUpdateEvent()); return true; } } return false; } public async Task ApplyClub(ulong clubID) { if (!TryGetClubSession(out var apiPlayerId, out var sessionVersion)) return false; ApplyClubRequest applyClubRequest = new ApplyClubRequest() { playerId = apiPlayerId, //entityKey = userService.entityKey.Id, id = clubID, }; string json = await customServerMgr.ClubRequest("ApplyClub", applyClubRequest); if (!IsClubSessionCurrent(apiPlayerId, sessionVersion)) return false; if (!string.IsNullOrEmpty(json) && json != "[]") { ApplyClubResp applyClubResp = Newtonsoft.Json.JsonConvert.DeserializeObject(json); if (applyClubResp.code == 0) { memberRole = EMemberRole.Member; ToastPanel.Show(LocalizationMgr.GetText("UI_ToastPanel_41")); myClubInfo = applyClubResp.clubInfo; internalIdToPlayerId = applyClubResp.playerIDs; SetClubPlayerProfile(applyClubResp.clubPlayerProfiles); //internalIds = applyClubResp.internalIds; chatService.GetConversationList((long)myClubInfo.id); MyClubInfoChange(true); return true; } else if (applyClubResp.code == 1) { ToastPanel.Show(LocalizationMgr.GetText("UI_ToastPanel_44")); } else { ToastPanel.Show(LocalizationMgr.GetText("UI_ToastPanel_45")); } } return false; } public async void HandleApply(bool isAgree, string applyId) { if (!TryGetClubSession(out var apiPlayerId, out var sessionVersion)) return; if (applyId == "" && isAgree) return; if (applyId != "" && !IsDecimalPlayerId(applyId)) return; if (myClubInfo == null) return; if (isAgree && myClubInfo.curMembers >= myClubInfo.maxMembers) { //人数已满 return; } HandleApplyRequest handleApplyRequest = new HandleApplyRequest() { playerId = applyId, //entityKey = entityID, isAgree = isAgree, id = myClubInfo.id, }; string json = await customServerMgr.ClubRequest("HandleApply", handleApplyRequest); if (!IsClubSessionCurrent(apiPlayerId, sessionVersion)) return; if (!string.IsNullOrEmpty(json) && json != "[]") { if (!TryReadClubResponse(json, out var handleApplyResp, applyId == "" ? 4 : 0) || myClubInfo == null) return; if (handleApplyResp.code == 0 || handleApplyResp.code == 4) { if (applyId == "") { clubPlayerInfos.Clear(); RedPointManager.Instance.SetRedPointState(RedPointName.ApplyList, false); } else { for (int i = 0; i < clubPlayerInfos.Count; i++) { if (clubPlayerInfos[i].playFabId == applyId) { clubPlayerInfos.RemoveAt(i); RedPointManager.Instance.SetRedPointState(RedPointName.ApplyList, clubPlayerInfos.Count > 0 && CanAccepted); break; } } } if (isAgree) myClubInfo.curMembers++; GContext.Publish(new ClubSttingUpdateEvent()); } } } public async void GetApplyList() { if (!TryGetClubSession(out var apiPlayerId, out var sessionVersion)) return; if (myClubInfo == null) return; GetApplyListRequest getApplyListRequest = new GetApplyListRequest() { playerId = apiPlayerId, id = myClubInfo.id, }; string json = await customServerMgr.ClubRequest("GetApplyList", getApplyListRequest); if (!IsClubSessionCurrent(apiPlayerId, sessionVersion)) return; if (!string.IsNullOrEmpty(json) && json != "[]") { GetApplyListResp getApplyListResp = Newtonsoft.Json.JsonConvert.DeserializeObject(json); clubPlayerInfos = new List(); SetClubPlayerProfile(getApplyListResp.clubPlayerProfiles); for (int i = 0; i < getApplyListResp.userIDList.Count; i++) { SocialInfoItemData clubPlayerInfo = new SocialInfoItemData(); //clubPlayerInfo.rank = i + 1; //clubPlayerInfo.entityKey = getApplyListResp.entityKeys[i]; clubPlayerInfo.playFabId = getApplyListResp.userIDList[i]; userService.GetPlayInfo(clubPlayerInfo.playFabId); clubPlayerInfo.lv = userService.GetPlayerLv(clubPlayerInfo.playFabId); clubPlayerInfos.Add(clubPlayerInfo); } clubPlayerInfos.Sort((x, y) => y.lv.CompareTo(x.lv)); RedPointManager.Instance.SetRedPointState(RedPointName.ApplyList, clubPlayerInfos.Count > 0 && CanAccepted); } } void SetClubPlayerProfile(List clubPlayerProfiles) { if (clubPlayerProfiles == null) { return; } foreach (var item in clubPlayerProfiles) { if (!string.IsNullOrEmpty(item.displayName) || !string.IsNullOrEmpty(item.avatar)) { userService.SetPlayInfo(item.playerId, item.displayName, item.avatar); userService.SetPlayerLv(item.playerId, item.level); } } } public async void QuitClub(string appointId = "0") { if (!TryGetClubSession(out var apiPlayerId, out var sessionVersion)) return; if (!string.IsNullOrEmpty(appointId) && appointId != "0" && (!IsDecimalPlayerId(appointId) || appointId == apiPlayerId)) return; var request = new QuitClubRequest { playerId = apiPlayerId, appointId = appointId }; var json = await customServerMgr.ClubRequest("QuitClub", request); if (!IsClubSessionCurrent(apiPlayerId, sessionVersion)) return; if (!TryReadClubResponse(json, out var response, 0, 1)) return; chatService.OnQuit(); myClubInfo = null; ClearLikeCursorIds(); ToastPanel.Show(LocalizationMgr.GetText("UI_ToastPanel_46")); MyClubInfoChange(); } public async void Demote(string playerId) { if (!TryGetClubSession(out var apiPlayerId, out var sessionVersion)) return; if (!IsDecimalPlayerId(playerId) || playerId == apiPlayerId) return; if (myClubInfo == null) return; DemoteClubRequest demoteClubRequest = new DemoteClubRequest() { culbId = myClubInfo.id, demoteId = playerId, playerId = apiPlayerId, }; string json = await customServerMgr.ClubRequest("DemoteClub", demoteClubRequest); if (!IsClubSessionCurrent(apiPlayerId, sessionVersion)) return; } public async void Promote(string playerId, EMemberRole role) { if (!TryGetClubSession(out var apiPlayerId, out var sessionVersion)) return; if (!IsDecimalPlayerId(playerId) || playerId == apiPlayerId) return; if (myClubInfo == null) return; PromoteClubRequest promoteClubRequest = new PromoteClubRequest() { culbId = myClubInfo.id, promoteId = playerId, playerId = apiPlayerId, role = role, }; string json = await customServerMgr.ClubRequest("PromoteClub", promoteClubRequest); if (!IsClubSessionCurrent(apiPlayerId, sessionVersion)) return; } public async void Kickout(string playerId) { if (!TryGetClubSession(out var apiPlayerId, out var sessionVersion)) return; if (!IsDecimalPlayerId(playerId) || playerId == apiPlayerId) return; if (myClubInfo == null) return; KickoutClubRequest kickoutClubRequest = new KickoutClubRequest() { culbId = myClubInfo.id, kickoutId = playerId, playerId = apiPlayerId, }; string json = await customServerMgr.ClubRequest("KickoutClub", kickoutClubRequest); if (!IsClubSessionCurrent(apiPlayerId, sessionVersion)) return; if (!TryReadClubResponse(json, out var response, 0) || myClubInfo == null) return; myClubInfo.curMembers = Math.Max(0, myClubInfo.curMembers - 1); GContext.Publish(new ClubSttingUpdateEvent()); //if (!string.IsNullOrEmpty(json) && json != "[]") //{ // KickoutClubResp quitClubResp = Newtonsoft.Json.JsonConvert.DeserializeObject(json); //} } public async void ReadClubEvent() { if (!TryGetClubSession(out var apiPlayerId, out var sessionVersion)) return; ReadClubEventRequest readClubEventRequest = new ReadClubEventRequest() { playerId = apiPlayerId, }; string json = await customServerMgr.ClubRequest("ReadClubEvent", readClubEventRequest); if (!IsClubSessionCurrent(apiPlayerId, sessionVersion)) return; //if (!string.IsNullOrEmpty(json) && json != "[]") //{ // ReadClubEventResp readClubEventResp = Newtonsoft.Json.JsonConvert.DeserializeObject(json); //} } private int? signingSession; public async Task ClubSingin() { if (!TryGetClubSession(out var apiPlayerId, out var sessionVersion)) return; if (myClubInfo == null) return; if (signingSession == sessionVersion || signTime?.Date == ZZTimeHelper.UtcNow().UtcNowOffset().Date) return; var store = SaveStore; var lifetime = userService.LoginLifetime; if (!store.IsCurrent || lifetime.IsCancellationRequested) return; if (store is PlayerDataStorage.KVPlayerSaveStore) store.Read("NewPlayerDataDic").ValueOrThrow(); var player = GContext.container.Resolve(); var items = GContext.container.Resolve(); var drop = GContext.container.Resolve().TbServerConfig.ClubSignReward; var clubId = myClubInfo.id; signingSession = sessionVersion; bool mayRetry = true; try { ClubSinginRequest clubSinginRequest = new ClubSinginRequest() { playerId = apiPlayerId, id = clubId, }; string json = await customServerMgr.ClubRequest("ClubSingin", clubSinginRequest); if (!IsClubSessionCurrent(apiPlayerId, sessionVersion) || !store.IsCurrent || lifetime.IsCancellationRequested) return; if (!string.IsNullOrEmpty(json) && json != "[]") { if (!TryReadClubResponse(json, out var clubSinginResp, 0)) return; // Once the server consumed the sign-in, a failed save must not replay its reward. mayRetry = false; await PlayerDataStorage.PlayerSaveAction.RunAsync(store, "club-signin", () => { signTime = ZZTimeHelper.UtcNow().UtcNowOffset(); store.Write("ClubSignin", signTime.Value.ToString("yyyy-MM-dd HH:mm:ss")).RequireAccepted(); items.AddItemByDrop(drop, null); PlayerDataStorage.PlayerSaveAction.Present(() => GContext.Publish(new ShowData())); }, () => player.SavePlayerData(), lifetime); if (!IsClubSessionCurrent(apiPlayerId, sessionVersion) || !store.IsCurrent || lifetime.IsCancellationRequested) return; if (clubSinginResp.code == 0) { chatService.SendSystemMessage($"{MessageChatType.SI}_{apiPlayerId}"); #if AGG using (var e = GEvent.GameEvent("guild_sign")) { e.AddContent("guild_id", clubId) .AddContent("drop_list", drop); } #endif } } SetClubRed(); mayRetry = true; } finally { if (mayRetry && signingSession == sessionVersion) signingSession = null; } } public void SendSystemMessage2(int index) { if (!TryGetClubSession(out var apiPlayerId, out _)) return; chatService.SendSystemMessage2($"{apiPlayerId}_{index}"); } /// /// 获取被赠送的照片 以及其他事件 /// /// int energyAddCount = 0; public int GetEnergyAddCount() { int count = energyAddCount; energyAddCount = 0; return count; } public async void GetServiceEvent() { if (!TryGetClubSession(out var apiPlayerId, out var sessionVersion)) return; GetPictureRequest getPictureRequest = new GetPictureRequest() { playerId = apiPlayerId, }; string json = await customServerMgr.ClubRequest("GetPictureList", getPictureRequest); if (!IsClubSessionCurrent(apiPlayerId, sessionVersion)) return; if (!string.IsNullOrEmpty(json) && json != "[]") { GetPictureResp getPictureResp = Newtonsoft.Json.JsonConvert.DeserializeObject(json); energyAddCount = 0; //var pictureDatas = getPictureResp.pictureDataList; //if (pictureDatas != null && pictureDatas.Count > 0) //{ // List pictureIDs = new List(); // foreach (var pictureData in pictureDatas) // { // pictureIDs.Add(pictureData.pictureID); // } // GContext.container.Resolve().AddPictureProgress(pictureIDs); //} eventPopupDatas = getPictureResp.eventPopupDatas; if (eventPopupDatas != null && eventPopupDatas.Count > 0) { IReportService reportService = GContext.container.Resolve(); var playerData = GContext.container.Resolve(); var tables = GContext.container.Resolve(); //CampData campData = GContext.container.Resolve(); foreach (var eventPopupData in eventPopupDatas) { if (eventPopupData.type == ReportDataType.Heist) { long content = long.Parse(eventPopupData.content); if (content < 0) { content = -content; } //=====新规则===== long newContent = content / 100; long rangeT = content % 100; float range = Mathf.Clamp(rangeT, 5, 15) * 0.1f; int m = Mathf.Min(tables.TbGlobalConfig.BottleCashParamLimit, (int)newContent); float mg = (1 + playerData.benefitsCashMag) * (1 + playerData.benefitsCashMagLimited); m = Mathf.RoundToInt(m * mg * range); //=====新规则===== eventPopupData.content = m.ToString(); } if (eventPopupData.IsRead == false) { if (eventPopupData.type == ReportDataType.Energy) { #if AGG using (var e = GEvent.GameEvent("guild_request_lures_reward")) { e.AddContent("donate_userid_list", eventPopupData.content) .AddContent("reward_hook", GContext.container.Resolve().TbServerConfig.ClubLureDonateReward); if (myClubInfo != null) { e.AddContent("guild_id", myClubInfo.id); } } #endif //事件弹窗 //添加体力 playerData.SetEnergy(playerData.Energy + GContext.container.Resolve().TbServerConfig.ClubLureDonateReward); energyAddCount++; } else if (eventPopupData.type == ReportDataType.Club) { //工会事件,只在工会界面调用,弹窗展示之后才设置为已读 eventPopupDataClub = eventPopupData; } else if (eventPopupData.type == ReportDataType.Aquarium) { reportService.AddReport(new ReportData() { type = eventPopupData.type, id = eventPopupData.redirectID, playFabId = eventPopupData.playerID, content = eventPopupData.content, }); } else { //可能扣钱 if (eventPopupData.type == ReportDataType.Heist && playerData.gold > 0) { int content = int.Parse(eventPopupData.content); reportService.AddReport(new ReportData() { type = eventPopupData.type, id = eventPopupData.redirectID, playFabId = eventPopupData.playerID, content = eventPopupData.content, }); ulong gold = (ulong)content; if (gold >= playerData.gold) { playerData.SetGold(0); } else { playerData.SetGold(playerData.gold - gold); } } else if (eventPopupData.type == ReportDataType.Bomb) { reportService.AddReport(new ReportData() { type = eventPopupData.type, id = eventPopupData.redirectID, playFabId = eventPopupData.playerID, content = eventPopupData.content, }); GContext.container.Resolve().SetIsFix(true); } } } } if (energyAddCount > 0) { GContext.container.Resolve().AddFaceCustomUIData(UITypes.EventReportPopupPanel, true); } CurRewardQCount curRewardQCount = new CurRewardQCount(); GContext.Publish(curRewardQCount); int faceCount = GContext.container.Resolve().GetFaceUICount(); if (curRewardQCount.count <= 0 && faceCount <= 0) { ShowHomeReport(); } } } } public void ShowHomeReport() { ReportData reportData = GContext.container.Resolve().GetReportData(); if (reportData != null) { GContext.Publish(reportData); } } //消息点赞相关 List LikeCursorIds; string LikeCursorIdsKey = "LikeCursorIds"; void ClearLikeCursorIds() { LikeCursorIds = null; PlayerPrefs.DeleteKey(LikeCursorIdsKey); } public async void SendLike(long cursorId) { ClubLikeRequest clubLikeRequest = new ClubLikeRequest() { cursorId = cursorId, id = myClubInfo.id, }; string json = await customServerMgr.ClubRequest("ClubLike", clubLikeRequest); if (!string.IsNullOrEmpty(json) && json != "[]") { ClubLikeResp clubSinginResp = Newtonsoft.Json.JsonConvert.DeserializeObject(json); LikeCursorIds.Add(cursorId); PlayerPrefs.SetString(LikeCursorIdsKey, Newtonsoft.Json.JsonConvert.SerializeObject(LikeCursorIds)); } } public async Task<(bool, int)> GetLikeCount(long cursorId) { GetLikeCountRequest LikeCountRequest = new GetLikeCountRequest() { cursorId = cursorId, id = myClubInfo.id, }; LikeCursorIds = Newtonsoft.Json.JsonConvert.DeserializeObject>(PlayerPrefs.GetString(LikeCursorIdsKey, "[]")); bool isLike = LikeCursorIds.Contains(cursorId); int count = 0; if (isLike) { count = 1; } string json = await customServerMgr.ClubRequest("GetLikeCount", LikeCountRequest); if (!string.IsNullOrEmpty(json) && json != "[]") { GetLikeCountResp clubSinginResp = Newtonsoft.Json.JsonConvert.DeserializeObject(json); count = clubSinginResp.count; } return (isLike, count); } //体力求助相关 //聊天消息 public async Task SendHelpEnergy() { //messageID long messageID = await chatService.SendHelpEnergyMessage(1001); if (messageID > 0) { #if AGG using (var e = GEvent.GameEvent("guild_request_lures")) { e.AddContent("guild_id", myClubInfo.id); } #endif //记录今日请求 体力互助 lureDonateData.ClubLureRequestCDEnd = ZZTimeHelper.UtcNow().UtcNowOffset(). AddHours(GContext.container.Resolve().TbServerConfig.ClubLureRequestCd); SaveLureDonateData(); SetClubRed(); return true; } return false; } //服务器消息状态 public async Task SendHelpOthersEnergy(string playerId, long cursorId) { ClubHelpEnergyRequest clubHelpEnergyRequest = new ClubHelpEnergyRequest() { donateId = userService.UserId, cursorId = cursorId, playerId = playerId, id = myClubInfo.id, }; lureDonateData.ClubLureDonateCount++; string json = await customServerMgr.ClubRequest("ClubHelpEnergy", clubHelpEnergyRequest); if (!string.IsNullOrEmpty(json) && json != "[]") { #if AGG using (var e = GEvent.GameEvent("guild_donate_lures")) { e.AddContent("guild_id", myClubInfo.id) .AddContent("to_user_id", playerId) ; } #endif ClubHelpEnergyResp clubHelpEnergyResp = Newtonsoft.Json.JsonConvert.DeserializeObject(json); SaveLureDonateData(); return clubHelpEnergyResp.idContent; } else { lureDonateData.ClubLureDonateCount--; } return ""; } public async Task GetHelpEnergyState(long cursorId) { GetHelpEnergyStatusRequest helpEnergyRequest = new GetHelpEnergyStatusRequest() { cursorId = cursorId, id = myClubInfo.id, }; string json = await customServerMgr.ClubRequest("GetHelpEnergyStatus", helpEnergyRequest); if (!string.IsNullOrEmpty(json) && json != "[]") { GetHelpEnergyStatusResp helpEnergyResp = Newtonsoft.Json.JsonConvert.DeserializeObject(json); return helpEnergyResp.idContent; } return ""; } } }