초기커밋

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,42 @@
using ServerCommon;
using ServerCore; using ServerBase;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace GameServer
{
internal class RentalAction : EntityActionBase
{
public RentalAction(Rental owner)
: base(owner)
{ }
public override async Task<Result> onInit()
{
var result = new Result();
return await Task.FromResult(result);
}
public override void onClear()
{
return;
}
public bool isRentalFinsh()
{
var rental = getOwner() as Rental;
NullReferenceCheckHelper.throwIfNull(rental, () => $"rental is null !!!");
var rental_attribute = rental.getEntityAttribute<RentalAttribute>();
NullReferenceCheckHelper.throwIfNull(rental_attribute, () => $"rental_attribute is null !!!");
if (DateTime.UtcNow > rental_attribute.RentalFinishTime)
return true;
return false;
}
}
}

View File

@@ -0,0 +1,140 @@
using ServerCommon;
using ServerCore; using ServerBase;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using static ClientToGameReq.Types;
namespace GameServer
{
internal class RentalAgentAction : EntityActionBase
{
ConcurrentDictionary<(int, int, int), Rental> m_rentals = new();
public RentalAgentAction(Player owner)
: base(owner)
{ }
public override async Task<Result> onInit()
{
var result = new Result();
return await Task.FromResult(result);
}
public override void onClear()
{
return;
}
public List<Rental> getRentals()
{
return m_rentals.Values.ToList();
}
public async Task<Result> tryAddRentalFromDoc(RentalDoc rentalDoc)
{
var result = new Result();
var err_msg = string.Empty;
var player = getOwner() as Player;
NullReferenceCheckHelper.throwIfNull(player, () => $"player is null !!!");
var server_logic = GameServerApp.getServerLogic();
var rental = new Rental(player);
await rental.onInit();
var rental_attribute = rental.getEntityAttribute<RentalAttribute>();
NullReferenceCheckHelper.throwIfNull(rental_attribute, () => $"rental_attribute is null !!! - {player.toBasicString()}");
if (!rental_attribute.copyEntityAttributeFromDoc(rentalDoc))
{
err_msg = $"Failed to copyEntityAttributeFromDoc() !!! to:{rental_attribute.getTypeName()}, from:{rentalDoc.getTypeName()} : {this.getTypeName()}";
result.setFail(ServerErrorCode.DynamoDbDocCopyToEntityAttributeFailed, err_msg);
Log.getLogger().error(result.toBasicString());
return result;
}
if (!m_rentals.TryAdd((rental_attribute.LandMetaId, rental_attribute.BuildingMetaId, rental_attribute.Floor), rental))
{
err_msg = $"Failed to TryAdd() !!! : {rental.toBasicString()} : {this.getTypeName()}";
result.setFail(ServerErrorCode.RentalDocLoadDuplicatedRental, err_msg);
Log.getLogger().error(result.toBasicString());
return result;
}
return result;
}
public void addRental(int landMetaId, int buildingMetaId, int floor, Rental rental)
{
m_rentals[(landMetaId, buildingMetaId, floor)] = rental;
}
public bool isRentalMyhome(string myhomeGuid)
{
foreach (var rental in m_rentals.Values)
{
var rental_attribute = rental.getEntityAttribute<RentalAttribute>();
if (rental_attribute == null)
continue;
if (rental_attribute.MyhomeGuid == myhomeGuid)
return true;
}
return false;
}
public (int, int, int) getAddrressFromMyhome(string myhomeGuid)
{
var land_meta_id = 0;
var building_meta_id = 0;
var floor = 0;
foreach (var rental in m_rentals.Values)
{
var rental_attribute = rental.getEntityAttribute<RentalAttribute>();
if (rental_attribute == null)
continue;
if (rental_attribute.MyhomeGuid == myhomeGuid)
{
land_meta_id = rental_attribute.LandMetaId;
building_meta_id = rental_attribute.BuildingMetaId;
floor = rental_attribute.Floor;
}
}
return (land_meta_id, building_meta_id, floor);
}
public override async Task onTick()
{
await Task.CompletedTask;
var remove_address = new List<(int, int, int)>();
foreach (var (address, rental) in m_rentals)
{
var rental_action = rental.getEntityAction<RentalAction>();
NullReferenceCheckHelper.throwIfNull(rental_action, () => $"rental_action is null !!!");
if (rental_action.isRentalFinsh())
{
remove_address.Add(address);
}
}
foreach (var address in remove_address)
{
m_rentals.TryRemove(address, out _);
}
}
}
}

View File

@@ -0,0 +1,91 @@
using Google.Protobuf;
using Google.Protobuf.WellKnownTypes;
using ServerCore;
using ServerBase;
using ServerCommon;
using ServerCommon.BusinessLogDomain;
using MetaAssets;
namespace GameServer;
public class RentalVisitAction : EntityActionBase
{
public RentalVisitAction(Player owner)
: base(owner)
{ }
public override async Task<Result> onInit()
{
var result = new Result();
return await Task.FromResult(result);
}
public override void onClear()
{
return;
}
public Result setRentalInstanceVisitFromDoc(RentalInstanceVisitDoc doc)
{
var result = new Result();
var owner = getOwner() as Player;
NullReferenceCheckHelper.throwIfNull(owner, () => $"owner is null !!!");
var rental_instance_visit_attribute = owner.getEntityAttribute<RentalInstanceVisitAttribute>();
if (rental_instance_visit_attribute is null)
{
var err_msg = $"Fail to get rental_instance_visit_attribute";
result.setFail(ServerErrorCode.EntityAttributeNotFound, err_msg);
return result;
}
if (false == doc.getAttribWrappers().TryGetValue(typeof(RentalInstanceVisitAttrib), out var to_copy_doc_attrib))
{
var err_msg = $"Fail to get RentalInstanceVisitAttrib";
result.setFail(ServerErrorCode.EntityAttributeNotFound, err_msg);
return result;
}
var attrib_base = to_copy_doc_attrib.getAttribBase();
var doc_attrib = attrib_base as RentalInstanceVisitAttrib;
if (doc_attrib is null)
{
var err_msg = $"Fail to get RentalInstanceVisitAttrib";
result.setFail(ServerErrorCode.EntityAttributeNotFound, err_msg);
return result;
}
foreach (var visitor in doc_attrib.m_rental_instance_visit_guid)
{
rental_instance_visit_attribute.m_rental_instance_visit.AddOrUpdate(visitor.Key, visitor.Value, (key, oldValue) => visitor.Value);
}
rental_instance_visit_attribute.m_next_refresh_time = doc_attrib.m_next_refresh_time;
rental_instance_visit_attribute.syncOriginDocBaseWithNewDoc<RentalInstanceVisitAttribute>(doc);
return result;
}
public void refresh(RentalInstanceVisitAttribute attribute)
{
var player = getOwner();
NullReferenceCheckHelper.throwIfNull(player, () => $"player is null !!!");
var now = DateTimeHelper.Current;
//시간 안됐으므로 리턴
if (attribute.m_next_refresh_time > now) return;
attribute.m_next_refresh_time = DateTimeHelper.Current.Date.AddDays(1);
attribute.m_rental_instance_visit = new();
attribute.modifiedEntityAttribute(true);
}
}

View File

