using Newtonsoft.Json; using Google.Protobuf; using Google.Protobuf.WellKnownTypes; using StackExchange.Redis; using ServerCore; using ServerBase; using ServerCommon; using ServerCommon.BusinessLogDomain; using MetaAssets; namespace ServerCommon; public class FriendRequestCache : CacheBase { [JsonProperty("sender_guid")] public string m_sender_guid { get; set; } = string.Empty; [JsonProperty("receiver_guid")] public string m_receiver_guid { get; set; } = string.Empty; [JsonProperty("is_new")] public Int32 m_is_new { get; set; } = 0; [JsonProperty("request_time")] public DateTime m_request_time { get; set; } = new(); public FriendRequestCache(string sender, string receiver, bool isNew, DateTime requestTime) { m_sender_guid = sender; m_receiver_guid = receiver; m_is_new = isNew ? 1: 0; m_request_time = requestTime; } } public class FriendReqCacheRequest : RedisRequestPrivateBase { private string m_guid = string.Empty; private string m_friend_guid = string.Empty; public FriendReqCacheRequest(UserBase owner, string myGuid, string friendGuid, RedisConnector redisConnector) : base(owner, redisConnector) { m_guid = myGuid; m_friend_guid = friendGuid; } public FriendReqCacheRequest(UserBase owner, string myGuid, RedisConnector redisConnector) : base(owner, redisConnector) { m_guid = myGuid; m_friend_guid = string.Empty; } public override string toBasicString() { return $"SendedFriendRequestCache: In:m_guid:{m_guid}"; } protected override string onMakeKey() { return $"friendrequest:{m_guid}"; } private string makeSendKey(string guid) { return $"sendedfriendrequest:{guid}"; } private string makeRecvKey(string guid) { return $"receivedfriendrequest:{guid}"; } public async Task> getSendedFriendRequests() { var database = getDatabase(); string key = makeSendKey(m_guid); List sendedFriendRequests = new(); try { var hashes = await database.HashGetAllAsync(key, CommandFlags.PreferReplica); //여기서 가져와서 RequestList로 만들어줘야 한다. foreach (var entry in hashes) { // RedisValue를 문자열로 변환하여 JSON 디시리얼라이즈 var value_string = entry.Value.ToString(); var obj = JsonConvert.DeserializeObject(value_string); if(obj == null) { string err_msg = $"Failed to get FriendCache from Redis !!! : : value_string:{entry.Value} - {getOwner().toBasicString()}"; Log.getLogger().error(err_msg); continue; } var is_active = await deleteOldRequest(obj.m_request_time, obj.m_sender_guid, obj.m_receiver_guid); if (is_active) { sendedFriendRequests.Add(obj); } } } catch (Exception e) { string err_msg = $"Failed to get FriendCache from Redis !!! : : errMsg:{e.Message} - {getOwner().toBasicString()}"; Log.getLogger().error(err_msg); return new(); } return sendedFriendRequests; } public async Task> getReceivedFriendRequests() { var database = getDatabase(); string key = makeRecvKey(m_guid); List recvedFriendRequests = new(); try { var hashes = await database.HashGetAllAsync(key, CommandFlags.PreferReplica); //여기서 가져와서 RequestList로 만들어줘야 한다. foreach (var entry in hashes) { var value_string = entry.Value.ToString(); var obj = JsonConvert.DeserializeObject(value_string); if (obj == null) { string err_msg = $"Failed to get FriendCache from Redis !!! : : value_string:{value_string} - {getOwner().toBasicString()}"; Log.getLogger().error(err_msg); continue; } var is_active = await deleteOldRequest(obj.m_request_time, obj.m_sender_guid, obj.m_receiver_guid); if (is_active) { recvedFriendRequests.Add(obj); } } } catch (Exception e) { string err_msg = $"Exception !!!, Failed to get FriendCache from Redis !!! : exception:{e} - {getOwner().toBasicString()}"; Log.getLogger().error(err_msg); return new(); } return recvedFriendRequests; } private async Task deleteOldRequest(DateTime requestTime, string sender, string receiver) { var now = DateTimeHelper.Current; var expire_time = requestTime.AddSeconds(MetaHelper.GameConfigMeta.SentFriendRequestValidTime); if (now > expire_time) { await deleteCache(sender, receiver); return false; } return true; } public async Task addFriendRequest(string senderGuid, string receiverGuid, DateTime now) { var result = new Result(); var database = getDatabase(); var tran = database.CreateTransaction(); { FriendRequestCache send_req_cache = new FriendRequestCache(senderGuid, receiverGuid, true, now); FriendRequestCache receuve_req_cache = new FriendRequestCache(senderGuid, receiverGuid, true, now); await database.HashSetAsync(makeSendKey(senderGuid), receiverGuid, JsonConvert.SerializeObject(send_req_cache)); await database.HashSetAsync(makeRecvKey(receiverGuid), senderGuid, JsonConvert.SerializeObject(receuve_req_cache)); } bool ret = tran.Execute(); if (false == ret) { string err_msg = $"Failed to RedisHashSets Set Failed to Redis !!! : : senderGuid:{senderGuid}, receiverGuid:{receiverGuid}"; result.setFail(ServerErrorCode.RedisHashesWriteFailed, err_msg); Log.getLogger().error(result.toBasicString()); return result; } return result; } public async Task confirmReceivedFriendRequest() { var result = new Result(); var database = getDatabase(); var redis_value = await database.HashGetAsync(makeRecvKey(m_guid), m_friend_guid, CommandFlags.PreferReplica); var value_string = redis_value.ToString(); var cache = JsonConvert.DeserializeObject(value_string); if (cache == null) { string err_msg = $"Failed to get FriendCache from Redis !!! : : redis_value:{redis_value} - {getOwner().toBasicString()}"; Log.getLogger().error(err_msg); result.setFail(ServerErrorCode.RedisHashesReadFailed, err_msg); return result; } cache.m_is_new = 0; await database.HashSetAsync(makeRecvKey(m_guid), m_friend_guid, JsonConvert.SerializeObject(cache)); return result; } public async Task deleteFriendByReply() { var result = await deleteCache(m_friend_guid, m_guid);//수락은은 요청 받은 사람이 하는 것이므로 sender가 friendGuid return result; } public async Task cancelFriendRequest() { var result = await deleteCache(m_guid, m_friend_guid); return result; } public async Task refuseFriendRequest() { var result = await deleteCache(m_friend_guid, m_guid);//거절은 요청 받은 사람이 하는 것이므로 sender가 friendGuid return result; } public async Task deleteCache(string senderGuid, string receiverGuid) { var result = new Result(); var database = getDatabase(); var tran = database.CreateTransaction(); { await database.HashDeleteAsync(makeSendKey(senderGuid), receiverGuid); await database.HashDeleteAsync(makeRecvKey(receiverGuid), senderGuid); } bool ret = tran.Execute(); if (false == ret) { string err_msg = $"Failed to RedisHashSets delete Failed to Redis !!! : : senderGuid:{senderGuid}, receiverGuid:{receiverGuid}"; result.setFail(ServerErrorCode.RedisHashesWriteFailed, err_msg); Log.getLogger().error(err_msg); return result; } return result; } }