数据存储的使用手册

*此内容使用人工智能(Beta)翻译,可能包含错误。若要查看英文页面,请点按 此处

除了使用 Lua 在 Studio 或生活服务器上使用 DataStoreService 以访问或使用 标准 和 1>订购1> 数据存储服务来访问和使用外部脚本和工具的 granular 访问权限和安全控制外,您还可以使用 Open Cloud API 来访问和使用 4>标准4> 和 7>订购7> 数据存储服务从外部脚本和工具

使用

您可以通过使用这些 API 来访问您的数据来改进您的工作流程,例如:

  • 客户支持门户 :数据存储有助于存储持久用户资源,例如用户库存中的物品或技能点。 有时您需要更新这些资源才能为客服 / 客户支持协助。 而不是使用 Studio 或加入体验每次手动更新,您可以构建一个网应用来允许您的客户服务代理直接处理客户支持请求,例如查看和修改用户库存或发行退款。

  • 生活操作面板 :您可以使用 API 构建生活操作面板,例如在体验中安排实验室活动。您可以在事件之前预订,将其隐藏在特性标签作为配置数据在数据存商店中的一部分,并设置时间来翻转旗帜发布事件。您的体验服务器可以通过读取标记来启动此变更。

  • 外部排行榜 : 为了在 Roblox 之外促进您的体验,您可以将您的体验的信息,例如比赛排行榜,提取实时并显示在外部网站上。您可以向您订购的数据存储存储您的数据存储存储,以便网站期间请求最新数据通过 HTTP 并更新网页。

  • 数据迁移自动化 :数据可能会随着您的体验进化而更改或更新,例如将数据架构升级以满足新功能。要避免丢失现有用户数据,您在移行数据存储从旧数据存储到新数据存储时,需要将数据存储存储从旧数据存储到新数据存储。您可以写一个外部脚本,读取从当前数据存储的每个条目,将数据写入新数据存储

与 Lua API 的差异

虽然 Open Cloud API 与 Lua DataStoreService 相似,但有几个不同的要求需要注意:

  • 宇宙ID和数据存储名称 :与Lua API不同,Open Cloud API是状态无效的,可以从任何地方来,因此您总是需要提供 宇宙ID ,您的体验的唯一标识,并且数据存储名称 在发送请求时。有关获取宇宙ID的更多信息,请参阅0>宇宙ID0>。

  • 创建和更新创建和更新权限区分 : Lua API 在调用 DataStore:SetAsync() 时创建新的条目,但 Open Cloud 方法为创建和更新条目是独立的。 在某些情况下,您可以创建一个可以编辑现有用户个人信息的客户支持工具,但不能创建新用户个人信个人资料的方法。 例如您

  • 数据 serialization : 所有开放云端端点都需要您在网络传输之前将所有数据序列化。 序列化意味着将对象转换为该字符串,而 deserialize 是其反向操作 (将字符串转换为对象)。 Lua API 会自动序列化和解码入口内容,但对于开放云端您需要使用 JSON 拥有立生成或处理您的入口数据。

安全权限

数据存储通常存储敏感信息,例如用户 profil 和虚拟货币。 为了保持安全,每个 Open Cloud API 的 API 有相应的权限,您必须将其添加到您的 API 钥键,例如清单 API 的权限。 如果您未添加所需权限,您的 API 调用将返回错误。 对于每个操作所需的特定权限,请参阅“

配置您的 API 钥匙 时,您可以为每个数据存储在特定体验中的数据存储存在内,或者您可以给予钥匙读取或写入所有数据存储。您还可以限制键在工具上的使用,而不是暴露所有数据存储。这在您的钥匙被泄露的情况下限制影响。

建筑工具

您可以使用您的选择语言使用 打开云端 API 为数据存储服务 来满足您的操作需求。以下示例通过在 Python 中使用标准数据存储存储和使用 External Persistent Leaderboard 使用排序数据存储存储的过程展示。

用户库存支持传送门

本节提供一个具体示例,在 Python 中构建用户库存支持传送门,在 котором您可以列出和读取您用户道具的子集,进行编辑,然后更新回到体验数据存商店。

在此示例中,假定以关注中/正在关注内容:

  • 用户存储的数据存储器的名称是 Inventory

  • 每个数据条的数据脚本为 "userId": {"currency": number, "weapon": string, "level": number} 。 钥匙是 just userId

  • Python 脚本列出一个基于用户名称的子集,根据前缀增加其虚拟货币 10 个,并更新数据。

从高等级,您可以通过添加 API 钥匙权限和添加脚本来构建您的 Python 应用程序。

为数据存储添加 API 钥匙权限