@@ -0,0 +1,113 @@
using Google.Protobuf;
using Google.Protobuf.WellKnownTypes;
using ServerCore;
using ServerBase;
using ServerCommon;
using ServerCommon.BusinessLogDomain;
using MetaAssets;
namespace GameServer;
public class DBQRentalInstanceVisitReadAll : QueryExecutorBase
{
private string m_combination_key_for_pk = string.Empty;
private string m_pk = string.Empty;
private readonly List<RentalInstanceVisitDoc> m_to_read_rental_instance_visit_doc = new();
public DBQRentalInstanceVisitReadAll(string combinationKeyForPK /*onwer_guid*/)
: base(typeof(DBQRentalInstanceVisitReadAll).Name)
{
m_combination_key_for_pk = combinationKeyForPK;
}
//===================================================================================================
// DB 쿼리 직전에 준비해야 할 로직들을 작성한다.
//===================================================================================================
public override Task<Result> onPrepareQuery()
{
var result = new Result();
var owner = getOwner();
NullReferenceCheckHelper.throwIfNull(owner, () => $"owner is null !!!");
var doc = new RentalInstanceVisitDoc(m_combination_key_for_pk);
var error_code = doc.onApplyPKSK();
if (error_code.isFail())
{
var err_msg = $"Failed to onApplyPKSK() !!! : {error_code.toBasicString()} - {toBasicString()}, {owner.toBasicString()}";
result.setFail(error_code, err_msg);
Log.getLogger().error(result.toBasicString());
return Task.FromResult(result);
}
m_pk = doc.getPK();
return Task.FromResult(result);
}
//===================================================================================================
// onPrepareQuery()를 성공할 경우 호출된다.
//===================================================================================================
public override async Task<Result> onQuery()
{
var result = new Result();
var err_msg = string.Empty;
var query_batch = getQueryBatch();
NullReferenceCheckHelper.throwIfNull(query_batch, () => $"query_batch is null !!!");
var db_connector = query_batch.getDynamoDbConnector();
var query_config = db_connector.makeQueryConfigForReadByPKSK(m_pk);
(result, var read_docs) = await db_connector.simpleQueryDocTypesWithQueryOperationConfig<RentalInstanceVisitDoc>(query_config, eventTid: query_batch.getTransId());
if (result.isFail())
{
//데이터 없으면 여기서 그냥 메모리에만 넣어준다.
Log.getLogger().warn($"RentalInstanceVisitDoc not exitst, so make new Data {result.toBasicString()}");
return new();
}
m_to_read_rental_instance_visit_doc.AddRange(read_docs);
var owner = getOwner();
NullReferenceCheckHelper.throwIfNull(owner, () => $"owner is null !!!");
var rental_visit_action = owner.getEntityAction<RentalVisitAction>();
NullReferenceCheckHelper.throwIfNull(rental_visit_action, () => $"rental_visit_action is null !!!");
foreach (var read_doc in read_docs)
{
var set_result = rental_visit_action.setRentalInstanceVisitFromDoc(read_doc);
if (set_result.isFail())
{
Log.getLogger().error(result.toBasicString());
continue;
}
}
return result;
}
//===================================================================================================
// DB 쿼리를 성공하고, doFnCommit()가 QueryResultType.NotCalledQueryFunc를 반환할 경우 호출된다.
//===================================================================================================
public override Task onQueryResponseCommit()
{
return Task.CompletedTask;
}
//===================================================================================================
// DB 쿼리를 실패하고, doFnRollback()가 QueryResultType.NotCalledQueryFunc를 반환할 경우 호출된다.
//===================================================================================================
public override Task onQueryResponseRollback(Result errorResult)
{
return Task.CompletedTask;
}
private new Player? getOwner() => getQueryBatch()?.getLogActor() as Player;
}

View File

@@ -0,0 +1,120 @@
using ServerCommon;
using ServerCore; using ServerBase;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace GameServer
{
internal class DBQRentalReadAll : QueryExecutorBase
{
private string m_combination_key_for_pk = string.Empty;
private string m_pk = string.Empty;
private readonly List<RentalDoc> m_to_read_rental_docs = new();
public DBQRentalReadAll(string combinationKeyForPK)
: base(typeof(DBQRentalReadAll).Name)
{
m_combination_key_for_pk = combinationKeyForPK;
}
//=====================================================================================
// DB 쿼리 직전에 준비해야 할 로직들을 작성한다.
//=====================================================================================
public override async Task<Result> onPrepareQuery()
{
var result = new Result();
var err_msg = string.Empty;
var owner = getOwner() as Player;
NullReferenceCheckHelper.throwIfNull(owner, () => $"owner is null !!!");
var doc = new RentalDoc();
doc.setCombinationKeyForPK(m_combination_key_for_pk);
var error_code = doc.onApplyPKSK();
if (error_code.isFail())
{
err_msg = $"Failed to onApplyPKSK() !!! : {error_code.toBasicString()} - {toBasicString()}, {owner.toBasicString()}";
result.setFail(error_code, err_msg);
Log.getLogger().error(result.toBasicString());
return result;
}
m_pk = doc.getPK();
return await Task.FromResult(result);
}
//=====================================================================================
// onPrepareQuery()를 성공할 경우 호출된다.
//=====================================================================================
public override async Task<Result> onQuery()
{
var result = new Result();
var err_msg = string.Empty;
var owner = getOwner() as Player;
NullReferenceCheckHelper.throwIfNull(owner, () => $"owner is null !!!");
var query_batch = getQueryBatch();
NullReferenceCheckHelper.throwIfNull(query_batch, () => $"query_batch is null !!!");
var db_connector = query_batch.getDynamoDbConnector();
var query_config = db_connector.makeQueryConfigForReadByPKOnly(m_pk);
(result, var read_docs) = await db_connector.simpleQueryDocTypesWithQueryOperationConfig<RentalDoc>(query_config, eventTid: query_batch.getTransId());
if (result.isFail())
{
return result;
}
var rental_agent_action = owner.getEntityAction<RentalAgentAction>();
NullReferenceCheckHelper.throwIfNull(rental_agent_action, () => $"rental_agent_action is null !!!");
foreach (var read_doc in read_docs)
{
var rental_attrib = read_doc.getAttrib<RentalAttrib>();
NullReferenceCheckHelper.throwIfNull(rental_attrib, () => $"rental_attrib is null !!!");
if (rental_attrib.RentalFinishTime < DateTime.UtcNow)
continue;
result = await rental_agent_action.tryAddRentalFromDoc(read_doc);
if (result.isFail())
{
return result;
}
m_to_read_rental_docs.Add(read_doc);
}
return await Task.FromResult(result);
}
public List<RentalDoc> getToReadRentalDocs() => m_to_read_rental_docs;
//=====================================================================================
// DB 쿼리를 성공하고, doFnCommit()가 QueryResultType.NotCalledQueryFunc를 반환할 경우 호출된다.
//=====================================================================================
public override async Task onQueryResponseCommit()
{
await Task.CompletedTask;
return;
}
//=====================================================================================
// DB 쿼리를 실패하고, doFnRollback()가 QueryResultType.NotCalledQueryFunc를 반환할 경우 호출된다.
//=====================================================================================
public override async Task onQueryResponseRollback(Result errorResult)
{
await Task.CompletedTask;
return;
}
}
}

View File

@@ -0,0 +1,36 @@
using ServerCommon.BusinessLogDomain;
using ServerCommon;
using ServerCore; using ServerBase;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace GameServer
{
internal static class RentalBusinessLogHelper
{
public static RentalLogInfo toRentalLogInfo(this RentFloorRequestInfo rentFloorRequestInfo)
{
var rental_log_info = new RentalLogInfo();
rental_log_info.setRentalInfo(rentFloorRequestInfo);
return rental_log_info;
}
public static void setRentalInfo(this RentalLogInfo log, RentFloorRequestInfo rentFloorRequestInfo)
{
log.setLogProperty(
rentFloorRequestInfo.LandId,
rentFloorRequestInfo.BuildingId,
rentFloorRequestInfo.Floor,
rentFloorRequestInfo.OwnerGuid,
rentFloorRequestInfo.MyhomeGuid,
rentFloorRequestInfo.RentalPeriod,
rentFloorRequestInfo.RentalStartTime.ToDateTime(),
rentFloorRequestInfo.RentalFinishTime.ToDateTime()
);
}
}
}

View File

