초기커밋

This commit is contained in:
2025-05-01 07:20:41 +09:00
commit 98bb2e3c5c
2747 changed files with 646947 additions and 0 deletions

View File

@@ -0,0 +1,649 @@
using Google.Protobuf.WellKnownTypes;
using MetaAssets;
using Newtonsoft.Json;
using ServerControlCenter;
using ServerCore; using ServerBase;
using StackExchange.Redis;
using System.Numerics;
namespace ServerCommon
{
public class InstanceRoomInfo
{
public string roomId { get; set; } = string.Empty;
public string InstanceAddress { get; set; } = string.Empty;
public int InstancePort { get; set; } = 0;
public int InstanceId { get; set; } = 0;
public int UgcNpcCount { get; set; } = 0;
public string MyhomeGuid { get; set; } = string.Empty;
public EPlaceType InstancePlaceType { get; set; } = EPlaceType.NONE;
public Timestamp InstanceStartTime { get; set; } = DateTimeHelper.MinTime.ToTimestamp();
}
public class InstanceRoomStorage
{
private enum ExistInstanceRoomState
{
None = 0,
Different = 1,
Exist = 2,
Exception = 3
}
readonly int KEEP_INSTANCE_ROOM_TIME = (60 * 1000);
//ConnectionMultiplexer _connection = default!;
IDatabase _database = default!;
string _roomKeyPrefix = String.Empty;
string _instanceKeyPrefix = String.Empty;
public void Init(IDatabase redisDB, string keyPrefix)
{
//_connection = await ConnectionMultiplexer.ConnectAsync(configuration);
//_database = _connection.GetDatabase();
_database = redisDB;
//var servers = _connection.GetEndPoints().Select(endpoint => _connection.GetServer(endpoint));
//foreach (var server in servers)
//{
// Console.WriteLine(server.EndPoint);
//}
_roomKeyPrefix = keyPrefix;
if (_roomKeyPrefix != string.Empty && !_roomKeyPrefix.EndsWith(":"))
{
_roomKeyPrefix += ":";
}
_roomKeyPrefix += "instanceroom";
_instanceKeyPrefix = keyPrefix;
if (_instanceKeyPrefix != string.Empty && !_instanceKeyPrefix.EndsWith(":"))
{
_instanceKeyPrefix += ":";
}
_instanceKeyPrefix += "instanceroom";
}
string GetRoomIdSeqKey()
{
return $"{_roomKeyPrefix}:roomidseq";
}
public string GetRoomInfoKey(string instanceRoomId)
{
return $"{_roomKeyPrefix}:{instanceRoomId}:info";
}
public string GetRoomMemberListKey(string instanceRoomId)
{
return $"{_roomKeyPrefix}:{instanceRoomId}:memberlist";
}
public string GetInstanceRoomListKey(string instanceRoomIdBase)
{
return $"{_instanceKeyPrefix}:{instanceRoomIdBase}:roomlist";
}
public async Task<long> getRoomIdSeq()
{
var result = new Result();
var err_msg = string.Empty;
long room_id_seq = 0;
try
{
string room_id_seq_key = GetRoomIdSeqKey();
room_id_seq = await _database.StringIncrementAsync(room_id_seq_key);
}
catch (Exception e)
{
err_msg = $"Failed to getRoomIdSeq from Redis !!! : message:{e}";
result.setFail(ServerErrorCode.TryCatchException, err_msg);
Log.getLogger().fatal(result.toBasicString());
}
return room_id_seq;
}
public async Task<(Result, bool)> createInstanceRoom(string instanceRoomId, string instanceAddress, int instancePort, int instanceMetaId)
{
var result = new Result();
var err_msg = string.Empty;
var is_created = false;
try
{
string room_info_key = GetRoomInfoKey(instanceRoomId);
var instance_room_info = new InstanceRoomInfo();
instance_room_info.roomId = instanceRoomId;
instance_room_info.InstanceAddress = instanceAddress;
instance_room_info.InstancePort = instancePort;
instance_room_info.InstanceId = instanceMetaId;
instance_room_info.UgcNpcCount = 0;
// 중복 확인
var exist_instance_room_state = await isExistInstanceRoom(instanceRoomId, instanceMetaId);
switch (exist_instance_room_state)
{
case ExistInstanceRoomState.None:
{
var hash_entries = TypeConvertHelper.toHashEntries(instance_room_info);
await _database.HashSetAsync(room_info_key, hash_entries);
await _database.KeyExpireAsync(room_info_key, TimeSpan.FromMilliseconds(KEEP_INSTANCE_ROOM_TIME));
is_created = true;
}
break;
case ExistInstanceRoomState.Different:
{
err_msg = $"InstanceRoomId is Duplicated !!! : instanceRoomId:{instanceRoomId}, instanceMetaId:{instanceMetaId}";
result.setFail(ServerErrorCode.InstanceRoomIdDuplicated, err_msg);
Log.getLogger().error(err_msg);
return (result, is_created);
}
case ExistInstanceRoomState.Exist:
{
// 존재하는 방이 만드려는 방과 동일하다.
// 해당 방으로 입장한다.
}
break;
case ExistInstanceRoomState.Exception:
{
err_msg = $"Failed to isExistInstanceRoom() !!!";
result.setFail(ServerErrorCode.TryCatchException, err_msg);
Log.getLogger().error(result.toBasicString());
return (result, is_created);
}
default:
{
err_msg = $"ExistInstanceRoomState Invalid !!! : state:{exist_instance_room_state}";
result.setFail(ServerErrorCode.NotImplemented, err_msg);
Log.getLogger().error(result.toBasicString());
return (result, is_created);
}
}
}
catch (Exception e)
{
err_msg = $"Failed to createInstanceRoom from Redis !!! : message:{e}";
result.setFail(ServerErrorCode.TryCatchException, err_msg);
Log.getLogger().fatal(err_msg);
}
return (result, is_created);
}
async Task<ExistInstanceRoomState> isExistInstanceRoom(string instanceRoomId, int instanceMetaId)
{
var result = new Result();
var err_msg = string.Empty;
try
{
string instance_room_info_key = GetRoomInfoKey(instanceRoomId);
// 기존 방 정보 얻기
var value = await _database.HashGetAllAsync(instance_room_info_key, CommandFlags.PreferReplica);
if (value.Length <= 0)
return ExistInstanceRoomState.None;
// 내가 원하는 방인지 확인
var instance_room_info = TypeConvertHelper.toClassFromHashEntries<InstanceRoomInfo>(value);
if (instance_room_info.roomId != instanceRoomId || instance_room_info.InstanceId != instanceMetaId)
return ExistInstanceRoomState.Different;
}
catch (Exception e)
{
err_msg = $"Failed to isExistInstanceRoom from Redis !!! : message:{e}";
result.setFail(ServerErrorCode.TryCatchException, err_msg);
Log.getLogger().fatal(result.toBasicString());
return ExistInstanceRoomState.Exception;
}
return ExistInstanceRoomState.Exist;
}
public async Task<Result> addInstanceRoomList(string instanceRoomIdBase, string instanceRoomId)
{
var result = new Result();
var err_msg = string.Empty;
try
{
string instance_room_list_key = GetInstanceRoomListKey(instanceRoomIdBase);
await _database.SortedSetAddAsync(instance_room_list_key, instanceRoomId, 0);
await _database.KeyExpireAsync(instance_room_list_key, TimeSpan.FromMilliseconds(KEEP_INSTANCE_ROOM_TIME));
}
catch (Exception e)
{
err_msg = $"Failed to addInstanceRoomList from Redis !!! : message:{e}";
result.setFail(ServerErrorCode.TryCatchException, err_msg);
Log.getLogger().fatal(err_msg);
}
return result;
}
public async Task<Result> joinInstanceRoom(string userGuid, string instanceRoomId, int limitCount)
{
var result = new Result();
var err_msg = string.Empty;
try
{
string instance_room_member_list_key = GetRoomMemberListKey(instanceRoomId);
var push_after_length = await _database.ListRightPushAsync(instance_room_member_list_key, userGuid);
if (push_after_length > limitCount)
{
await _database.ListTrimAsync(instance_room_member_list_key, 0, limitCount - 1);
var trim_after_position = await _database.ListPositionAsync(instance_room_member_list_key, userGuid);
if (trim_after_position == -1)
{
err_msg = $"roomId:{instanceRoomId} is full !!! : pushAfterLength:{push_after_length}, limitCount:{limitCount}, trimAfterPosition:{trim_after_position} - userGuid:{userGuid}";
result.setFail(ServerErrorCode.InstanceRoomIsFull, err_msg);
Log.getLogger().debug(err_msg);
return result;
}
}
await _database.KeyExpireAsync(instance_room_member_list_key, TimeSpan.FromMilliseconds(KEEP_INSTANCE_ROOM_TIME));
}
catch (Exception e)
{
err_msg = $"Failed to joinInstanceRoom from Redis !!! : message:{e} - userGuid:{userGuid}";
result.setFail(ServerErrorCode.TryCatchException, err_msg);
Log.getLogger().fatal(result.toBasicString());
}
return result;
}
public async Task<Result> increaseInstanceRoomScore(string instanceRoomIdBase, string instanceRoomId)
{
var result = new Result();
var err_msg = string.Empty;
try
{
string instance_room_list_key = GetInstanceRoomListKey(instanceRoomIdBase);
await _database.SortedSetIncrementAsync(instance_room_list_key, instanceRoomId, 1);
}
catch (Exception e)
{
err_msg = $"Failed to increaseInstanceRoomScore from Redis !!! : message:{e}";
result.setFail(ServerErrorCode.TryCatchException, err_msg);
Log.getLogger().fatal(result.toBasicString());
}
return result;
}
public async Task<Result> increaseInstanceRoomUgcNpcScore(string instanceRoomId)
{
var result = new Result();
var err_msg = string.Empty;
try
{
string instance_room_info_key = GetRoomInfoKey(instanceRoomId);
await _database.HashIncrementAsync(instance_room_info_key, nameof(InstanceRoomInfo.UgcNpcCount), 1);
}
catch (Exception e)
{
var error_code = ServerErrorCode.TryCatchException;
err_msg = $"Failed to decreaseInstanceRoomUgcNpcScore from Redis !!! : : errorCode{error_code}, errMsg:{e.Message}";
result.setFail(error_code, err_msg);
Log.getLogger().error(err_msg);
}
return result;
}
public async Task<List<string>> GetInstanceRoomMemberList(string roomId)
{
List<string> returnList = new();
string roomKey = GetRoomMemberListKey(roomId);
var roomMemberList = await _database.ListRangeAsync(roomKey);
if (roomMemberList == null) return returnList;
returnList.AddRange(roomMemberList.Select(x => x.ToString()));
return returnList;
}
public async Task<Result> leaveInstanceRoom(string userGuid, string instanceRoomId)
{
var result = new Result();
var err_msg = string.Empty;
try
{
string instance_room_list_key = GetRoomMemberListKey(instanceRoomId);
await _database.ListRemoveAsync(instance_room_list_key, userGuid);
}
catch (Exception e)
{
err_msg = $"Failed to leaveInstanceRoom from Redis !!! : message:{e} - userGuid:{userGuid}";
result.setFail(ServerErrorCode.TryCatchException, err_msg);
Log.getLogger().fatal(err_msg);
}
return result;
}
public async Task<Result> decreaseInstanceRoomScore(string instanceRoomIdBase, string instanceRoomId)
{
var result = new Result();
var err_msg = string.Empty;
try
{
string instance_room_list_key = GetInstanceRoomListKey(instanceRoomIdBase);
await _database.SortedSetDecrementAsync(instance_room_list_key, instanceRoomId, 1);
}
catch (Exception e)
{
var error_code = ServerErrorCode.TryCatchException;
err_msg = $"Failed to decreaseInstanceRoomScore from Redis !!! : : errorCode{error_code}, errMsg:{e.Message}";
result.setFail(error_code, err_msg);
Log.getLogger().error(err_msg);
}
return result;
}
public async Task<Result> decreaseInstanceRoomUgcNpcScore(string instanceRoomId)
{
var result = new Result();
var err_msg = string.Empty;
try
{
string instance_room_info_key = GetRoomInfoKey(instanceRoomId);
await _database.HashDecrementAsync(instance_room_info_key, nameof(InstanceRoomInfo.UgcNpcCount), 1);
}
catch (Exception e)
{
var error_code = ServerErrorCode.TryCatchException;
err_msg = $"Failed to decreaseInstanceRoomUgcNpcScore from Redis !!! : : errorCode{error_code}, errMsg:{e.Message}";
result.setFail(error_code, err_msg);
Log.getLogger().error(err_msg);
}
return result;
}
public async Task<Result> deleteInstanceRoom(string instanceRoomId)
{
var result = new Result();
var err_msg = string.Empty;
try
{
string roomInfoKey = GetRoomInfoKey(instanceRoomId);
string roomMemberListKey = GetRoomMemberListKey(instanceRoomId);
await _database.KeyDeleteAsync(roomInfoKey);
await _database.KeyDeleteAsync(roomMemberListKey);
}
catch (Exception e)
{
var error_code = ServerErrorCode.TryCatchException;
err_msg = $"Failed to deleteInstanceRoom from Redis !!! : errorCode{error_code}, errMsg:{e.Message}";
result.setFail(error_code, err_msg);
Log.getLogger().error(err_msg);
}
return result;
}
public async Task<Result> removeInstanceRoomList(string instanceRoomIdBase, string instanceRoomId)
{
var result = new Result();
var err_msg = string.Empty;
try
{
string instance_room_list_key = GetInstanceRoomListKey(instanceRoomIdBase);
await _database.SortedSetRemoveAsync(instance_room_list_key, instanceRoomId);
}
catch (Exception e)
{
var error_code = ServerErrorCode.TryCatchException;
err_msg = $"Failed to removeInstanceRoomList from Redis !!! : : errorCode{error_code}, errMsg:{e.Message}";
result.setFail(error_code, err_msg);
Log.getLogger().error(err_msg);
}
return result;
}
public async Task<InstanceRoomInfo?> GetInstanceRoomInfo(string instanceRoomId)
{
var result = new Result();
var err_msg = string.Empty;
try
{
var instance_room_info_key = GetRoomInfoKey(instanceRoomId);
var value = await _database.HashGetAllAsync(instance_room_info_key, CommandFlags.PreferReplica);
if (value.Length <= 0) return null;
return TypeConvertHelper.toClassFromHashEntries<InstanceRoomInfo>(value);
}
catch (Exception e)
{
err_msg = $"Failed to GetInstanceRoomInfo() from Redis !!! : message:{e}";
result.setFail(ServerErrorCode.TryCatchException, err_msg);
Log.getLogger().error(err_msg);
return null;
}
}
public async Task<Result> setInstanceRoomExtraInfo(string roomId, EPlaceType placeType, DateTime startTime)
{
var result = new Result();
try
{
var instance_info = await GetInstanceRoomInfo(roomId);
if (null == instance_info)
{
result.setFail(ServerErrorCode.NotExistInstanceRoom);
return result;
}
instance_info.InstancePlaceType = placeType;
instance_info.InstanceStartTime = startTime.ToTimestamp();
var room_info_key = GetRoomInfoKey(roomId);
var hash_entries = TypeConvertHelper.toHashEntries(instance_info);
await _database.HashSetAsync(room_info_key, hash_entries);
await _database.KeyExpireAsync(room_info_key, TimeSpan.FromMilliseconds(KEEP_INSTANCE_ROOM_TIME));
return result;
}
catch (Exception ex)
{
result.setFail(ServerErrorCode.InstanceRoomException, $"{ex}");
Log.getLogger().error($"{ex.ToString()}");
return result;
}
}
public async Task<Result> setInstanceRoomMyhomeGuid(string roomId, string myhomeGuid)
{
var result = new Result();
var err_msg = string.Empty;
try
{
var instance_info = await GetInstanceRoomInfo(roomId);
if (null == instance_info)
{
err_msg = $"Failed to GetInstanceRoomInfo() !!! : instanceRoomId:{roomId}";
result.setFail(ServerErrorCode.InstanceRoomNotExistAtRedis, err_msg);
Log.getLogger().error(result.toBasicString());
return result;
}
instance_info.MyhomeGuid = myhomeGuid;
var room_info_key = GetRoomInfoKey(roomId);
var hash_entries = TypeConvertHelper.toHashEntries(instance_info);
await _database.HashSetAsync(room_info_key, hash_entries);
await _database.KeyExpireAsync(room_info_key, TimeSpan.FromMilliseconds(KEEP_INSTANCE_ROOM_TIME));
return result;
}
catch (Exception e)
{
err_msg = $"Failed to setInstanceRoomMyhomeGuid from Redis !!! : message:{e}";
result.setFail(ServerErrorCode.TryCatchException, err_msg);
Log.getLogger().fatal(err_msg);
return result;
}
}
public async Task<List<string>> GetInstanceRoomList(string instanceRoomIdBase, int limitCount)
{
var err_msg = string.Empty;
List<string> result_room_list = new List<string>();
try
{
string instance_room_list_key = GetInstanceRoomListKey(instanceRoomIdBase);
var room_list = await _database.SortedSetRangeByScoreAsync(instance_room_list_key, 0, limitCount, Exclude.Stop, Order.Descending);
foreach (var roomId in room_list)
{
result_room_list.Add(roomId.ToString());
}
}
catch (Exception e)
{
var error_code = ServerErrorCode.TryCatchException;
err_msg = $"Failed to get InstanceRoomList from Redis !!! : : errorCode{error_code}, errMsg:{e.Message}";
Log.getLogger().error(err_msg);
}
return result_room_list;
}
public async Task<int> getInstanceRoomListTotalUserCount(string instanceRoomIdBase)
{
var err_msg = string.Empty;
int total_user_count = 0;
try
{
string instance_room_list_key = GetInstanceRoomListKey(instanceRoomIdBase);
var sorted_set_entities = await _database.SortedSetRangeByRankWithScoresAsync(instance_room_list_key);
foreach (var entity in sorted_set_entities)
{
if (entity.Score < 0)
continue;
total_user_count += (int)entity.Score;
}
}
catch (Exception e)
{
var error_code = ServerErrorCode.TryCatchException;
err_msg = $"Failed to get InstanceRoomListTotalUserCount from Redis !!! : : errorCode{error_code}, errMsg:{e.Message}";
Log.getLogger().error(err_msg);
}
return total_user_count;
}
public async Task<int> getInstanceRoomUserCount(string instanceRoomId)
{
var err_msg = string.Empty;
int user_count = 0;
try
{
var room_member_list_key = GetRoomMemberListKey(instanceRoomId);
user_count = (int)await _database.ListLengthAsync(room_member_list_key, CommandFlags.PreferReplica);
}
catch (Exception e)
{
var error_code = ServerErrorCode.TryCatchException;
err_msg = $"Failed to get InstanceRoomUserCount from Redis !!! : : errorCode{error_code}, errMsg:{e.Message}";
Log.getLogger().error(err_msg);
}
return user_count;
}
public async Task<Result> keepInstanceRoom(string instanceRoomId)
{
var result = new Result();
var err_msg = string.Empty;
try
{
string instance_room_info_key = GetRoomInfoKey(instanceRoomId);
string intstance_room_member_list_key = GetRoomMemberListKey(instanceRoomId);
await _database.KeyExpireAsync(instance_room_info_key, TimeSpan.FromMilliseconds(KEEP_INSTANCE_ROOM_TIME));
await _database.KeyExpireAsync(intstance_room_member_list_key, TimeSpan.FromMilliseconds(KEEP_INSTANCE_ROOM_TIME));
}
catch(Exception e)
{
var error_code = ServerErrorCode.TryCatchException;
err_msg = $"Failed to KeepInstanceRoom from Redis !!! : : errorCode{error_code}, errMsg:{e.Message}";
result.setFail(error_code, err_msg);
Log.getLogger().error(err_msg);
}
return result;
}
public async Task<Result> keepInstanceRoomList(string instanceRoomIdBase)
{
var result = new Result();
var err_msg = string.Empty;
try
{
string instance_room_list_key = GetInstanceRoomListKey(instanceRoomIdBase);
await _database.KeyExpireAsync(instance_room_list_key, TimeSpan.FromMilliseconds(KEEP_INSTANCE_ROOM_TIME), ExpireWhen.Always, CommandFlags.FireAndForget);
}
catch (Exception e)
{
var error_code = ServerErrorCode.TryCatchException;
err_msg = $"Failed to KeepInstanceRoomList from Redis !!! : : errorCode{error_code}, errMsg:{e.Message}";
result.setFail(error_code, err_msg);
Log.getLogger().error(err_msg);
}
return result;
}
}
}