创建 API 钥匙 为此示例时,请确保您执行以下设置:

  1. 选择 API 系统 菜单在 访问权限 部分中,选择 宇宙数据存储

  2. (可选)数据存储 部分中,选择API操作对特定数据存储。

    1. 启用 特定数据存储操作 切换。默认情况下,五个数据存储自动加载,但您可以通过“+ 添加数据存储到列表”按钮添加额外的数据存储。
    2. 选择数据商店名称旁边的下拉箭头,然后选择您想要数据商店拥有访问权限的 API 操作。
  3. 选择 API 操作为整个体验。

    1. 单击 选择体验添加 下拉列表,然后选择一个体验。
    2. 体验操作 中,单击下拉箭头并选择您想要添加到您的 API 的操作。此示例选择 读取条目更新条目 和1>列入钥匙1>。
  4. 安全性 部分中,使用CIDR 语法,明确将 IP 访问设置为键使用 expiry 日期 ,并且让您的钥匙在那之后自动停止工作。在此示例中,如果您打算先进行本地测试,您可以通过将0> 0.0.0.0/00>设

为用户库存支持门户添加脚本

在创建示例应用程App所需的 API 钥匙之后,您需要添加 Python 脚本来执行应用程序功能。 data_stores_methods.py 文件显示如何定义

数据存储方法.py

import hashlib
import requests
import json
import base64
class DataStores:
def __init__(self):
self._base_url = "https://apis.roblox.com/datastores/v1/universes/{universeId}"
# API 钥匙保存在一个环境变量中,称为 'API_KEY'
self._apiKey = str(os.environ['API_KEY'])
self._universeId = "UNIVERSE_ID"
self.ATTR_HDR = 'Roblox-entry-Attributes'
self.USER_ID_HDR = 'Roblox-entry-UserIds'
self._objects_url = self._base_url +self._universeId+'/standard-datastores/datastore/entries/entry'
self._increment_url = self._objects_url + '/increment'
self._version_url = self._objects_url + '/versions/version'
self._list_objects_url = self._base_url +self._universeId+'/standard-datastores/datastore/entries'
def _H(self):
return { 'x-api-key' : self._apiKey }
def _get_url(self, path_format: str):
return f"{self._config['base_url']}/{path_format.format(self._config['universe_id'])}"
return r, attributes, user_ids
def get_entry(self, datastore, object_key, scope = None):
self._objects_url = self._base_url +self._universeId+'/standard-datastores/datastore/entries/entry'
headers = { 'x-api-key' : self._apiKey }
params={"datastoreName" : datastore, "entryKey" : object_key}
if scope:
params["scope"] = scope
r = requests.get(self._objects_url, headers=headers, params=params)
if 'Content-MD5' in r.headers:
expected_checksum = r.headers['Content-MD5']
checksum = base64.b64encode(hashlib.md5(r.content).digest())
#print(f'Expected {Expected_checksum}, 得到了 {checknum})
attributes = None
if self.ATTR_HDR in r.headers:
attributes = json.loads(r.headers[self.ATTR_HDR])
user_ids = []
if self.USER_ID_HDR in r.headers:
user_ids = json.loads(r.headers[self.USER_ID_HDR])
return r
def list_entries(self, datastore, scope = None, prefix="", limit=100, allScopes = False, exclusive_start_key=None):
self._objects_url = self._base_url +self._universeId+'/standard-datastores/datastore/entries'
headers = { 'x-api-key' : self._apiKey }
r = requests.get(self._objects_url, headers=headers, params={"datastoreName" : datastore, "scope" : scope, "allScopes" : allScopes, "prefix" : prefix, "limit" : 100, "cursor" : exclusive_start_key})
return r
def increment_entry(self, datastore, object_key, incrementBy, scope = None, attributes=None, user_ids=None):
self._objects_url = self._base_url +self._universeId+'/standard-datastores/datastore/entries/entry/increment'
headers = { 'x-api-key' : self._apiKey, 'Content-Type': 'application/octet-stream' }
params={"datastoreName" : datastore, "entryKey" : object_key, "incrementBy" : incrementBy}
if scope:
params["scope"] = scope
r = requests.post(self._objects_url, headers=headers, params=params)
attributes = None
if self.ATTR_HDR in r.headers:
attributes = json.loads(r.headers[self.ATTR_HDR])
user_ids = []
if self.USER_ID_HDR in r.headers:
user_ids = json.loads(r.headers[self.USER_ID_HDR])
return r
更新_inventory

import tutorialFunctions
DatastoresApi = tutorialFunctions.DataStores()
# 设置
datastoreName = "Inventory"
# 列出用户子集的钥匙(你可能需要使用下一页指针来查看其他条目)
keys = DatastoresApi.list_entries(datastoreName)
print(keys.content)
# 阅读每个用户的物品栏
for x in range(5):
updatedObjectKey = "User_"+str(x+1)
value = DatastoresApi.get_entry(datastoreName, updatedObjectKey)
# 将响应类型变更为字符串
updatedValue = value.json()
print(updatedObjectKey + " has "+str(updatedValue)+" gems in their inventory")
# 更新每个用户的货币10
for x in range(5):
updatedObjectKey = "User_"+str(x+1)
value = DatastoresApi.increment_entry(datastoreName, updatedObjectKey, 10)
# 将响应类型变更为字符串
updatedValue = value.json()
print(updatedObjectKey + " now has "+str(updatedValue)+" robux in their inventory")