@@ -0,0 +1,74 @@
using Google.Protobuf.WellKnownTypes;
using ServerCommon;
using ServerCore; using ServerBase;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using static ClientToGameReq.Types;
using static Org.BouncyCastle.Asn1.Cmp.Challenge;
namespace GameServer
{
internal static class RentalHelper
{
public static async Task<Rental> makeRental(Player player, RentFloorRequestInfo rentFloorRequestInfo)
{
var rental = new Rental(player);
await rental.onInit();
var rental_attribute = rental.getEntityAttribute<RentalAttribute>();
NullReferenceCheckHelper.throwIfNull(rental_attribute, () => $"rental_attribute is null !!! - {player.toBasicString()}");
rental_attribute.LandMetaId = rentFloorRequestInfo.LandId;
rental_attribute.BuildingMetaId = rentFloorRequestInfo.BuildingId;
rental_attribute.Floor = rentFloorRequestInfo.Floor;
rental_attribute.MyhomeGuid = rentFloorRequestInfo.MyhomeGuid;
rental_attribute.RentalFinishTime = rentFloorRequestInfo.RentalFinishTime.ToDateTime();
rental_attribute.modifiedEntityAttribute(true);
return rental;
}
public static OwnedRentalInfo toOwnedRentalInfo(this Rental rental)
{
var rental_attribute = rental.getEntityAttribute<RentalAttribute>();
NullReferenceCheckHelper.throwIfNull(rental_attribute, () => $"var rental_attribute is null !!!");
var owned_rental_info = new OwnedRentalInfo();
owned_rental_info.LandId = rental_attribute.LandMetaId;
owned_rental_info.BuildingId = rental_attribute.BuildingMetaId;
owned_rental_info.Floor = rental_attribute.Floor;
owned_rental_info.MyhomeGuid = rental_attribute.MyhomeGuid;
owned_rental_info.RentalFinishTime = rental_attribute.RentalFinishTime.ToTimestamp();
return owned_rental_info;
}
public static RentFloorRequestInfo toRentFloorRequestInfo(this C2GS_REQ_RENT_FLOOR reqRentFloor, string ownerGuid)
{
var rental_period = TimeSpan.FromDays(reqRentFloor.RentalPeriod);
var rental_start_time = DateTime.UtcNow;
var rental_finish_time = rental_start_time.Add(rental_period).Date;
var rent_floor_request_info = new RentFloorRequestInfo();
rent_floor_request_info.LandId = reqRentFloor.LandId;
rent_floor_request_info.BuildingId = reqRentFloor.BuildingId;
rent_floor_request_info.Floor = reqRentFloor.Floor;
rent_floor_request_info.OwnerGuid = ownerGuid;
rent_floor_request_info.MyhomeGuid = reqRentFloor.MyhomeGuid;
rent_floor_request_info.InstanceName = reqRentFloor.InstanceName;
rent_floor_request_info.ThumbnailImageId = reqRentFloor.ThumbnailImageId;
rent_floor_request_info.ListImageId = reqRentFloor.ListImageId;
rent_floor_request_info.EnterPlayerCount = reqRentFloor.EnterPlayerCount;
rent_floor_request_info.RentalPeriod = reqRentFloor.RentalPeriod;
rent_floor_request_info.RentalStartTime = rental_start_time.ToTimestamp();
rent_floor_request_info.RentalFinishTime = rental_finish_time.ToTimestamp();
return rent_floor_request_info;
}
}
}

View File

@@ -0,0 +1,75 @@
using ServerCore; using ServerBase;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using static ClientToGameMessage.Types;
using static ServerMessage.Types;
namespace GameServer
{
internal static class RentalNotifyHelper
{
public static bool send_S2C_NTF_OWNED_RENTAL_INFOS(this Player player)
{
var rental_agent_action = player.getEntityAction<RentalAgentAction>();
var ntf_packet = new ClientToGame();
ntf_packet.Message = new ClientToGameMessage();
ntf_packet.Message.NtfOwnedRentalInfos = new GS2C_NTF_OWNED_RENTAL_INFOS();
var rentals = rental_agent_action.getRentals();
foreach (var rental in rentals)
{
var owned_rental_info = rental.toOwnedRentalInfo();
ntf_packet.Message.NtfOwnedRentalInfos.OwnedRentalInfos.Add(owned_rental_info);
}
if (false == GameServerApp.getServerLogic().onSendPacket(player, ntf_packet))
{
return false;
}
return true;
}
public static bool send_S2C_NTF_MODIFY_OWNED_RENTAL_INFOS(this Player player, ModifyType modifyType, Rental rental)
{
var modify_owned_rental_info = new ModifyOwnedRentalInfo();
modify_owned_rental_info.ModifyType = modifyType;
modify_owned_rental_info.OwnedRentalInfo = rental.toOwnedRentalInfo();
var ntf_packet = new ClientToGame();
ntf_packet.Message = new ClientToGameMessage();
ntf_packet.Message.NtfModifyOwnedRentalInfos = new GS2C_NTF_MODIFY_OWNED_RENTAL_INFOS();
ntf_packet.Message.NtfModifyOwnedRentalInfos.ModifyOwnedRentalInfos.Add(modify_owned_rental_info);
if (false == GameServerApp.getServerLogic().onSendPacket(player, ntf_packet))
{
return false;
}
return true;
}
public static bool send_GS2GS_NTF_RENT_FLOOR(RentFloorRequestInfo rentFloorRequestInfo, int instanceMetaId)
{
var server_logic = GameServerApp.getServerLogic();
var message = new ServerMessage();
message.NtfRentFloor = new GS2GS_NTF_RENT_FLOOR();
message.NtfRentFloor.ExceptServerName = server_logic.getServerName();
message.NtfRentFloor.RentFloorRequestInfo = rentFloorRequestInfo;
message.NtfRentFloor.InstanceMetaId = instanceMetaId;
var rabbit_mq = server_logic.getRabbitMqConnector() as RabbitMQ4Game;
NullReferenceCheckHelper.throwIfNull(rabbit_mq, () => $"rabbit_mq is null !!!");
rabbit_mq.sendMessageToExchangeAllGame(message);
return true;
}
}
}

View File

