using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; using System.Xml.Linq; using System.Text; using System.Text.Json.Nodes; using System.Threading.Tasks; using NLog.Layouts; using Newtonsoft.Json.Linq; using Nettention.Proud; using Amazon.DynamoDBv2.DocumentModel; using MySqlConnector; using StackExchange.Redis; using NeoSmart.AsyncLock; using NeoSmart; using Org.BouncyCastle.Bcpg.OpenPgp; using Axion.Collections.Concurrent; using Amazon.DynamoDBv2; using MongoDB.Driver; using ServerCore; using MODULE_ID = System.UInt32; using DYNAMO_DB_TABLE_NAME = System.String; using LOG_ACTION_TYPE = System.String; using LOG_DOMAIN_TYPE = System.String; using SESSION_ID = System.Int32; using WORLD_ID = System.UInt32; using META_ID = System.UInt32; using ENTITY_GUID = System.String; using MASTER_GUID = System.String; using SUMMENED_ENTITY_GUID = System.String; using ACCOUNT_ID = System.String; using OWNER_GUID = System.String; using USER_GUID = System.String; using CHARACTER_GUID = System.String; using ITEM_GUID = System.String; using Microsoft.Extensions.Configuration; namespace ServerBase; //============================================================================================= // //============================================================================================= public partial class Initializers { public List getInitializers() => m_initializers; public string getContentsName() => m_contents_name; } //============================================================================================= // //============================================================================================= public partial class ServerConfig { public UInt16 getAppParamPort() => m_app_param_port; public void setAppParamPort(UInt16 port) => m_app_param_port = port; public string getConfigFilePath() => m_config_file_path; public void setConfigFilePath(string filePath) => m_config_file_path = filePath; public JObject? getLoadedConfig() => m_loaded_config_nullable; public string getRegionId() => m_region_id; public void setRegionId(string id) => m_region_id = id; public WORLD_ID getWorldId() => m_world_id; public void setWorldId(UInt16 worldId) => m_world_id = worldId; public UInt32 getChannelNo() => m_channel_no; public void setChannelNo(UInt32 channelNo) => m_channel_no = channelNo; public UInt16 SessionKeepAliveTimeSec { get; set; } = 30; public bool StandaloneMode { get; set; } = false; public bool ClientProgramVersionCheck { get; set; } = false; public UInt64 ClientMinimumRequiredLogicVersion { get; set; } = 0; public bool CheatCommandAlwaysAllow { get; set; } = false; public string LogDir { get; private set; } = "./Logs"; public string DumpDir { get; private set; } = "./Dumps"; public bool LocalServer { get; private set; } = false; public bool SingleThreaded { get; private set; } = false; public string ClientListenIp { get; private set; } = string.Empty; public UInt16 ClientListenPort { get; private set; } public bool AccountLoginBlockEnable { get; private set; } = false; public string ServiceType { get; private set; } = "Live"; public int MinWorkerThreadCount { get; private set; } = 0; public int MinIOCThreadCount { get; private set; } = 0; public ServiceType ServiceTypeNew { get; private set; } = global::ServiceType.Live; public int DefaultMaxUser { get; set; } = 0; public bool OfflineMode { get; private set; } = false; public RabbitmqConfig Rabbitmq { get; private set; } = new RabbitmqConfig(); public string SsoAccountDb { get; private set; } = "Server=127.0.0.1;Port=3306;User ID=external_ro;Password=bQNEXbRWQTtV6bwlqktGyBiuf2KqYF;Database=caliverse"; public string SsoAccountAuthJwtSecretKey { get; private set; } = "Gudx7xjCbCKxZsLEWr7HL5auSkScVPTUaYnZEztN"; public string AccountNftDb { get; private set; } = "Server=127.0.0.1;Port=3306;User ID=external_ro;Password=bQNEXbRWQTtV6bwlqktGyBiuf2KqYF;Database=caliverse"; public const UInt16 RedisDefaultPort = 6379; public string Redis { get; private set; } = "127.0.0.1:6379"; public string Dynamodb { get; private set; } = "http://localhost:8000"; public GameConf GameConfig = new(); public MongoDbConf MongoDbConfig = new(); public AWSConf AWS { get; private set; } = new AWSConf(); public bool ControlAgentEnable { get; private set; } public bool PerformanceCheckEnable { get; private set; } public bool BattleSystemEnable { get; private set; } public string EC2TemplateIMG { get; private set; } = string.Empty; public Dictionary getServerUrls() => m_server_urls; public AuthRule AuthRule { get; private set; } = new(); public NftRule NftRule { get; private set; } = new(); public AIChatConfig AIChatConfig { get; private set; } = new(); public EchoSystemConfig EchoSystemConfig { get; private set; } = new(); public BillingConfig BillingConfig { get; private set; } = new(); public UgqApiServerConfig UgqApiServerConfig { get; private set; } = new(); public LoadBalancingRule LoadBalancingRule { get; set; } = new(); public bool isLoadedConfig() => m_is_loaded_config; } public class GameConf { public int ReservationWaitTimeMSec { get; set; } = 30_000; public int LoginCacheExpiryTimeMSec { get; set; } = 60 * 60 * 1000; public int ServerSwitchCacheExpiryTimeMSec { get; set; } = 5 * 60 * 1000; } public class MongoDbConf { public string ConnectionString { get; set; } = string.Empty; public string DatabaseName { get; set; } = string.Empty; public int MinConnectionPoolSize { get; set; } = 0; public int MaxConnectionPoolSize { get; set; } = 100; public int WaitQueueTimeoutSecs { get; set; } = 120; } //============================================================================================= // //============================================================================================= public class AWSConf { public bool Enable { get; init; } public bool LocalDynamoDB { get; init; } public string AccessKey { get; init; } = string.Empty; public string SecretKey { get; init; } = string.Empty; public string Region { get; init; } = string.Empty; public string MilestoneName { get; init; } = string.Empty; public CloudWatchLogConf CloudWatchLog { get; set; } = new(); public S3Conf S3 { get; set; } = new(); } public class CloudWatchLogConf { public bool Enable { get; init; } public string? CloudWatchLogGroup { get; init; } public string? CloudWatchLogNamePattern { get; init; } public string? CloudWatchLogLevel { get; init; } public JsonLayout CloudWatchLogLayout { get; set; } = new JsonLayout(); } public class S3Conf { public string ServiceFolderName { get; init; } = string.Empty; public string MyhomeUgcInfoBucketName { get; init; } = string.Empty; public string BeaconAppProfileBucketName { get; init; } = string.Empty; } public static partial class ServerConfigHelper { public static ServerConfig? getServerConfig() => m_server_config; public static Flags getAuthRuleFlags() => m_auth_rules_flags; public static Dictionary, LoadBalancingRule.Config> getLoadBalancingRuleConfigs() => m_load_balancing_rule_configs; } //============================================================================================= // //============================================================================================= public abstract partial class SessionBase : ISession, IInitializer { public IRmiHost getRmiHost() => m_net_host; public ConnectionState getConnectionState() => m_connection_state; public void setConnectionState(ConnectionState state) => m_connection_state = state; public bool isConnected() => m_connection_state == ConnectionState.Connected; public bool isTryConneting() => m_connection_state == ConnectionState.TryConnecting; public bool isDisconnected() => m_connection_state == ConnectionState.Disconnected; public PacketReceiver getPacketReceiver() => m_packet_receiver; public PacketSender getPacketSender() => m_packet_sender; public int getLargePacketCheckSize() => m_large_packet_check_size; public int getPacketChunkSize() => m_packet_chunk_size; public LargePacketHandler getLargePacketHandler() => m_large_packet_handler; } //============================================================================================= // //============================================================================================= public abstract partial class ListenSessionBase : SessionBase { public string getServerType() => m_server_type; public ConcurrentDictionary getEntityWithSessions() => m_entity_with_sessions; public NetServer getNetServer() { var net_server = getRmiHost() as NetServer; NullReferenceCheckHelper.throwIfNull(net_server, () => $"net_server is null !!!"); return net_server; } } //============================================================================================= // //============================================================================================= public abstract partial class ConnectToServerSessionBase : SessionBase { public string getHostIp() => m_host_ip; public UInt16 getHostPort() => m_host_port; public string getHostAddress() => m_host_address; public void setHostAddress(string hostAddress, UInt16 port) { m_host_address = $"{hostAddress}:{port}"; m_host_port = port; } public string getToConnectServerType() => m_to_connect_server_type; } //============================================================================================= // //============================================================================================= public abstract partial class ServerLogicBase : IServerLogic { public AtomicBool getAccountLoginBlockEnable() => m_account_login_block_enable; public ConcurrentDictionary getRedisGlobalSharedCaches() => m_redis_global_shared_caches; public ConcurrentDictionary getRules() => m_rules; public CancellationTokenSource getCancellationTokenSource() => m_cancel_token; public ServerProgramVersion getServerProgramVersion() => m_server_program_version; public void setInstanceId(string instanceId) => m_server_instanceid = instanceId; public string getInstanceId() => m_server_instanceid; public void setConfiguration(IConfigurationRoot config) => m_configuration_root = config; public IConfigurationRoot getConfiguration() { NullReferenceCheckHelper.throwIfNull(m_configuration_root, () => $"m_configuration_root is null !!!"); return m_configuration_root; } public ServerConfig getServerConfig() { NullReferenceCheckHelper.throwIfNull(m_server_config, () => $"m_server_config is null !!!"); return m_server_config; } public void setServerConfig(ServerConfig config) => m_server_config = config; public string getServerName() => m_server_name; public void initServerName(string name) => m_server_name = name; public void setServerName(string name) => m_server_name = name; protected void replaceServerName(string name) => m_server_name = name; public void setServerType(string serverType) => m_server_type = serverType; public string getServerType() => m_server_type; public ConfigManager getConfigManager() { NullReferenceCheckHelper.throwIfNull(m_config_manager, () => $"m_config_manager is null !!!"); return m_config_manager; } } //============================================================================================= // //============================================================================================= public abstract partial class EntityBase : IActor, IInitializer, IWithTaskSerializer { public EntityType getEntityType() => m_entity_type; public bool hasParent() => null != m_parent_nullable; public EntityBase? getDirectParent() => m_parent_nullable; public TaskSerializer getTaskSerializer() => m_task_serializer; public async Task getAsyncLock() => await m_async_lock.LockAsync(); public ENTITY_GUID getEntityGuid() => m_entity_guid; public ConcurrentDictionary getEntityAttributes() => m_entity_attributes; public ConcurrentDictionary getEntityActions() => m_entity_actions; public bool hasMasterGuid() => false == m_master_guid.isNullOrWhiteSpace(); public MASTER_GUID getMasterGuid() => m_master_guid; public ConcurrentHashSet getSummenedEntityGuids() => m_summoned_entities; } //============================================================================================= // //============================================================================================= public abstract partial class EntityAttributeBase : IInitializer { public void setTryPendingDocBase(DynamoDbDocBase docBase) => m_try_pending_doc_base_nullable = docBase; public DynamoDbDocBase? getTryPendingDocBase() => m_try_pending_doc_base_nullable; public void resetTryPendingDocBase() => m_try_pending_doc_base_nullable = null; public EntityBase? getEntityOfOwnerEntityType() => m_entity_of_owner_entity_type; public OwnerEntityType getOwnerEntityType() => m_owner_entity_type; public void bindEntityRecorder(EntityRecorder recorder) => m_recorder_nullable = recorder; public bool isOrigin() => m_is_origin; public bool isDelete() => m_is_delete; public void resetEntityAttriubteState() => m_attribute_state.reset(); public bool setCloned() => m_is_origin = false; public void resetDelete() => m_is_delete = false; public void setDelete() => m_is_delete = true; public bool isApplicableCommonResult() => m_is_applicable_to_common_result; public AttributeState getAttributeState() => m_attribute_state; public EntityRecorder? getEntityRecorder() => m_recorder_nullable; public ReaderWriterLockSlim getRWLock() => m_rw_lock; public void setEntityOfOwnerEntityType(OwnerEntityType ownerEntityType, EntityBase entityOfOwnerEntityType) { m_owner_entity_type = ownerEntityType; m_entity_of_owner_entity_type = entityOfOwnerEntityType; } public EntityBase getOwner() => m_owner; } //============================================================================================= // //============================================================================================= public abstract partial class EntityAttributeTransactorBase : IEntityAttributeTransactor where TEntityAttribute : EntityAttributeBase { public EntityAttributeBase? getOriginEntityAttribute() => m_origin_entity_attribute_nullable as TEntityAttribute; public EntityAttributeBase? getClonedEntityAttribute() => m_cloned_entity_attribute_nullable as TEntityAttribute; public TransactionState getTransactionState() => m_transaction_state; public void setTransactionState(TransactionState state) => m_transaction_state = state; public EntityRecorder getEntityRecorder() => m_entity_recorder; public EntityBase getOwner() => m_owner; } //============================================================================================= // //============================================================================================= public abstract partial class EntityActionBase : IInitializer { public EntityBase getOwner() => m_owner; } //============================================================================================= // //============================================================================================= public abstract partial class EntityHFSMBase : HFSMBase, IWithEntityOwner { public EntityBase getOwner() => m_owner; } //============================================================================================= // //============================================================================================= public partial class TransactionRunner : IDisposable { public ConcurrentDictionary getEntityCommonResults() => m_entity_common_results; public ConcurrentDictionary> getReservedInvenSlotAllOfOwners() => m_reserved_inven_slots_of_owners; private bool isBinding() => m_is_binding; private void setBinding() => m_is_binding = true; public string getTransactionName() => m_transaction_name; public TransactionIdType getTransactionIdType() => m_transaction_id_type; public string getTransId() => m_trans_id; public EntityBase getOwner() => m_owner; } //============================================================================================= // //============================================================================================= public abstract partial class UserManagerBase where TPrimaryKey : notnull where TSubKey : notnull where TEntity : EntityBase { public UInt16 getUserCount() => (UInt16)m_users.Count; public MultiIndexDictionary getUsers() => m_users; } //============================================================================================= // //============================================================================================= public abstract partial class RedisRequestBase : IInitializer { public RedisConnector getRedisConnector() => m_redis_connector; public IDatabase getDatabase() { var db = m_redis_connector.getDatabase(); NullReferenceCheckHelper.throwIfNull(db, () => $"db is null !!!"); return db; } public string getKey() { ConditionValidCheckHelper.throwIfFalseWithCondition(() => false == m_key.isNullOrWhiteSpace(), () => $"Invalid Key !!!"); return m_key; } public string getMember() => m_member; public void setMember(string member) => m_member = member; } //============================================================================================= // //============================================================================================= public abstract partial class RedisRequestPrivateBase : RedisRequestBase { public IActor getOwner() => m_owner; } //============================================================================================= // //============================================================================================= public abstract partial class RedisRequestSharedBase : RedisRequestBase { public string getSharedKey() { ConditionValidCheckHelper.throwIfFalseWithCondition(() => false == m_shared_key.isNullOrWhiteSpace(), () => $"Invalid SharedKey !!!"); return m_shared_key; } } //============================================================================================= // //============================================================================================= public partial class DynamoDbDocumentQueryContext : IQueryContext { public Document getDocument() => m_document; public QueryType getQueryType() => m_query_type; public DynamoDbQueryExceptionNotifier.ExceptionHandler? getExceptionHandler() => m_exception_handler_nullable; } //============================================================================================= // //============================================================================================= public partial class DynamoDbItemRequestQueryContext : IQueryContext { public AmazonDynamoDBRequest getAmazonDynamoDBRequest() => m_db_request; public QueryType getQueryType() => m_query_type; public DynamoDbQueryExceptionNotifier.ExceptionHandler? getExceptionHandler() => m_exception_handler_nullable; } //============================================================================================= // //============================================================================================= public abstract partial class DynamoDbDocBase : IRowData { public PrimaryKey getPrimaryKey() => m_key; public string getPK() => m_key.PK; public string getSK() => m_key.SK.isNullOrWhiteSpace() == false ? m_key.SK : DynamoDbClient.SK_EMPTY; public string getDocType() => m_doc_type; public void setCombinationKeyForPKSK(string keyForPK, string keyForSK) { m_combination_key_for_pk = keyForPK; m_combination_key_for_sk = keyForSK; } public string getCombinationKeyForPK() => m_combination_key_for_pk; public void setCombinationKeyForPK(string uniqueKey) => m_combination_key_for_pk = uniqueKey; public string getCombinationKeyForSK() => m_combination_key_for_sk; public void setCombinationKeyForSK(string sortKey) => m_combination_key_for_sk = sortKey; public ConcurrentDictionary getAttribWrappers() => m_attrib_wrappers; public DbTimestamp getCreatedDateTime() => m_created_datetime; public DbTimestamp getUpdatedDateTime() => m_updated_datetime; public DbTimestamp getDeletedDateTime() => m_deleted_datetime; public DbTimestamp getRestoredDateTime() => m_restored_datetime; public void setExceptionHandler(DynamoDbQueryExceptionNotifier.ExceptionHandler exceptionHandler) => m_exception_handler_nullable = exceptionHandler; public DynamoDbQueryExceptionNotifier.ExceptionHandler? getExceptionHandler() => m_exception_handler_nullable; public void setInitializeResult(Result result) => m_initialize_result = result; public Result getInitializeResult() => m_initialize_result; public QueryType getQueryType() => m_query_type; public QueryType setQueryType(QueryType queryType) => m_query_type = queryType; } //============================================================================================= // //============================================================================================= public abstract partial class AttribBase { } //============================================================================================= // //============================================================================================= public partial class AttribWrapper : IAttribWrapper where TAttrib : AttribBase, new() { public TAttrib getAttrib() => m_attrib; public AttribBase getAttribBase() => m_attrib; public Type getAttribType() => m_attrib.GetType(); } //============================================================================================= // //============================================================================================= public partial class MySqlDbConnector { public MySqlConnection? getConnection() => m_connection; public System.Data.ConnectionState getLastConnectionState() => m_last_connection_state; public string getConnectionString() => m_connection_string; } //============================================================================================= // //============================================================================================= public partial class LogAction { public LOG_ACTION_TYPE getLogActionType() => m_log_action_type; public System.Guid getTranId() => m_tran_id; } //============================================================================================= // //============================================================================================= public abstract partial class ILogInvoker { public LogAction? GetLogAction() => m_log_action_nullable; public LOG_ACTION_TYPE getLogActionType() => m_log_action_nullable != null ? m_log_action_nullable.getLogActionType() : string.Empty; public LOG_DOMAIN_TYPE getLogDomainType() => m_log_domain_type; public System.Guid getTranId() => m_log_action_nullable != null ? m_log_action_nullable.getTranId() : System.Guid.Empty; }