为了测试,设置 API_KEY 环境变量,并运行 update_inventory 文件:


export API_KEY=... \
python update_inventory

外部持久排行榜

本节从 Python 中创建一个外部持久排行榜的具体示例展示,在这里您可以列出和读取您的用户信息存储在顺序的数据存储中,进行编辑,然后发布到外部网站进行推广进。

在此示例中,假定以关注中/正在关注内容:

  • 代码示例创建了一个预定列表的用户名以供示例用途。 对于您自己的应用程序,您应该使用您体验中的用户列表。

  • 代码示例为每个加入体验的用户添加 50 积分。对于您自己的应用程序,您应该根据体验的设计定义规则。

从高等级,您可以通过添加 API 钥匙权限和添加脚本来构建您的 Python 应用程序。

为订购数据存储添加 API 权限

示例应用程序需要四个方法来实现其功能: List Create 0> Update0> 1> 2> Increment2> ,因此您需要添加以下 API 权限:4> 5> Increment5> ,6> 7> Update6>

  • 阅读 对于 list 方法。
  • 写下CreateUpdate 和 0> Increment0> 方法。

创建 API 钥匙 为此示例时,请确保您执行以下操作:

  1. 选择 API 系统 菜单在 访问权限 部分中,选择 订购数据存储

  2. 将 API 操作的权限添加到目标体验中,以读取和写入订阅的数据存储。

    1. 单击 选择体验添加 下拉菜单,然后选择目标体验。
    2. 体验操作 中,扩展下拉列表,选择 读取写入 操作。
  3. 安全性 部分中,使用CIDR 语法,明确将 IP 访问设置为键使用 expiry 日期 ,并且让您的钥匙在那之后自动停止工作。在此示例中,如果您打算先进行本地测试,您可以通过将0> 0.0.0.0/00>设

为排行榜添加脚本

在创建示例应用程App需要权限的 API 钥匙后,您需要添加 Python 脚本来实现应用程序功能。

ordened_data_stores.py 文件显示如

订购_数据_存储.py

import hashlib
import requests
import json
class DataStores:
def __init__(self, config_file):
with open(config_file) as f:
self._config = json.load(f)
def _H(self):
return { 'x-api-key' : self._config["api_key"], 'Content-Type': 'application/json'}
def _get_url(self, path_format: str):
return f"{self._config['base_url']}/{path_format.format(self._config['universe_id'])}"
def list(self, datastore, scope, pageSize = 10, orderBy = "", filter = "", exclusiveStartKey = ""):
self._objects_url = self._config['api_key_url']+"universes/"+self._config["universe_id"]+"/orderedDataStores/"+datastore+"/scopes/"+scope+"/entries"
headers = { 'x-api-key' : self._config["api_key"] }
r = requests.get(self._objects_url, headers=headers, params={"max_page_size": pageSize, "order_by" : orderBy, "filter" : filter, "page_token" : ""})
return r
def create(self, datastore, scope, entry, data):
self._objects_url = self._config['api_key_url']+"universes/"+self._config["universe_id"]+"/orderedDataStores/"+datastore+"/scopes/"+scope+"/entries"
headers = self._H()
payload = json.dumps({
"value": 11
})
return requests.post(self._objects_url, params = {"id": entry }, data=payload, headers=headers)
def increment(self, datastore, scope, entry, incrementBy):
self._objects_url = self._config['api_key_url']+"universes/"+self._config["universe_id"]+"/orderedDataStores/"+datastore+"/scopes/"+scope+"/entries/"+entry+":increment"
headers = { 'x-api-key' : self._config["api_key"] }
payload = json.dumps({
"amount": 1
})
r = requests.post(self._objects_url, headers=headers, data=payload)
return r
排行榜.py

import leaderboardEndpoints
# 在这里输入配置文件
datastores = leaderboardEndpoints.DataStores("config.json")
# 变量
orderedDataStore = "PlayerScores"
scope = "global"
entryNames = ["Ragdoll", "Balinese", "Tabby", "Siamese"]
# 创建一个入口,并为每个新游戏家创建 50 积分
for x in range(len(entryNames)):
r = datastores.create(orderedDataStore, scope, entryNames[x], 50)
# 显示玩家的分数
playerScores = datastores.list(orderedDataStore, scope)
print(playerScores.content)
# 增加第一位玩家的得分以赢得游戏
datastores.increment(orderedDataStore, scope, entryNames[0], 100)
# 增加所有玩家的分数以参与游戏
for x in range(len(entryNames)):
datastores.increment(orderedDataStore, scope, entryNames[x], 10)
# 显示排行榜
playerScores = datastores.list(orderedDataStore, scope)
print(playerScores.content)
配置

{
"universe_id": "",
"api_key_url": "https://apis.roblox.com/datastores/了解订购-v1/",
"api_key": ""
}

为了测试,设置 API_KEY 环境变量,并运行 leaderboard 文件:


export API_KEY=... \
python leaderboard

完成测试后,您可以将排行榜发布或嵌入到 Roblox 之外的网站上,以获得更多曝光。