@@ -0,0 +1,125 @@
using Google.Protobuf;
using Google.Protobuf.WellKnownTypes;
using ServerCore;
using ServerBase;
using ServerCommon;
using ServerCommon.BusinessLogDomain;
using MetaAssets;
using static ClientToGameRes.Types;
namespace GameServer.PacketHandler;
[PacketHandler(typeof(ClientToGameReq), typeof(ClientToGameReq.Types.C2GS_REQ_LAND_INFO), typeof(LandInfoPacketHandler), typeof(GameLoginListener))]
internal class LandInfoPacketHandler : PacketRecvHandler
{
public static bool send_S2C_ACK_LAND_INFO(Player owner, Result result, GS2C_ACK_LAND_INFO res)
{
var ack_packet = new ClientToGame();
ack_packet.Response = new ClientToGameRes();
ack_packet.Response.ErrorCode = result.ErrorCode;
ack_packet.Response.AckLandInfo = res;
if (false == GameServerApp.getServerLogic().onSendPacket(owner, ack_packet))
{
return false;
}
return true;
}
public override async Task<Result> onProcessPacket(ISession entityWithSession, Google.Protobuf.IMessage recvMessage)
{
var result = new Result();
var err_msg = string.Empty;
var player = entityWithSession as Player;
NullReferenceCheckHelper.throwIfNull(player, () => $"player is null !!!");
var server_logic = GameServerApp.getServerLogic();
var req_msg = recvMessage as ClientToGame;
ArgumentNullReferenceCheckHelper.throwIfNull(req_msg, () => $"req_msg is null !!! - {player.toBasicString()}");
var request = req_msg.Request.ReqLandInfo;
ArgumentNullReferenceCheckHelper.throwIfNull(request, () => $"request is null !!! - {player.toBasicString()}");
var res = new GS2C_ACK_LAND_INFO();
var fn_transaction_runner = async delegate ()
{
var result = new Result();
if (!MapManager.Instance.GetLandMapTree(request.LandId, out var land_map_tree))
{
err_msg = $"Failed to GetLandMapTree() !!! : LandMetaId:{request.LandId} - {player.toBasicString()}";
result.setFail(ServerErrorCode.LandMapTreeDataNotFound, err_msg);
Log.getLogger().error(result.toBasicString());
send_S2C_ACK_LAND_INFO(player, result, res);
return result;
}
var building_map_tree = land_map_tree.ChildBuildingMapTree;
if (building_map_tree == null)
{
err_msg = $"Not Exist LandMapTree ChildBuilding !!! : LandMap:{land_map_tree.LandMapFileName}";
result.setFail(ServerErrorCode.LandMapTreeChildBuildingNotFound, err_msg);
Log.getLogger().error(result.toBasicString());
send_S2C_ACK_LAND_INFO(player, result, res);
return result;
}
if (!MetaData.Instance._BuildingTable.TryGetValue(building_map_tree.BuildingMetaId, out var building_meta_data))
{
err_msg = $"Failed to MetaData.TryGetValue() !!! : buildingMetaId:{building_map_tree.BuildingMetaId} - {player.toBasicString()}";
result.setFail(ServerErrorCode.BuildingMetaDataNotFound, err_msg);
Log.getLogger().error(result.toBasicString());
send_S2C_ACK_LAND_INFO(player, result, res);
return result;
}
var count = building_map_tree.ChildRoomMapTrees.Count;
res.RentalLandInfo = new()
{
LandId = land_map_tree.LandId,
BuildingId = building_map_tree.BuildingMetaId,
RentalCount = count
};
var batch = new QueryBatchEx<QueryRunnerWithDocument>(player, LogActionType.None, server_logic.getDynamoDbClient());
{
batch.addQuery(new DBQWriteToAttributeAllWithTransactionRunner());
batch.addQuery(new QueryFinal());
}
result = await QueryHelper.sendQueryAndBusinessLog(batch);
if (result.isFail())
{
send_S2C_ACK_LAND_INFO(player, result, res);
return result;
}
send_S2C_ACK_LAND_INFO(player, result, res);
return result;
};
result = await player.runTransactionRunnerSafely(TransactionIdType.PrivateContents, "LandInfo", fn_transaction_runner);
if (result.isFail())
{
err_msg = $"Failed to runTransactionRunnerSafely() !!! : {result.toBasicString()} - {player.toBasicString()}";
Log.getLogger().error(err_msg);
}
return result;
}
}

View File

