-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
12 changed files
with
229 additions
and
89 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
import { Controller, type OnStart } from "@flamework/core"; | ||
import { Events } from "client/network"; | ||
import Log from "shared/logger"; | ||
|
||
@Controller() | ||
export class InitializationController implements OnStart { | ||
public onStart(): void { | ||
Events.data.updated.connect((directory, value) => Log.info(`DATA UPDATED! ${directory}: ${value}`)); | ||
Events.data.initialize(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
interface Headers { | ||
[name: string]: string; | ||
} | ||
|
||
interface FirebaseService { | ||
/** | ||
* Sets whether Firebase's data can be updated from server. Data can still be read from realtime Database regardless. | ||
* @param use bool Using Firebase | ||
*/ | ||
useFirebase(use: boolean): void; | ||
/** | ||
* Sets whether Firebase's data can be updated from server. Data can still be read from realtime Database regardless. | ||
* @param name Given name of a JSON Object in the Realtime Database. | ||
* @param scope Optional scope. | ||
* @returns Firebase database | ||
*/ | ||
fetch(dataKey: string, database?: string): Firebase; | ||
} | ||
|
||
interface Firebase { | ||
/** | ||
* A method to get a datastore with the same name and scope. | ||
* @returns Roblox GlobalDataStore representing the Firebase database. | ||
*/ | ||
getDatastore(): GlobalDataStore; | ||
/** | ||
* Returns the value of the entry in the database JSON Object with the given key. | ||
* @param directory Directory of the value that you are look for. E.g. "PlayerSaves" or "PlayerSaves/Stats". | ||
* @returns Value associated with directory. | ||
*/ | ||
get<T>(directory: string): T; | ||
/** | ||
* Sets the value of the key. This overwrites any existing data stored in the key. | ||
* @param directory Directory of the value that you are look for. E.g. "PlayerSaves" or "PlayerSaves/Stats". | ||
* @param value Value can be any basic data types. It's recommened you HttpService:JSONEncode() your values before passing it through. | ||
* @param headers Optional HTTPRequest Header overwrite. Default is {["X-HTTP-Method-Override"]="PUT"}. | ||
*/ | ||
set<T>(directory: string, value: T, headers?: Headers): void; | ||
/**' | ||
* Increments the value of a particular key and returns the incremented value. | ||
* @param directory Directory of the value that you are look for. E.g. "PlayerSaves" or "PlayerSaves/Stats". | ||
* @param delta The amount to increment by. | ||
* @returns The new incremented value | ||
*/ | ||
increment(directory: string, delta: number): number; | ||
/** | ||
* Removes the given key from the data store and returns the value associated with that key. | ||
* @param directory Directory of the value that you are look for. E.g. "PlayerSaves" or "PlayerSaves/Stats". | ||
*/ | ||
delete(directory: string): void; | ||
/** | ||
* Retrieves the value of a key from a data store and updates it with a new value. | ||
* @param directory Directory of the value that you are look for. E.g. "PlayerSaves" or "PlayerSaves/Stats". | ||
* @param callback Works similarly to Roblox's GlobalDatastore:UpdateAsync(). | ||
*/ | ||
update<T>(directory: string, callback: (currentData: T) => T): void; | ||
} | ||
|
||
declare const Firebase: FirebaseService; | ||
export = Firebase; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
--TODO: store in datastore | ||
--== Configuration; | ||
local defaultDatabase = "https://roblox-tabletop-lounge-default-rtdb.firebaseio.com/"; -- Set your database link | ||
local authenticationToken = "9vql32DWOoZGjQzOiO28XWGhsexcPN8ejId8FsTF"; -- Authentication Token | ||
|
||
--== Variables; | ||
local HttpService = game:GetService("HttpService"); | ||
local DataStoreService = game:GetService("DataStoreService"); | ||
|
||
local FirebaseService = {}; | ||
local UseFirebase = true; | ||
|
||
--== Script; | ||
|
||
function FirebaseService:useFirebase(use) | ||
UseFirebase = use; | ||
end | ||
|
||
function FirebaseService:fetch(name, database) | ||
database = database or defaultDatabase; | ||
local datastore = DataStoreService:GetDataStore(name); | ||
local databaseName = database..HttpService:UrlEncode(name); | ||
local authentication = ".json?auth="..authenticationToken; | ||
local Firebase = {}; | ||
|
||
function Firebase:getDatastore() | ||
return datastore; | ||
end | ||
|
||
function Firebase:get(directory) | ||
--== Firebase Get; | ||
local data; | ||
local endpoint = databaseName..HttpService:UrlEncode(directory and "/"..directory or "")..authentication; | ||
local tries = 0; repeat until pcall(function() | ||
tries += 1; | ||
data = HttpService:GetAsync(endpoint, true); | ||
end) or tries > 2; | ||
return if data ~= nil then HttpService:JSONDecode(data) else nil; | ||
end | ||
|
||
function Firebase:set(directory, value, headers) | ||
if not UseFirebase then return end | ||
if value == "[]" then self:delete(directory); return end; | ||
|
||
--== Firebase Set; | ||
headers = headers or {["X-HTTP-Method-Override"]="PUT"}; | ||
local replyJson = ""; | ||
local endpoint = databaseName..HttpService:UrlEncode(directory and "/"..directory or "")..authentication; | ||
local success, errorMessage = pcall(function() | ||
replyJson = HttpService:PostAsync( | ||
endpoint, HttpService:JSONEncode(value), | ||
Enum.HttpContentType.ApplicationUrlEncoded, false, headers | ||
); | ||
end); | ||
if not success then | ||
warn("[Firebase] Error: "..errorMessage); | ||
pcall(function() | ||
replyJson = HttpService:JSONDecode(replyJson or "[]"); | ||
end) | ||
end | ||
end | ||
|
||
function Firebase:delete(directory) | ||
if not UseFirebase then return end | ||
self:set(directory, nil, {["X-HTTP-Method-Override"]="DELETE"}); | ||
end | ||
|
||
function Firebase:increment(directory, delta) | ||
delta = delta or 1; | ||
if type(delta) ~= "number" then warn("[Firebase] Error: Increment delta is not a number for key ("..directory.."), delta(",delta,")"); return end; | ||
local data = self:get(directory) or 0; | ||
if data and type(data) == "number" then | ||
data += delta; | ||
self:set(directory, data); | ||
else | ||
warn("[Firebase] Error: Invalid data type to increment for key ("..directory..")"); | ||
end | ||
return data; | ||
end | ||
|
||
function Firebase:update(directory, callback) | ||
local data = self:get(directory); | ||
local callbackData = callback(data); | ||
if callbackData then | ||
self:set(directory, callbackData); | ||
end | ||
end | ||
|
||
print("fetched firebase") | ||
return Firebase; | ||
end | ||
|
||
return FirebaseService; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
import { OnInit, Service } from "@flamework/core"; | ||
import Signal from "@rbxts/signal"; | ||
|
||
import { DataValue } from "shared/data-models/generic"; | ||
import { Events, Functions } from "server/network"; | ||
import Firebase from "server/classes/firebase"; | ||
import Log from "shared/logger"; | ||
|
||
import type { LogStart } from "shared/hooks"; | ||
|
||
const PlayerData = Firebase.fetch("playerData"); | ||
|
||
@Service() | ||
export class DatabaseService implements OnInit, LogStart { | ||
public readonly loaded = new Signal<(player: Player) => void>; | ||
|
||
public onInit(): void { | ||
Events.data.initialize.connect((player) => this.setup(player)); | ||
Events.data.set.connect((player, key, value) => this.set(player, key, value)); | ||
Events.data.increment.connect((player, key, amount) => this.increment(player, key, amount)) | ||
Functions.data.get.setCallback((player, key) => this.get(player, key)); | ||
} | ||
|
||
public get<T extends DataValue>(player: Player, directory: string): T { | ||
const fullDirectory = this.getDirectoryForPlayer(player, directory); | ||
return PlayerData.get(fullDirectory); | ||
} | ||
|
||
public set<T extends DataValue>(player: Player, directory: string, value: T): void { | ||
const fullDirectory = this.getDirectoryForPlayer(player, directory); | ||
PlayerData.set(fullDirectory, value); | ||
Events.data.updated(player, fullDirectory, value); | ||
} | ||
|
||
public increment(player: Player, directory: string, amount = 1): number { | ||
const fullDirectory = this.getDirectoryForPlayer(player, directory); | ||
return PlayerData.increment(fullDirectory, amount); | ||
} | ||
|
||
public delete(player: Player, directory: string): void { | ||
const fullDirectory = this.getDirectoryForPlayer(player, directory); | ||
return PlayerData.delete(fullDirectory); | ||
} | ||
|
||
private setup(player: Player): void { | ||
this.initialize(player, "playtime", 0); | ||
this.loaded.Fire(player); | ||
Log.info("Initialized data"); | ||
} | ||
|
||
private initialize<T extends DataValue>(player: Player, directory: string, initialValue: T): void { | ||
const fullDirectory = this.getDirectoryForPlayer(player, directory); | ||
const value = PlayerData.get<Maybe<T>>(fullDirectory) ?? initialValue; | ||
this.set(player, directory, value); | ||
} | ||
|
||
private getDirectoryForPlayer(player: Player, directory: string) { | ||
return `${player.UserId}/${directory}`; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,15 +1,10 @@ | ||
export interface GameDataModel { | ||
// put all of your data fields and types here | ||
// for example: | ||
gold: number; | ||
gems: number; | ||
playtime: number; | ||
} | ||
|
||
export type DataValue = GameDataModel[DataKey]; | ||
export type DataKey = keyof GameDataModel; | ||
|
||
export const DataKeys: DataKey[] = [ | ||
// put all of the keys for your data here | ||
// using the last example's data, you would write: | ||
"gold", "gems" | ||
"playtime" | ||
]; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters