7. 配置文件(MANIFEST.json)¶
7.1. 什么是MANIFEST.json?¶
iFun引擎的功能可通过名为 MANIFEST.json
的配置文件来设置。 MANIFEST.json
的结构如下。
Note
在以下示例中以//开头的注释仅用于帮助理解,而不包含在JSON file中。
7.1.1. MANIFEST.json 的结构¶
{
// 表示MANIFEST.json schema版本。目前须保持为1。
"version": 1,
"components": [
{
// 我的游戏服务器的Component名。
// 通过"funapi_initiator my_project"创建项目后,变为MyProjectServer。
"name": "MyProjectServer",
// 若需要向游戏服务器组件传送参数,请按如下方法使用。
// (my_component_arg1和my_component_arg2是作为示例使用的名称。)
"arguments": {
"my_component_arg1": integer_value,
"my_component_arg2": "string_value"
},
// 叙述游戏构建生成的shared object文件名。
// 通过"funapi_initiator my_project"创建项目后,变为libmy_project.so。
"library": "libmy_project.so",
// 在此处指定已使用的iFun引擎各个功能的设置值。
// iFun引擎功能已在/usr/share/funapi/manifests/*/MANIFEST.json中定义。
"dependency": {
...
"SessionService": {
"tcp_json_port": 8012,
...
},
...
"IoService": {
"internal_threads_size": 2,
...
}
...
}
}
]
}
7.2. MANIFEST.json 内容加密¶
有时须在MANIFEST.json中通过DB加密等方式来保存敏感信息。在开发过程中,只有具有代码访问权限的开发人员才能够访问,在服务环境中,只有可以访问live server的管理员才能够查看MANIFEST.json,所以大部分情况下不会造成什么问题,但为了更加安全地管理,可以对MANIFEST.json内的敏感信息进行加密。
MANIFEST.json加密仅支持字符串值,基于许可证文件来运行,因此须要在游戏服务器中使用的
account.ilf
已被设置的开发环境中执行以下 funapi_argument_encryptor 。
7.2.1. 字符串加密¶
输入以下代码,为 mypassword 字符串加密。
$ funapi_argument_encryptor "mypassword"
/etc/ifunfactory/account.ilf loaded.
Argument: mypassword
Encrypted argument: __ENCA_[ASnbrseCc050UsCHZWzV5A]
若已安装的 account.ilf
不同于已安装在游戏服务器中的内容,可以按如下方法,明确指定许可证文件路径,并进行加密。
$ funapi_argument_encryptor "mypassword" /path/to/game/servers/account.ilf
/path/to/game/servers/account.ilf loaded.
Argument: mypassword
Encrypted argument: __ENCA_[ASnbrseCc050UsCHZWzV5A]
7.2.2. 将加密后的字符串应用到MANIFEST.json¶
将上面生成的 Encrypted argument 值直接输入到MANIFEST文件中。以下示例是当
db_mysql_pw
为 mypassword 时,对其进行加密并指定的情况。
...
"Object": {
...,
"db_mysql_server_address" : "tcp://127.0.0.1:3306",
"db_mysql_id" : "funapi",
"db_mysql_pw" : "__ENCA_[ASnbrseCc050UsCHZWzV5A]",
"db_mysql_database" : "funapi",
...
},
...
7.3. 临时重写MANIFEST.json¶
MANIFEST.json在将游戏服务器程序被发布到实际提供服务的设备上时一同发布,它拥有在所有设备上共同应用的静态信息。因此,最好不要在提供服务的主机上对已发布并安装的MANIFEST.json进行手动修改。因为这样会随着服务器数量的增多而引发管理问题。
然而,在非常特殊的情况下,也有必须在提供服务的主机上按照 各个设备 对MANIFEST.json进行修改的情况。此时,可以设置一个对MANIFEST.json的内容进行override的单独文件。
Important
该文件相当于对各个主机的临时设置,因此在 对游戏服务打包时 不包含在内。
若已经以 funapi_initiator my_project 的名字创建了项目,则在服务主机上以
/etc/my_project/MANIFEST.override.json
的名字来创建文件。
若仅在使用 Flavor: 按不同作用来区分服务器 功能的my_flavor的情况下进行override设置,则以
/etc/my_project/MANIFEST.my_flavor.override.json
的名字来创建文件。
例如,在名为 hello 的项目中,若已定义了名为 game 的flavor,就会变为 /etc/hello/MANIFEST.game.override.json
。
然后,按以下形式编写代码。
{
"override": {
"ApiService": {
"api_service_port": 9014
},
"SessionService": {
"tcp_json_port": 0,
"udp_json_port": 8017
}
}
}
首先,须存在名为 override
的JSON属性值,其中罗列iFun引擎功能名称,指定各个功能所需的设置值。上述示例是对
ApiService
的 api_service_port
, SessionService
的 tcp_json_port
, udp_json_port
进行override的情况。
7.4. MANIFEST.json 示例 (funapi_initiator my_project 的情况)¶
以下示例是在上面的 my_project 时,自动生成的MANIFEST.json。通过 dependency
项可以了解怎样变更 my_project 所使用的各个iFun引擎功能的设置值。对于各个功能及可设置的参数,请参考 配置文件(MANIFEST.json)详情 。
{
"version": 1,
"components": [
{
"name": "MyProjectServer",
"arguments": {
"example_arg1": "val1",
"example_arg2": 100
},
"dependency": {
"AppInfo": {
"app_id": "MyProject",
"client_current_version": "0.0.3",
"client_compatible_versions": ["0.0.1", "0.0.2"],
"client_update_info": "",
"client_update_uri": ""
},
"EventDispatcher": {
"event_threads_size": 4,
"enable_event_profiler": true,
"enable_outstanding_event_profilier": true,
"slow_event_log_threshold_in_ms": 300,
"event_timeout_in_ms": 30000,
"enable_inheriting_event_tag": true,
"enable_random_event_tag": true,
"enable_event_thread_checker": true
},
"Logging": {
"activity_log_output": "json://activity/activity_log.json",
"activity_log_rotation_interval": 60,
"activity_log_write_schema": true,
"glog_flush_interval": 1,
"glog_retention_period_in_days": 30
},
"IoService": {
"internal_threads_size": 4
},
"SessionService": {
"tcp_json_port": 8012,
"udp_json_port": 0,
"http_json_port": 8018,
"tcp_protobuf_port": 0,
"udp_protobuf_port": 0,
"http_protobuf_port": 0,
"session_timeout_in_second" : 300,
"use_session_reliability": false,
"use_sequence_number_validation": false,
"use_encryption": false,
"tcp_encryptions": ["ife1", "ife2"],
"udp_encryptions": ["ife2"],
"http_encryptions": [],
"encryption_ecdh_key": "02d87cf9965f27cec9dd399b00cde2fb1c39af4711df5a1cb96a79f597c2e1b8",
"disable_tcp_nagle": true,
"enable_http_message_list": true,
"session_message_logging_level": 0,
"enable_per_message_metering_in_counter": false,
"json_protocol_schema_dir": "json_protocols",
"ping_sampling_interval_in_second": 0,
"ping_message_size_in_byte": 0,
"ping_timeout_in_second": 0,
"close_transport_when_session_close": true,
"send_session_id_as_string": true
},
"Timer": {},
"Object": {
"enable_database" : false,
"cache_expiration_in_ms": 300000,
"copy_cache_expiration_in_ms": 700,
"enable_delayed_db_update" : false,
"db_update_delay_in_second" : 10,
"db_mysql_server_address" : "tcp://127.0.0.1:3306",
"db_mysql_id" : "funapi",
"db_mysql_pw" : "funapi",
"db_mysql_database" : "funapi",
"db_read_connection_count" : 8,
"db_write_connection_count" : 16,
"db_key_shard_read_connection_count" : 8,
"db_key_shard_write_connection_count" : 16,
"db_character_set": "utf8",
"use_db_select_transaction_isolation_level_read_uncommitted": true,
"use_db_stored_procedure": true,
"export_db_schema": false,
"use_db_char_type_for_object_id": false,
"enable_assert_no_rollback" : true
},
"AccountManager": {
// To redirect client to servers behind load-balancers, set
// redirection_strict_check_server_id to "false".
"redirection_strict_check_server_id": true,
// Secret hexdecimal string used to protect redirection-procedure
// from tampering.
"redirection_secret": "403f217b685f437df905541b5e3286f1725153f7a95e63d1c0158731d52c0d5f"
},
"CounterService": {
"counter_flush_interval_in_sec": 0,
"counter_monitoring_interval_in_sec": 30,
"warning_threshold_event_queue_length": 3000,
"warning_threshold_outstanding_fetch_query": 5000,
"warning_threshold_outstanding_update_query": 5000
},
"RuntimeConfiguration": {
"enable_runtime_configuration": true,
"additional_configurations": []
},
"ApiService": {
"api_service_port": 8014,
"api_service_event_tags_size": 1,
"api_service_logging_level": 2
},
"AuthenticationClient": {
"use_authenticator" : false,
"remote_authenticator_ip_address" : "127.0.0.1",
"remote_authenticator_port" : 12800
},
"BillingClient": {
"use_biller" : false,
"remote_biller_ip_address" : "127.0.0.1",
"remote_biller_port" : 12810,
"googleplay_refresh_token" : "",
"googleplay_client_id" : "",
"googleplay_client_secret" : ""
},
"LeaderboardClient": {
"use_leaderboard" : false,
"leaderboard_agents": {
"" : {
"address": "127.0.0.1:12820",
"fallback_servers": []
}
}
},
"ClientResourceService": {
"use_client_resource_service" : false,
"client_resource_service_port" : 0,
"client_resource_dir" : "client_data",
"client_resource_url_base": "",
"client_resource_list_url": "",
"client_resource_service_threads_size": 2,
"client_resource_max_file_size": 10485760
},
"MapLoader": {
"use_map_loader": false,
"map_export_path": "",
"map_server_url": ""
},
"SystemInfo": {
"systeminfo_refresh_interval_in_sec": 5
},
"ResourceManager": {
"game_json_data_dir": "game_data",
"enable_game_data_mysql": false,
"game_data_mysql_server": "tcp://localhost:3306",
"game_data_mysql_username": "funapi",
"game_data_mysql_password": "funapi",
"game_data_mysql_database": "game_data",
"game_data_mysql_character_set": "utf8",
"game_data_mysql_tables": "game_data_table1,game_data_table2"
},
"Redis": {
"enable_redis": false,
"redis_mode": "redis",
"redis_servers": {
"": {
"address": "127.0.0.1:6379",
"auth_pass": ""
}
},
"redis_sentinel_servers": {
"": {
"master_name": "mymaster",
"addresses": ["127.0.0.1:26379"],
"auth_pass": ""
}
},
"redis_async_threads_size": 4
},
"MaintenanceService": {
"under_maintenance": false,
"maintenance_data_path": ""
},
"RpcService": {
"rpc_enabled": false,
"rpc_threads_size": 4,
"rpc_port": 8015,
"rpc_nic_name": "", // if not specified, uses first NIC appeared in predictable network interface names.
"rpc_tags": [],
"rpc_message_logging_level": 0,
"rpc_disable_tcp_nagle": true,
"enable_rpc_reply_checker": true
},
"ZookeeperClient": {
"zookeeper_nodes": "localhost:2181",
"zookeeper_client_count": 4,
"zookeeper_session_timeout_in_second": 60
},
"HardwareInfo": {
"external_ip_resolvers": "aws,nic:eth0,nat:192.0.2.113:tcp+pbuf=8012:http+json=8018"
},
"Curl": {
"curl_threads_size": 1
},
"CrossServerStorage": {
"enable_cross_server_storage": false,
"redis_tag_for_cross_server_storage": ""
}
},
"library": "libmy_project.so"
}
]
}