@@ -0,0 +1,555 @@
using Google.Protobuf;
using Google.Protobuf.WellKnownTypes;
using ServerCore;
using ServerBase;
using ServerCommon;
using ServerCommon.BusinessLogDomain;
using MetaAssets;
using static ClientToGameRes.Types;
namespace GameServer.PacketHandler;
[PacketHandler(typeof(ClientToGameReq), typeof(ClientToGameReq.Types.C2GS_REQ_RENT_FLOOR), typeof(RentFloorPacketHandler), typeof(GameLoginListener))]
internal class RentFloorPacketHandler : PacketRecvHandler
{
public static bool send_S2C_ACK_RENT_FLOOR(Player owner, Result result, GS2C_ACK_RENT_FLOOR res)
{
var ack_packet = new ClientToGame();
ack_packet.Response = new ClientToGameRes();
ack_packet.Response.ErrorCode = result.ErrorCode;
ack_packet.Response.AckRentFloor = res;
if (false == GameServerApp.getServerLogic().onSendPacket(owner, ack_packet))
{
return false;
}
return true;
}
public override async Task<Result> onProcessPacket(ISession entityWithSession, Google.Protobuf.IMessage recvMessage)
{
var result = new Result();
var err_msg = string.Empty;
var player = entityWithSession as Player;
NullReferenceCheckHelper.throwIfNull(player, () => $"player is null !!!");
var server_logic = GameServerApp.getServerLogic();
var req_msg = recvMessage as ClientToGame;
NullReferenceCheckHelper.throwIfNull(req_msg, () => $"req_msg is null !!! - {player.toBasicString()}");
var request = req_msg.Request.ReqRentFloor;
NullReferenceCheckHelper.throwIfNull(request, () => $"request is null !!! - {player.toBasicString()}");
var res = new GS2C_ACK_RENT_FLOOR();
// 랜드
if (!MetaData.Instance._LandTable.TryGetValue(request.LandId, out var land_meta_data))
{
err_msg = $"Failed to MetaData.TryGetValue() !!! : LandMetaId:{request.LandId} - {player.toBasicString()}";
result.setFail(ServerErrorCode.LandMetaDataNotFound, err_msg);
Log.getLogger().error(result.toBasicString());
send_S2C_ACK_RENT_FLOOR(player, result, res);
return result;
}
if (!MapManager.Instance.GetLandMapTree(request.LandId, out var land_map_tree))
{
err_msg = $"Failed to GetLandMapTree() !!! : LandMetaId:{request.LandId} - {player.toBasicString()}";
result.setFail(ServerErrorCode.LandMapTreeDataNotFound, err_msg);
Log.getLogger().error(result.toBasicString());
send_S2C_ACK_RENT_FLOOR(player, result, res);
return result;
}
if (land_meta_data.LandType != MetaAssets.LandType.RENTAL)
{
err_msg = $"LandType is not RENTAL !!! : LandMetaId:{land_meta_data.LandId} - {player.toBasicString()}";
result.setFail(ServerErrorCode.RentalNotAvailableLand, err_msg);
Log.getLogger().error(result.toBasicString());
send_S2C_ACK_RENT_FLOOR(player, result, res);
return result;
}
if (!server_logic.getLandManager().tryGetLand(request.LandId, out var land))
{
err_msg = $"Failed to tryGetLand() !!! : landMetaId:{request.LandId} - {player.toBasicString()}";
result.setFail(ServerErrorCode.LandNotFound, err_msg);
Log.getLogger().error(result.toBasicString());
send_S2C_ACK_RENT_FLOOR(player, result, res);
return result;
}
// 빌딩
var building_map_tree = land_map_tree.ChildBuildingMapTree;
if (building_map_tree == null)
{
err_msg = $"Not Exist LandMapTree ChildBuilding !!! : LandMap:{land_map_tree.LandMapFileName} - {player.toBasicString()}";
result.setFail(ServerErrorCode.LandMapTreeChildBuildingNotFound, err_msg);
Log.getLogger().error(result.toBasicString());
send_S2C_ACK_RENT_FLOOR(player, result, res);
return result;
}
if (!MetaData.Instance._BuildingTable.TryGetValue(request.BuildingId, out var building_meta_data))
{
err_msg = $"Failed to MetaData.TryGetValue() !!! : BuildingMetaId:{request.BuildingId} - {player.toBasicString()}";
result.setFail(ServerErrorCode.BuildingMetaDataNotFound, err_msg);
Log.getLogger().error(result.toBasicString());
send_S2C_ACK_RENT_FLOOR(player, result, res);
return result;
}
if (building_map_tree.BuildingMetaId != request.BuildingId)
{
err_msg = $"Not Match LandMap ChildBuilding !!! : ChildBuildingMetaId:{building_map_tree.BuildingMetaId}, inputBuildingMetaId:{request.BuildingId} - {player.toBasicString()}";
result.setFail(ServerErrorCode.LandMapTreeChildBuildingNotFound, err_msg);
Log.getLogger().error(result.toBasicString());
send_S2C_ACK_RENT_FLOOR(player, result, res);
return result;
}
if (!server_logic.getBuildingManager().tryGetBuilding(request.BuildingId, out var building))
{
err_msg = $"Failed to tryGetBuilding() !!! : buildingMetaId:{request.BuildingId} - {player.toBasicString()}";
result.setFail(ServerErrorCode.BuildingNotFound, err_msg);
Log.getLogger().error(result.toBasicString());
send_S2C_ACK_RENT_FLOOR(player, result, res);
return result;
}
var building_action = building.getEntityAction<BuildingAction>();
NullReferenceCheckHelper.throwIfNull(building_action, () => $"building_action is null !!! - {player.toBasicString()}");
var is_load_from_db = building_action.isLoadFromDb();
if (land_meta_data.RentalStateSwitch && is_load_from_db)
{
if (!building_action.isRentalOpen())
{
err_msg = $"Land Rental is not Open !!! : LandMetaId:{land_meta_data.LandId} - {player.toBasicString()}";
result.setFail(ServerErrorCode.RentalNotAvailableLand, err_msg);
Log.getLogger().error(result.toBasicString());
send_S2C_ACK_RENT_FLOOR(player, result, res);
return result;
}
}
else
{
if (!land_meta_data.RentalAvailable)
{
err_msg = $"Land RentalAvailable is false !!! : LandMetaId:{land_meta_data.LandId} - {player.toBasicString()}";
result.setFail(ServerErrorCode.RentalNotAvailableLand, err_msg);
Log.getLogger().error(result.toBasicString());
send_S2C_ACK_RENT_FLOOR(player, result, res);
return result;
}
}
// 층
if (request.Floor <= 0 || request.Floor > building_meta_data.InstanceSocket_)
{
err_msg = $"Floor value is invalid !!! : BuildingMetaId:{building_map_tree.BuildingMetaId}, Floor:{request.Floor} - {player.toBasicString()}";
result.setFail(ServerErrorCode.RentalAddressInvalid, err_msg);
Log.getLogger().error(result.toBasicString());
send_S2C_ACK_RENT_FLOOR(player, result, res);
return result;
}
if (building_map_tree.ChildRoomMapTrees.TryGetValue(request.Floor, out var room_map_tree))
{
err_msg = $"Address is not Empty !!! : BuildingMetaId:{building_map_tree.BuildingMetaId}, Floor:{request.Floor} - {player.toBasicString()}";
result.setFail(ServerErrorCode.RentalAddressIsNotEmpty, err_msg);
Log.getLogger().error(result.toBasicString());
send_S2C_ACK_RENT_FLOOR(player, result, res);
return result;
}
var building_floor_agent_action = building.getEntityAction<BuildingFloorAgentAction>();
NullReferenceCheckHelper.throwIfNull(building_floor_agent_action, () => $"building_floor_agent_action is null !!! - {player.toBasicString()}");
if (!building_floor_agent_action.isEmptyFloor(request.Floor))
{
err_msg = $"Building Floor is not Empty !!! : BuildingMetaId:{request.BuildingId}, Floor:{request.Floor} - {player.toBasicString()}";
result.setFail(ServerErrorCode.BuildingFloorIsNotEmpty, err_msg);
Log.getLogger().error(result.toBasicString());
send_S2C_ACK_RENT_FLOOR(player, result, res);
return result;
}
// 마이홈
var myhome_agent_action = player.getEntityAction<MyhomeAgentAction>();
NullReferenceCheckHelper.throwIfNull(myhome_agent_action, () => $"myhome_agent_action is null !!! - {player.toBasicString()}");
if (!myhome_agent_action.tryGetMyHome(request.MyhomeGuid, out var myhome))
{
err_msg = $"Failed to tryGetMyHome() !!! : myhomeGuid:{request.MyhomeGuid} - {player.toBasicString()}";
result.setFail(ServerErrorCode.MyHomeNotFound, err_msg);
Log.getLogger().error(result.toBasicString());
send_S2C_ACK_RENT_FLOOR(player, result, res);
return result;
}
var rental_agent_action = player.getEntityAction<RentalAgentAction>();
NullReferenceCheckHelper.throwIfNull(rental_agent_action, () => $"rental_agent_action is null !!! - {player.toBasicString()}");
if (rental_agent_action.isRentalMyhome(request.MyhomeGuid))
{
err_msg = $"Myhome is On Rental !!! : MyhomeGuid:{request.MyhomeGuid} - {player.toBasicString()}";
result.setFail(ServerErrorCode.MyhomeIsOnRental, err_msg);
Log.getLogger().error(result.toBasicString());
send_S2C_ACK_RENT_FLOOR(player, result, res);
return result;
}
var myhome_action = myhome.getEntityAction<MyhomeAction>();
NullReferenceCheckHelper.throwIfNull(myhome_action, () => $"myhome_action is null !!! - {player.toBasicString()}");
var myhome_ugc_info = myhome_action.getMyhomeUgcInfo();
var myhome_ugc_npc_infos = myhome_ugc_info.getUgcNpcAnchorInfos();
var myhome_ugc_npc_guids = new List<string>();
var modify_floor_linked_infos = new List<ModifyFloorLinkedInfo>();
foreach (var myhome_ugc_npc_info in myhome_ugc_npc_infos.Values)
{
myhome_ugc_npc_guids.Add(myhome_ugc_npc_info.EntityGuid);
}
if (myhome_ugc_npc_guids.Count > 0)
{
var modify_floor_linked_info = MapHelper.makeModifyFloorLinkedInfo(ModifyType.Add, request.LandId, request.BuildingId, request.Floor, myhome_ugc_npc_guids);
modify_floor_linked_infos.Add(modify_floor_linked_info);
}
result = MyhomeHelper.getMyhomeInstanceId(myhome_ugc_info.RoomType, out var instance_meta_id);
if (result.isFail())
{
err_msg = $"Fail to getMyhomeInstanceId() !!! : {result.toBasicString()} - {player.toBasicString()}";
Log.getLogger().error(err_msg);
send_S2C_ACK_RENT_FLOOR(player, result, res);
return result;
}
if (!MetaData.Instance._RentalfeeTable.TryGetValue((land_meta_data.Editor, land_meta_data.LandSize), out var rentalfee_meta_data))
{
err_msg = $"Failed to MetaData.TryGetValue() !!! : Editor:{land_meta_data.Editor}, Size:{land_meta_data.LandSize} - {player.toBasicString()}";
result.setFail(ServerErrorCode.RentalfeeMetaDataNotFound, err_msg);
Log.getLogger().error(result.toBasicString());
send_S2C_ACK_RENT_FLOOR(player, result, res);
return result;
}
var charge_type = (CurrencyType)rentalfee_meta_data.CurrencyType;
var total_charge = 0.0d;
var rental_profits = new Dictionary<CurrencyType, double>();
ReceivedMailDoc? reward_mail_doc = null;
var is_burn_calium = false;
var user_guid = player.getUserGuid();
var is_building_owner = building_action.isBuildingOwner(user_guid);
if (!is_building_owner)
{
// 비용
var daily_charge = 0.0d;
if (is_load_from_db)
{
(charge_type, daily_charge) = building_action.getRentalCurrency();
}
else
{
daily_charge = rentalfee_meta_data.CurrencyValue;
}
if (charge_type == CurrencyType.Calium && land_meta_data.Editor == EditorType.CALIVERSE)
{
is_burn_calium = true;
}
var is_equal_amount = CaliumStorageHelper.compareDoubleByLong(request.RentalCurrencyAmount, daily_charge);
if (request.RentalCurrencyType != charge_type || !is_equal_amount)
{
err_msg = $"Rental Contract Info Update !!!";
result.setFail(ServerErrorCode.RentalContractInfoUpdate, err_msg);
Log.getLogger().error(result.toBasicString());
send_S2C_ACK_RENT_FLOOR(player, result, res);
return result;
}
total_charge = CaliumStorageHelper.MultiplyDoubleByLong(request.RentalPeriod, daily_charge);
rental_profits[charge_type] = total_charge;
// 보상
if (!MetaData.Instance.SystemMailMetaData.TryGetValue(ServerCommon.Constant.RENTAL_REWARD_SYSTEM_MAIL_META_KEY, out var system_mail_meta_data))
{
err_msg = $"Failed to MetaData.TryGetValue() !!! : SystemMailKey:{ServerCommon.Constant.RENTAL_REWARD_SYSTEM_MAIL_META_KEY} - {player.toBasicString()}";
result.setFail(ServerErrorCode.SystemMailMetaDataNotFound, err_msg);
Log.getLogger().error(result.toBasicString());
send_S2C_ACK_RENT_FLOOR(player, result, res);
return result;
}
var nickname = player.getUserNickname();
var mail_items = new List<ServerCommon.MailItem>() { new ServerCommon.MailItem() { ItemId = (uint)rentalfee_meta_data.RentalReward, Count = rentalfee_meta_data.RentalQuantity * request.RentalPeriod } };
(result, reward_mail_doc) = await Mail.createSystemMailWithMeta(user_guid, nickname, system_mail_meta_data, mail_items, MetaHelper.GameConfigMeta.SystemMailStoragePeriod);
if (result.isFail())
{
err_msg = $"Failed to createSystemMailWithMeta() !!! : {result.toBasicString()}";
Log.getLogger().error(err_msg);
send_S2C_ACK_RENT_FLOOR(player, result, res);
return result;
}
NullReferenceCheckHelper.throwIfNull(reward_mail_doc, () => $"reward_mail_doc is null !!!");
}
// 랜탈 레디스 등록
var address = RentalOccupyCacheRequest.makeShareKey(request.LandId, request.BuildingId, request.Floor);
var rental_occupy_cache_request = new RentalOccupyCacheRequest(address, server_logic.getRedisConnector());
result = await rental_occupy_cache_request.tryOccupyRental(user_guid);
if (result.isFail())
{
err_msg = $"Failed to tryOccupyRental() !!! : {result.toBasicString()}";
Log.getLogger().error(err_msg);
result.setFail(ServerErrorCode.RentalAddressIsNotEmpty, result.ResultString);
send_S2C_ACK_RENT_FLOOR(player, result, res);
return result;
}
var building_profit_agent_action = building.getEntityAction<BuildingProfitAgentAction>();
NullReferenceCheckHelper.throwIfNull(building_profit_agent_action, () => $"building_profit_agent_action is null !!! - {player.toBasicString()}");
using (building_profit_agent_action.getAsyncLock().Lock())
{
BuildingProfitBusinessLog? building_profit_business_log = null;
DynamoDbDocBase? new_building_profit_doc = null;
DynamoDbItemRequestQueryContext? building_profit_update_item_query_context = null;
if (!building_profit_agent_action.tryGetBuildingProfit(request.Floor, out var building_profit))
{
(result, building_profit, new_building_profit_doc) = await BuildingProfitHelper.tryMakeBuildingProfit(building, request.BuildingId, request.Floor, charge_type, total_charge);
if (result.isFail())
{
err_msg = $"Failed to tryMakeBuildingProfit() !!! : {result.toBasicString()}";
Log.getLogger().error(err_msg);
send_S2C_ACK_RENT_FLOOR(player, result, res);
return result;
}
NullReferenceCheckHelper.throwIfNull(building_profit, () => $"building_profit is null !!!");
NullReferenceCheckHelper.throwIfNull(new_building_profit_doc, () => $"new_building_profit_doc is null !!!");
var building_profit_log_info = BuildingProfitBusinessLogHelper.toBuildingProfitLogInfo(building_map_tree.BuildingMetaId, request.Floor, charge_type, AmountDeltaType.Acquire, total_charge, total_charge);
building_profit_business_log = new BuildingProfitBusinessLog(building_profit_log_info);
}
else
{
// UpdateItemRequest DB
(result, building_profit_update_item_query_context) = BuildingProfitHelper.tryMakeUpdateItemRequestFromBuildingProfit(building_map_tree.BuildingMetaId, request.Floor, charge_type, total_charge);
if (result.isFail())
{
err_msg = $"Failed to tryMakeUpdateItemRequestFromBuildingProfit() !!! : {result.toBasicString()}";
Log.getLogger().error(err_msg);
send_S2C_ACK_RENT_FLOOR(player, result, res);
return result;
}
NullReferenceCheckHelper.throwIfNull(building_profit_update_item_query_context, () => $"building_profit_update_item_query_context is null !!! - {player.toBasicString()}");
var profit_action = building_profit.getEntityAction<BuildingProfitAction>();
NullReferenceCheckHelper.throwIfNull(profit_action, () => $"profit_action is null !!! - {player.toBasicString()}");
var current_profit = profit_action.getProfit(charge_type);
var building_profit_log_info = BuildingProfitBusinessLogHelper.toBuildingProfitLogInfo(building_map_tree.BuildingMetaId, request.Floor, charge_type, AmountDeltaType.Acquire, total_charge, current_profit + total_charge);
building_profit_business_log = new BuildingProfitBusinessLog(building_profit_log_info);
}
var building_profit_action = building_profit.getEntityAction<BuildingProfitAction>();
NullReferenceCheckHelper.throwIfNull(building_profit_action, () => $"building_profit_action is null !!!");
var building_profit_history_agent_action = building.getEntityAction<BuildingProfitHistoryAgentAction>();
NullReferenceCheckHelper.throwIfNull(building_profit_history_agent_action, () => $"building_profit_history_agent_action is null !!!");
var building_rental_history_agent_action = building.getEntityAction<BuildingRentalHistoryAgentAction>();
NullReferenceCheckHelper.throwIfNull(building_rental_history_agent_action, () => $"building_rental_history_agent_action is null !!!");
var fn_transaction_runner = async delegate ()
{
var result = new Result();
// Money
var money_action = player.getEntityAction<MoneyAction>();
NullReferenceCheckHelper.throwIfNull(money_action, () => $"money_action is null !!! - {player.toBasicString()}");
result = await money_action.changeMoney(charge_type, -total_charge, useCaliumEvent:is_burn_calium);
if (result.isFail())
{
err_msg = $"Failed to changeMoney() !!! : {result.toBasicString()}";
Log.getLogger().error(err_msg);
send_S2C_ACK_RENT_FLOOR(player, result, res);
return result;
}
// Rental
var rent_floor_request_info = request.toRentFloorRequestInfo(player.getUserGuid());
var rental = await RentalHelper.makeRental(player, rent_floor_request_info);
var room_map_tree = MapHelper.makeRoomMapTree(building_map_tree, instance_meta_id, rent_floor_request_info, myhome_ugc_npc_guids);
// Building Floor
(result, var building_floor, var building_floor_doc) = await BuildingFloorHelper.tryMakeBuildingFloor(building, rent_floor_request_info);
if (result.isFail())
{
err_msg = $"Failed to tryMakeBuildingFloor() !!! : {result.toBasicString()}";
Log.getLogger().error(err_msg);
send_S2C_ACK_RENT_FLOOR(player, result, res);
return result;
}
NullReferenceCheckHelper.throwIfNull(building_floor, () => $"building_floor is null !!!");
NullReferenceCheckHelper.throwIfNull(building_floor_doc, () => $"building_floor_doc is null !!!");
// Building Profit History
(result, var building_profit_history, var building_profit_history_doc) = await BuildingProfitHistoryHelper.tryMakeBuildingProfitHistory(building, request.BuildingId, request.Floor, DateTime.UtcNow, ProfitHistoryType.Stack, rental_profits);
if (result.isFail())
{
err_msg = $"Failed to tryMakeBuildingProfitHistory() !!! : {result.toBasicString()}";
Log.getLogger().error(err_msg);
send_S2C_ACK_RENT_FLOOR(player, result, res);
return result;
}
NullReferenceCheckHelper.throwIfNull(building_profit_history, () => $"building_profit_history is null !!!");
NullReferenceCheckHelper.throwIfNull(building_profit_history_doc, () => $"building_profit_history_doc is null !!!");
// Building Rental History
(result, var building_rental_history, var building_rental_history_doc) = await BuildingRentalHistoryHelper.tryMakeBuildingRentalHistory(building, request.BuildingId, request.Floor, user_guid, DateTime.UtcNow, request.RentalPeriod);
if (result.isFail())
{
err_msg = $"Failed to tryMakeBuildingRentalHistory() !!! : {result.toBasicString()}";
Log.getLogger().error(err_msg);
send_S2C_ACK_RENT_FLOOR(player, result, res);
return result;
}
NullReferenceCheckHelper.throwIfNull(building_rental_history, () => $"building_rental_history is null !!!");
NullReferenceCheckHelper.throwIfNull(building_rental_history_doc, () => $"building_rental_history_doc is null !!!");
var rental_log_info = RentalBusinessLogHelper.toRentalLogInfo(rent_floor_request_info);
var rental_business_log = new RentalBusinessLog(rental_log_info);
var batch = new QueryBatchEx<QueryRunnerWithItemRequest>(player, LogActionType.RentFloor, server_logic.getDynamoDbClient());
{
batch.addQuery(new DBQWriteToAttributeAllWithTransactionRunner());
if (new_building_profit_doc != null)
{
batch.addQuery(new DBQEntityWrite(new_building_profit_doc));
}
if (building_profit_update_item_query_context != null)
{
batch.addQuery(new DBQWithItemRequestQueryContext(building_profit_update_item_query_context));
}
batch.addQuery(new DBQEntityWrite(building_floor_doc));
batch.addQuery(new DBQEntityWrite(building_profit_history_doc));
batch.addQuery(new DBQEntityWrite(building_rental_history_doc));
if (reward_mail_doc != null)
{
batch.addQuery(new DBQEntityWrite(reward_mail_doc));
}
batch.addQuery(new QueryFinal());
}
batch.appendBusinessLog(rental_business_log);
batch.appendBusinessLog(building_profit_business_log);
result = await QueryHelper.sendQueryAndBusinessLog(batch);
if (result.isFail())
{
send_S2C_ACK_RENT_FLOOR(player, result, res);
return result;
}
var found_transaction_runner = player.findTransactionRunner(TransactionIdType.PrivateContents);
NullReferenceCheckHelper.throwIfNull(found_transaction_runner, () => $"found_transaction_runner is null !!! - {player.toBasicString()}");
res.CommonResult = found_transaction_runner.getCommonResult();
// Memory
if (new_building_profit_doc != null)
{
building_profit_agent_action.addBuildingProfit(request.Floor, building_profit);
}
else
{
building_profit_action.modifyProfit(charge_type, total_charge);
}
rental_agent_action.addRental(rent_floor_request_info.LandId, rent_floor_request_info.BuildingId, rent_floor_request_info.Floor, rental);
MapManager.Instance.addRoomMaptree(building_map_tree, rent_floor_request_info.Floor, room_map_tree);
building_floor_agent_action.addBuildingFloor(rent_floor_request_info.Floor, building_floor);
building_profit_history_agent_action.addBuildingProfitHistory(building_profit_history);
building_rental_history_agent_action.addBuildingRentalHistory(building_rental_history);
var mail_action = player.getEntityAction<MailAction>();
NullReferenceCheckHelper.throwIfNull(mail_action, () => $"mail_action is null !!! - {player.toBasicString()}");
mail_action.NewReceivedMail();
// Packet
send_S2C_ACK_RENT_FLOOR(player, result, res);
player.send_S2C_NTF_MODIFY_OWNED_RENTAL_INFOS(ModifyType.Add, rental);
RentalNotifyHelper.send_GS2GS_NTF_RENT_FLOOR(rent_floor_request_info, instance_meta_id);
MapNotifyHelper.sendNtfModifyFloorLinkedInfos(modify_floor_linked_infos);
await BuildingNotifyHelper.sendNtfModifyBuildingInfo(building);
BuildingProfitNotifyHelper.send_GS2GS_NTF_MODIFY_BUILDING_PROFIT(rent_floor_request_info.BuildingId, rent_floor_request_info.Floor, charge_type, total_charge);
BuildingProfitHistoryNotifyHelper.send_GS2GS_NTF_ADD_BUILDING_PROFIT_HISTORY(building_profit_history);
BuildingRentalHistoryNotifyHelper.send_GS2GS_NTF_ADD_BUILDING_RENTAL_HISTORY(building_rental_history);
return result;
};
result = await player.runTransactionRunnerSafely(TransactionIdType.PrivateContents, "RentFloor", fn_transaction_runner);
if (result.isFail())
{
err_msg = $"Failed to runTransactionRunnerSafely() !!! : {result.toBasicString()} - {player.toBasicString()}";
Log.getLogger().error(err_msg);
}
};
return result;
}
}

