Skip to content

Commit 9ebd87a

Browse files
committed
Initial commit
0 parents  commit 9ebd87a

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+11866
-0
lines changed

.gitignore

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
.vs/
2+
.vscode/
3+
.idea/
4+
5+
.DS_Store
6+
7+
*.output

ATTRIBUTIONS.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# Attributions
2+
3+
This project includes open source components under the MIT License (MIT).
4+
5+
**Component:** frkcli <br>
6+
**Source:** https://github.com/itsfrank/frkcli/tree/main <br>
7+
**Copyright:** Copyright (c) 2024 Francis O'Brien
8+
9+
**Component:** lune-cloud-luau-client <br>
10+
**Source:** https://github.com/itsfrank/lune-cloud-luau-client <br>
11+
**Copyright:** Copyright (c) 2024 Francis O'Brien

GUIDE.html

Lines changed: 1784 additions & 0 deletions
Large diffs are not rendered by default.

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2025 Roblox Corporation
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

Lines changed: 748 additions & 0 deletions
Large diffs are not rendered by default.

SECURITY.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# Security Policy
2+
## Reporting a Vulnerability
3+
If you discover a security vulnerability in this repository, we appreciate your help in ensuring that the issue is addressed quickly.
4+
5+
Report any vulnerabilities found to our bug bounty program on HackerOne: https://hackerone.com/roblox
6+
7+
Please do not create a public issue in this repo.

batch-process.luau

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
local main = require('./src/main')
2+
main()

config.template.json

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
{
2+
"universeId": -1,
3+
"placeId": -1,
4+
"callback": "",
5+
"outputDirectory": "",
6+
"numProcessingInstances": -1,
7+
8+
"dataStoreName": "",
9+
"dataStoreScope": "",
10+
"allScopes": false,
11+
"keyPrefix": "",
12+
"excludeDeletedKeys": false,
13+
14+
"dataStorePrefix": "",
15+
16+
"processItemRateLimit": 50,
17+
"numRetries": 4,
18+
"retryTimeoutBase": 0.5,
19+
"retryExponentialBackoff": 2,
20+
"maxTotalFailedItems": 100,
21+
"maxItemsPerJob": 50,
22+
"jobQueueMaxSize": 20,
23+
"errorLogMaxLength": 50,
24+
"progressRefreshTimeout": 5,
25+
"memoryStoresExpiration": 3888000,
26+
"memoryStoresStorageLimit": -1
27+
}

examples/ds2-config.json

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
{
2+
"universeId": -1,
3+
"placeId": -1,
4+
"callback": "examples/ds2-migrate-delete.luau",
5+
"outputDirectory": "<insert output directory>",
6+
"numProcessingInstances": 9,
7+
8+
"dataStorePrefix": "<insert ds2 name>/",
9+
10+
"processItemRateLimit": 50,
11+
"numRetries": 5,
12+
"retryTimeoutBase": 1,
13+
"retryExponentialBackoff": 3,
14+
"maxTotalFailedItems": 100,
15+
"maxItemsPerJob": 50,
16+
"jobQueueMaxSize": 20,
17+
"errorLogMaxLength": 50,
18+
"progressRefreshTimeout": 5,
19+
"memoryStoresExpiration": 3888000
20+
}
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
--[[
2+
This script will:
3+
- Migrate the latest version of the DS2 data store to the migrated data store,
4+
- Delete the entire DS2 data store.
5+
6+
This script deletes the entire DS2 data store, so use with caution.
7+
]]
8+
local DataStoreService = game:GetService("DataStoreService")
9+
local HttpService = game:GetService("HttpService")
10+
local MIGRATED_DS_SCOPE = "global" -- Change to a different scope as needed
11+
local UNIVERSE_ID = -1 -- Change to the universe id
12+
13+
-- Wait for sufficient data store budget
14+
local function waitForBudgetAsync(requestType: Enum.DataStoreRequestType, minBudget: number): ()
15+
while true do
16+
local budget = DataStoreService:GetRequestBudgetForRequestType(requestType)
17+
if budget >= minBudget then
18+
return
19+
end
20+
task.wait(0.5) -- Wait 0.5 second before checking again
21+
end
22+
end
23+
24+
return function(dataStoreName)
25+
-- Parse the datastore name
26+
local ds2Key, playerIdString = string.match(dataStoreName, "^(.*)/([^/]*)$")
27+
28+
if not ds2Key or not playerIdString then
29+
error("Invalid Data Store Name: " .. dataStoreName)
30+
end
31+
32+
local playerId = tonumber(playerIdString)
33+
34+
-- Initialize data stores
35+
local ds2SDS = DataStoreService:GetDataStore(dataStoreName)
36+
local ds2ODS = DataStoreService:GetOrderedDataStore(dataStoreName)
37+
local migratedDS = DataStoreService:GetDataStore(ds2Key, MIGRATED_DS_SCOPE)
38+
39+
-------------
40+
-- MIGRATE --
41+
-------------
42+
43+
-- Modified from BerezaaMethodDataMigrationTool
44+
-- See https://create.roblox.com/store/asset/100741523916104/BETA-Berezaa-Method-Data-Migration-Tool
45+
local migratedData = migratedDS:GetAsync(playerId)
46+
if migratedData == nil then
47+
waitForBudgetAsync(Enum.DataStoreRequestType.GetSortedAsync, 1)
48+
local pages = ds2ODS:GetSortedAsync(false, 1)
49+
50+
-- Get the latest version
51+
local latestVersion = pages:GetCurrentPage()[1]
52+
if latestVersion then
53+
-- Get the data value from the SDS
54+
local version = latestVersion.value
55+
waitForBudgetAsync(Enum.DataStoreRequestType.GetAsync, 2)
56+
local data = ds2SDS:GetAsync(version)
57+
58+
-- Move this data into the new SDS
59+
waitForBudgetAsync(Enum.DataStoreRequestType.SetIncrementAsync, 1)
60+
migratedDS:UpdateAsync(playerId, function(oldData)
61+
if oldData then
62+
return oldData
63+
end
64+
return data
65+
end)
66+
end
67+
print("Info: Migrated latest version from " .. dataStoreName .. " to " .. ds2Key .. ".")
68+
else
69+
print("Info: Data already exists for player " .. playerId .. " in " .. ds2Key .. ".")
70+
end
71+
72+
------------
73+
-- DELETE --
74+
------------
75+
76+
-- Delete the data store
77+
local encodedDataStoreName = HttpService:UrlEncode(dataStoreName)
78+
local apiKey = HttpService:GetSecret("DS_DELETION_API_KEY")
79+
local response = HttpService:RequestAsync({
80+
Url = "https://apis.roblox.com/cloud/v2/universes/" .. UNIVERSE_ID .. "/data-stores/" .. encodedDataStoreName,
81+
Method = "DELETE",
82+
Headers = {
83+
["x-api-key"] = apiKey,
84+
["Content-Type"] = "application/json",
85+
},
86+
})
87+
88+
if response.StatusCode ~= 200 then
89+
error("Failed to delete data store. Status code: " .. response.StatusCode .. ", Status message: " .. response.StatusMessage .. ", Body: " .. response.Body)
90+
end
91+
print("Info: Deleted data store: " .. dataStoreName)
92+
end

0 commit comments

Comments
 (0)