远程配置
无需发布更新即可调整数值平衡、价格和功能开关。每个响应都经过签名,在设备上验证,并缓存以供离线游玩。
代码注释和 API 名称保留英文,以便与 SDK 保持一致。
值类型#
在远程配置页面中创建键。值以文本形式存储,并带有一个类型,告诉 SDK 如何读取:
| 类型 | 示例 | 限制 |
|---|---|---|
string | Welcome back! | 最多 10,000 个字符 |
number | 25 | 任意有限数值 |
boolean | false | true 或 false |
json | {"sale": 0.2} | 最多 50,000 字节 |
读取配置值#
Getter 永远不会失败:当键不存在或无法转换时,会返回你提供的默认值。
int damage = Majacloud.RemoteConfig.GetInt("enemy_damage", 25);
float speed = Majacloud.RemoteConfig.GetFloat("player_speed", 4.5f);
bool maintenance = Majacloud.RemoteConfig.GetBool("maintenance_mode", false);
string welcome = Majacloud.RemoteConfig.GetString("welcome_message", "Hi!");
ShopConfig shop = Majacloud.RemoteConfig.GetJson<ShopConfig>("shop");var damage := Majacloud.remote_config.get_int("enemy_damage", 25)
var speed := Majacloud.remote_config.get_float("player_speed", 4.5)
var maintenance := Majacloud.remote_config.get_bool("maintenance_mode", false)
var welcome := Majacloud.remote_config.get_string("welcome_message", "Hi!")
var shop = Majacloud.remote_config.get_json("shop", {})const damage = mc.remoteConfig.getInt('enemy_damage', 25);
const speed = mc.remoteConfig.getNumber('player_speed', 4.5);
const maintenance = mc.remoteConfig.getBool('maintenance_mode', false);
const welcome = mc.remoteConfig.getString('welcome_message', 'Hi!');
const shop = mc.remoteConfig.getJson('shop', {});拉取和更新#
Unity 和 Godot 会在游戏启动时拉取配置;在 Web 上需要你自己调用 fetch()。之后的拉取会发送 ETag,因此配置未变化时只会产生一个很小的 304 响应。
Majacloud.RemoteConfig.ConfigUpdated += config => ApplyBalance();
var fetch = await Majacloud.RemoteConfig.FetchAsync(); // 304 when nothing changed
if (fetch.Ok) Debug.Log("Config v" + fetch.Value.Version + (fetch.Value.Changed ? " (new)" : ""));Majacloud.remote_config.updated.connect(apply_balance)
var fetch := await Majacloud.remote_config.fetch() # 304 when nothing changed
if fetch.ok:
print("Config v", fetch.value.version, " changed: ", fetch.value.changed)mc.remoteConfig.on('updated', () => applyBalance());
const fetch = await mc.remoteConfig.fetch(); // 304 when nothing changed
if (fetch.ok) console.log('Config v' + fetch.value.version, fetch.value.changed);curl -i https://majacloud.majanite.com/v1/config -H "X-Project-ID: $PROJECT_ID" -H "X-Client-Key: $CLIENT_KEY"
# Next time, send the ETag: 304 Not Modified when nothing changed
curl -i https://majacloud.majanite.com/v1/config -H "X-Project-ID: $PROJECT_ID" -H "X-Client-Key: $CLIENT_KEY" \
-H 'If-None-Match: "<etag>"'离线和缓存#
最近一次验证通过的配置会缓存在设备上并在启动时加载,因此 getter 可以离线工作,在首次拉取完成前也能使用。因网络原因失败的拉取会保留缓存副本;比缓存更旧的配置会被拒绝。
签名验证#
data 是 base64url 载荷,checksum 是它的 SHA-256,signature 是使用 storage/keys/ 中的私钥对 data 生成的 RSA-SHA256 签名。SDK 在使用配置前会检查这三项,以及项目 ID 和版本。
| SDK | 公钥来源 |
|---|---|
| Unity | Tools ▸ Majacloud ▸ Setup ▸ Test connection |
| Godot | Project ▸ Tools ▸ Majacloud: Test connection |
| Web | configPublicKey 选项(API 密钥页面上的 PEM) |
| REST | GET /v1/project → config_public_key_pem |
如果没有固定公钥,SDK 会在首次使用时获取它。请在正式构建中固定公钥,并将
storage/keys/ 纳入备份:游戏固定的正是它的公钥。你也可以用 OpenSSL 自行验证响应:
# Verify a config response yourself (what every SDK does before using it)
curl -s https://majacloud.majanite.com/v1/project -H "X-Project-ID: $PROJECT_ID" -H "X-Client-Key: $CLIENT_KEY" | jq -r .project.config_public_key_pem > public.pem
curl -s https://majacloud.majanite.com/v1/config -H "X-Project-ID: $PROJECT_ID" -H "X-Client-Key: $CLIENT_KEY" > response.json
jq -j .data response.json > data.txt
jq -r .signature response.json | base64 --decode > signature.bin
openssl dgst -sha256 -verify public.pem -signature signature.bin data.txt # Verified OK
jq -r .data response.json | tr '_-' '/+' | base64 --decode 2>/dev/null | jq . # the payload历史记录和恢复#
每次更改都有版本记录。控制台会根据套餐保留 7 到 365 天的历史记录,并可一键恢复任何先前的值。