View File

@@ -0,0 +1,135 @@
using Google.Protobuf;
using Google.Protobuf.WellKnownTypes;
using ServerCore;
using ServerBase;
using ServerCommon;
using ServerCommon.BusinessLogDomain;
using MetaAssets;
using static ClientToGameRes.Types;
namespace GameServer.PacketHandler;
[PacketHandler(typeof(ClientToGameReq), typeof(ClientToGameReq.Types.C2GS_REQ_RENTAL_FLOOR_INFOS), typeof(RentalFloorInfosPacketHandler), typeof(GameLoginListener))]
internal class RentalFloorInfosPacketHandler : PacketRecvHandler
{
public static bool send_S2C_ACK_RENTAL_FLOOR_INFOS(Player owner, Result result, GS2C_ACK_RENTAL_FLOOR_INFOS res)
{
var ack_packet = new ClientToGame();
ack_packet.Response = new ClientToGameRes();
ack_packet.Response.ErrorCode = result.ErrorCode;
ack_packet.Response.AckRentalFloorInfos = res;
if (false == GameServerApp.getServerLogic().onSendPacket(owner, ack_packet))
{
return false;
}
return true;
}
public override async Task<Result> onProcessPacket(ISession entityWithSession, Google.Protobuf.IMessage recvMessage)
{
var result = new Result();
var err_msg = string.Empty;
var player = entityWithSession as Player;
NullReferenceCheckHelper.throwIfNull(player, () => $"player is null !!!");
var server_logic = GameServerApp.getServerLogic();
var req_msg = recvMessage as ClientToGame;
NullReferenceCheckHelper.throwIfNull(req_msg, () => $"req_msg is null !!!");
var request = req_msg.Request.ReqRentalFloorInfos;
NullReferenceCheckHelper.throwIfNull(request, () => $"request is null !!!");
var res = new GS2C_ACK_RENTAL_FLOOR_INFOS();
var fn_transaction_runner = async delegate ()
{
var result = new Result();
if (!MapManager.Instance.GetLandMapTree(request.LandId, out var land_map_tree))
{
err_msg = $"Failed to GetLandMapTree() !!! : LandMetaId:{request.LandId} - {player.toBasicString()}";
result.setFail(ServerErrorCode.LandMapTreeDataNotFound, err_msg);
Log.getLogger().error(result.toBasicString());
send_S2C_ACK_RENTAL_FLOOR_INFOS(player, result, res);
return result;
}
var building_map_tree = land_map_tree.ChildBuildingMapTree;
if (building_map_tree == null)
{
err_msg = $"Not Exist LandMapTree ChildBuilding !!! : LandMap:{land_map_tree.LandMapFileName}";
result.setFail(ServerErrorCode.LandMapTreeChildBuildingNotFound, err_msg);
Log.getLogger().error(result.toBasicString());
send_S2C_ACK_RENTAL_FLOOR_INFOS(player, result, res);
return result;
}
if (!MetaData.Instance._BuildingTable.TryGetValue(request.BuildingId, out var building_meta_data))
{
err_msg = $"Failed to MetaData.TryGetValue() !!! : BuildingMetaId:{request.BuildingId} - {player.toBasicString()}";
result.setFail(ServerErrorCode.BuildingMetaDataNotFound, err_msg);
Log.getLogger().error(result.toBasicString());
send_S2C_ACK_RENTAL_FLOOR_INFOS(player, result, res);
return result;
}
if (building_map_tree.BuildingMetaId != request.BuildingId)
{
err_msg = $"Not Match LandMap ChildBuilding !!! : ChildBuildingMetaId:{building_map_tree.BuildingMetaId}, inputBuildingMetaId:{request.BuildingId}";
result.setFail(ServerErrorCode.LandMapTreeChildBuildingNotFound, err_msg);
Log.getLogger().error(result.toBasicString());
send_S2C_ACK_RENTAL_FLOOR_INFOS(player, result, res);
return result;
}
foreach (var (floor, room_map_tree) in building_map_tree.ChildRoomMapTrees)
{
var rental_floor_info = new RentalFloorInfo();
rental_floor_info.Floor = floor;
rental_floor_info.InstanceName = room_map_tree.InstanceName;
res.RentalFloorInfos.Add(floor, rental_floor_info);
}
var batch = new QueryBatchEx<QueryRunnerWithDocument>(player, LogActionType.None, server_logic.getDynamoDbClient());
{
batch.addQuery(new DBQWriteToAttributeAllWithTransactionRunner());
batch.addQuery(new QueryFinal());
}
result = await QueryHelper.sendQueryAndBusinessLog(batch);
if (result.isFail())
{
send_S2C_ACK_RENTAL_FLOOR_INFOS(player, result, res);
return result;
}
send_S2C_ACK_RENTAL_FLOOR_INFOS(player, result, res);
return result;
};
result = await player.runTransactionRunnerSafely(TransactionIdType.PrivateContents, "RentalFloorInfos", fn_transaction_runner);
if (result.isFail())
{
err_msg = $"Failed to runTransactionRunnerSafely() !!! : {result.toBasicString()} - {player.toBasicString()}";
Log.getLogger().error(err_msg);
}
return result;
}
}

View File

@@ -0,0 +1,143 @@
using Google.Protobuf;
using Google.Protobuf.WellKnownTypes;
using ServerCore;
using ServerBase;
using ServerCommon;
using ServerCommon.BusinessLogDomain;
using MetaAssets;
using static ClientToGameRes.Types;
namespace GameServer.PacketHandler;
[PacketHandler(typeof(ClientToGameReq), typeof(ClientToGameReq.Types.C2GS_REQ_RENTAL_LAND_INFOS), typeof(RentalLandInfosPacketHandler), typeof(GameLoginListener))]
internal class RentalLandInfosPacketHandler : PacketRecvHandler
{
public static bool send_S2C_ACK_RENTAL_LAND_INFOS(Player owner, Result result, GS2C_ACK_RENTAL_LAND_INFOS res)
{
var ack_packet = new ClientToGame();
ack_packet.Response = new ClientToGameRes();
ack_packet.Response.ErrorCode = result.ErrorCode;
ack_packet.Response.AckRentalLandInfos = res;
if (false == GameServerApp.getServerLogic().onSendPacket(owner, ack_packet))
{
return false;
}
return true;
}
public override async Task<Result> onProcessPacket(ISession entityWithSession, Google.Protobuf.IMessage recvMessage)
{
var result = new Result();
var err_msg = string.Empty;
var player = entityWithSession as Player;
NullReferenceCheckHelper.throwIfNull(player, () => $"player is null !!!");
var server_logic = GameServerApp.getServerLogic();
var req_msg = recvMessage as ClientToGame;
NullReferenceCheckHelper.throwIfNull(req_msg, () => $"req_msg is null !!!");
var request = req_msg.Request.ReqRentalLandInfos;
NullReferenceCheckHelper.throwIfNull(request, () => $"request is null !!!");
var res = new GS2C_ACK_RENTAL_LAND_INFOS();
var fn_transaction_runner = async delegate ()
{
var result = new Result();
if (!MetaData.Instance._WorldMetaTable.TryGetValue(request.WorldId, out var world_meta_data))
{
err_msg = $"Failed to MetaData.TryGetValue() !!! : worldMetaId:{request.WorldId} - {player.toBasicString()}";
result.setFail(ServerErrorCode.WorldMetaDataNotFound, err_msg);
Log.getLogger().error(result.toBasicString());
send_S2C_ACK_RENTAL_LAND_INFOS(player, result, res);
return result;
}
if (!MapManager.Instance.GetWorldMapTree(world_meta_data.MapPath, out var world_map_tree))
{
err_msg = $"Failed to GetWorldMapTree() !!! : MapPath:{world_meta_data.MapPath} - {player.toBasicString()}";
result.setFail(ServerErrorCode.WorldMapTreeDataNotFound, err_msg);
Log.getLogger().error(result.toBasicString());
send_S2C_ACK_RENTAL_LAND_INFOS(player, result, res);
return result;
}
foreach (var land_map_tree in world_map_tree.ChildLandMapTrees.Values)
{
if (!MetaData.Instance._LandTable.TryGetValue(land_map_tree.LandId, out var land_meta_data))
{
err_msg = $"Failed to MetaData.TryGetValue() !!! : landMetaId:{land_map_tree.LandId} - {player.toBasicString()}";
result.setFail(ServerErrorCode.LandMetaDataNotFound, err_msg);
Log.getLogger().error(result.toBasicString());
send_S2C_ACK_RENTAL_LAND_INFOS(player, result, res);
return result;
}
if (land_meta_data.LandType != MetaAssets.LandType.RENTAL)
continue;
var building_map_tree = land_map_tree.ChildBuildingMapTree;
if (building_map_tree == null)
continue;
if (!MetaData.Instance._BuildingTable.TryGetValue(building_map_tree.BuildingMetaId, out var building_meta_data))
{
err_msg = $"Failed to MetaData.TryGetValue() !!! : buildingMetaId:{building_map_tree.BuildingMetaId} - {player.toBasicString()}";
result.setFail(ServerErrorCode.BuildingMetaDataNotFound, err_msg);
Log.getLogger().error(result.toBasicString());
send_S2C_ACK_RENTAL_LAND_INFOS(player, result, res);
return result;
}
var count = building_map_tree.ChildRoomMapTrees.Count;
var rental_land_info = new RentalLandInfo();
rental_land_info.LandId = land_map_tree.LandId;
rental_land_info.BuildingId = building_map_tree.BuildingMetaId;
rental_land_info.RentalCount = count;
res.RentalLandInfos.Add(rental_land_info.LandId, rental_land_info);
}
var batch = new QueryBatchEx<QueryRunnerWithDocument>(player, LogActionType.None, server_logic.getDynamoDbClient());
{
batch.addQuery(new DBQWriteToAttributeAllWithTransactionRunner());
batch.addQuery(new QueryFinal());
}
result = await QueryHelper.sendQueryAndBusinessLog(batch);
if (result.isFail())
{
send_S2C_ACK_RENTAL_LAND_INFOS(player, result, res);
return result;
}
send_S2C_ACK_RENTAL_LAND_INFOS(player, result, res);
return result;
};
result = await player.runTransactionRunnerSafely(TransactionIdType.PrivateContents, "RentalLandInfos", fn_transaction_runner);
if (result.isFail())
{
err_msg = $"Failed to runTransactionRunnerSafely() !!! : {result.toBasicString()} - {player.toBasicString()}";
Log.getLogger().error(err_msg);
}
return result;
}
}

View File

@@ -0,0 +1,39 @@
using ServerCommon;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ServerCore; using ServerBase;
namespace GameServer
{
internal class Rental : EntityBase
{
public Rental(Player parent)
: base(EntityType.Rental, parent)
{
}
public override async Task<Result> onInit()
{
addEntityAttribute(new RentalAttribute(this));
addEntityAction(new RentalAction(this));
return await base.onInit();
}
public override string toBasicString()
{
return $"{this.getTypeName()}, LandMetaId:{getOriginEntityAttribute<LandAttribute>()?.LandMetaId}";
}
public override string toSummaryString()
{
return $"{this.getTypeName()}, {getEntityAttribute<LandAttribute>()?.toBasicString()}";
}
}
}