Skip to content

Commit

Permalink
Merge pull request #411 from Quenty/users/quenty/product_fix
Browse files Browse the repository at this point in the history
Users/quenty/product fix
  • Loading branch information
Quenty authored Sep 21, 2023
2 parents c121b83 + a43e0f9 commit 08c01fd
Show file tree
Hide file tree
Showing 37 changed files with 507 additions and 106 deletions.
2 changes: 2 additions & 0 deletions src/chatproviderservice/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,13 @@
"@quenty/permissionprovider": "file:../permissionprovider",
"@quenty/playerbinder": "file:../playerbinder",
"@quenty/playerutils": "file:../playerutils",
"@quenty/preferredparentutils": "file:../preferredparentutils",
"@quenty/promise": "file:../promise",
"@quenty/richtext": "file:../richtext",
"@quenty/rx": "file:../rx",
"@quenty/rxbinderutils": "file:../rxbinderutils",
"@quenty/servicebag": "file:../servicebag",
"@quenty/signal": "file:../signal",
"@quenty/string": "file:../string",
"@quenty/table": "file:../table",
"@quenty/valueobject": "file:../valueobject"
Expand Down
12 changes: 11 additions & 1 deletion src/chatproviderservice/src/Client/ChatProviderServiceClient.lua
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ local require = require(script.Parent.loader).load(script)
local TextChatService = game:GetService("TextChatService")
local Players = game:GetService("Players")

local Maid = require("Maid")
local Signal = require("Signal")
local String = require("String")

local ChatProviderServiceClient = {}
Expand All @@ -15,11 +17,14 @@ ChatProviderServiceClient.ServiceName = "ChatProviderServiceClient"
function ChatProviderServiceClient:Init(serviceBag)
assert(not self._serviceBag, "Already initialized")
self._serviceBag = assert(serviceBag, "No serviceBag")
self._maid = Maid.new()

-- State
self.MessageIncoming = self._maid:Add(Signal.new())

-- External
self._serviceBag:GetService(require("CmdrServiceClient"))


-- Binders
self._serviceBag:GetService(require("ChatTagClient"))
self._serviceBag:GetService(require("ChatProviderTranslator"))
Expand All @@ -28,6 +33,8 @@ end

function ChatProviderServiceClient:Start()
TextChatService.OnIncomingMessage = function(textChatMessage)
self.MessageIncoming:Fire(textChatMessage)

local textSource = textChatMessage.TextSource
if not textSource then
return
Expand Down Expand Up @@ -60,5 +67,8 @@ function ChatProviderServiceClient:_renderTags(textSource)
return hasChatTags:GetAsRichText()
end

function ChatProviderServiceClient:Destroy()
self._maid:DoCleaning()
end

return ChatProviderServiceClient
11 changes: 11 additions & 0 deletions src/chatproviderservice/src/Server/ChatProviderService.lua
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,17 @@
local require = require(script.Parent.loader).load(script)

local ServerScriptService = game:GetService("ServerScriptService")
local TextChatService = game:GetService("TextChatService")

local ChatTagDataUtils = require("ChatTagDataUtils")
local LocalizedTextUtils = require("LocalizedTextUtils")
local Maid = require("Maid")
local PermissionLevel = require("PermissionLevel")
local PreferredParentUtils = require("PreferredParentUtils")
local Promise = require("Promise")
local Rx = require("Rx")
local RxBrioUtils = require("RxBrioUtils")
local Signal = require("Signal")

local ChatProviderService = {}
ChatProviderService.ServiceName = "ChatProviderService"
Expand All @@ -22,6 +25,9 @@ function ChatProviderService:Init(serviceBag)
self._serviceBag = assert(serviceBag, "No serviceBag")
self._maid = Maid.new()

-- State
self.MessageIncoming = self._maid:Add(Signal.new())

-- External
self._serviceBag:GetService(require("CmdrService"))
self._serviceBag:GetService(require("PermissionService"))
Expand All @@ -47,6 +53,11 @@ function ChatProviderService:Init(serviceBag)
}))
end

function ChatProviderService:AddChatCommand(textChatCommand)
assert(typeof(textChatCommand) == "Instance", "Bad textChatCommand")

textChatCommand.Parent = PreferredParentUtils.getPreferredParent(TextChatService, "ChatProviderCommands")
end

--[=[
Sets the developer chat tag
Expand Down
1 change: 1 addition & 0 deletions src/cmdrservice/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
"Quenty"
],
"dependencies": {
"@quenty/chatproviderservice": "file:../chatproviderservice",
"@quenty/loader": "file:../loader",
"@quenty/maid": "file:../maid",
"@quenty/permissionprovider": "file:../permissionprovider",
Expand Down
21 changes: 20 additions & 1 deletion src/cmdrservice/src/Client/CmdrServiceClient.lua
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ local Promise = require("Promise")
local promiseChild = require("promiseChild")
local PromiseUtils = require("PromiseUtils")
local String = require("String")
local ChatProviderServiceClient = require("ChatProviderServiceClient")
local Remoting = require("Remoting")

local CmdrServiceClient = {}
CmdrServiceClient.ServiceName = "CmdrServiceClient"
Expand All @@ -30,6 +32,7 @@ function CmdrServiceClient:Init(serviceBag)

self._maid = Maid.new()
self._permissionServiceClient = self._serviceBag:GetService(PermissionServiceClient)
self._chatProviderServiceClient = self._serviceBag:GetService(ChatProviderServiceClient)

self:PromiseCmdr():Then(function(cmdr)
cmdr.Registry:RegisterHook("BeforeRun", function(context)
Expand Down Expand Up @@ -69,7 +72,6 @@ function CmdrServiceClient:Init(serviceBag)
return nil
end
end)

end)
end

Expand All @@ -79,6 +81,8 @@ end
function CmdrServiceClient:Start()
assert(self._serviceBag, "Not initialized")

self._remoting = self._maid:Add(Remoting.new(ReplicatedStorage, "CmdrService"))

self._maid:GivePromise(PromiseUtils.all({
self:PromiseCmdr(),
self._maid:GivePromise(self._permissionServiceClient:PromisePermissionProvider())
Expand Down Expand Up @@ -106,6 +110,21 @@ function CmdrServiceClient:_setBindings(cmdr)
end
end))

self._maid:GiveTask(self._remoting.OpenCmdr:Connect(function()
cmdr:Show()
end))

-- same with chat provider
self._maid:GiveTask(self._chatProviderServiceClient.MessageIncoming:Connect(function(textChatMessage)
if not (textChatMessage.TextSource and textChatMessage.TextSource.UserId == Players.LocalPlayer.UserId) then
return
end

if String.startsWith(textChatMessage.Text, "/cmdr") then
cmdr:Show()
end
end))

-- Race condition
task.defer(function()
-- Default blink for debugging purposes
Expand Down
42 changes: 40 additions & 2 deletions src/cmdrservice/src/Server/CmdrService.lua
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,14 @@
local require = require(script.Parent.loader).load(script)

local HttpService = game:GetService("HttpService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")

local PermissionService = require("PermissionService")
local CmdrTemplateProviderServer = require("CmdrTemplateProviderServer")
local Promise = require("Promise")
local Maid = require("Maid")
local Remoting = require("Remoting")

local CmdrService = {}
CmdrService.ServiceName = "CmdrService"
Expand All @@ -25,10 +28,18 @@ local GLOBAL_REGISTRY = setmetatable({}, {__mode = "kv"})
@param serviceBag ServiceBag
]=]
function CmdrService:Init(serviceBag)
assert(not self._promiseCmdr, "Already initialized")

assert(not self._serviceBag, "Already initialized")
self._maid = Maid.new()
self._serviceBag = assert(serviceBag, "No serviceBag")

-- State
self._remoting = self._maid:Add(Remoting.new(ReplicatedStorage, "CmdrService"))
self._remoting:DeclareEvent("OpenCmdr")

-- External
self._chatProviderService = self._serviceBag:GetService(require("ChatProviderService"))

-- Internal
self._cmdrTemplateProviderServer = self._serviceBag:GetService(CmdrTemplateProviderServer)

self._serviceId = HttpService:GenerateGUID(false)
Expand Down Expand Up @@ -86,6 +97,10 @@ function CmdrService:Init(serviceBag)
GLOBAL_REGISTRY[self._serviceId] = self
end

function CmdrService:Start()
self:_createActivateChatCommand()
end

--[=[
Returns cmdr
@return Promise<Cmdr>
Expand Down Expand Up @@ -143,6 +158,29 @@ function CmdrService:RegisterCommand(commandData, execute)
end)
end

function CmdrService:_createActivateChatCommand()
local command = Instance.new("TextChatCommand")
command.Name = "OpenCmdrCommand"
command.PrimaryAlias = "/cmdr"

self._maid:GiveTask(command)
self._maid:GiveTask(command.Triggered:Connect(function(originTextSource, _unfilteredText)
local player = Players:GetPlayerByUserId(originTextSource.UserId)
if not player then
return
end

self._permissionService:PromiseIsAdmin(player):Then(function(isAdmin)
if isAdmin then
self._remoting.OpenCmdr:FireClient(player)
end
end)
end))

self._chatProviderService:AddChatCommand(command)
end


--[=[
Private function used by the execution template to retrieve the execution function.
@param cmdrCommandId string
Expand Down
15 changes: 4 additions & 11 deletions src/datastore/src/Server/DataStore.lua
Original file line number Diff line number Diff line change
Expand Up @@ -102,17 +102,10 @@ function DataStore.new(robloxDataStore, key)
self._robloxDataStore = robloxDataStore or error("No robloxDataStore")
self._debugWriting = DEFAULT_DEBUG_WRITING

self._autoSaveTimeSeconds = ValueObject.new(DEFAULT_AUTO_SAVE_TIME_SECONDS)
self._maid:GiveTask(self._autoSaveTimeSeconds)

self._jitterProportion = ValueObject.new(DEFAULT_JITTER_PROPORTION, "number")
self._maid:GiveTask(self._jitterProportion)

self._syncOnSave = ValueObject.new(false, "boolean")
self._maid:GiveTask(self._syncOnSave)

self._loadedOk = ValueObject.new(false, "boolean")
self._maid:GiveTask(self._loadedOk)
self._autoSaveTimeSeconds = self._maid:Add(ValueObject.new(DEFAULT_AUTO_SAVE_TIME_SECONDS))
self._jitterProportion = self._maid:Add(ValueObject.new(DEFAULT_JITTER_PROPORTION, "number"))
self._syncOnSave = self._maid:Add(ValueObject.new(false, "boolean"))
self._loadedOk = self._maid:Add(ValueObject.new(false, "boolean"))

self._userIdList = nil

Expand Down
1 change: 1 addition & 0 deletions src/gameproductservice/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
"@quenty/baseobject": "file:../baseobject",
"@quenty/binder": "file:../binder",
"@quenty/brio": "file:../brio",
"@quenty/enumutils": "file:../enumutils",
"@quenty/gameconfig": "file:../gameconfig",
"@quenty/instanceutils": "file:../instanceutils",
"@quenty/loader": "file:../loader",
Expand Down
25 changes: 1 addition & 24 deletions src/gameproductservice/src/Server/GameProductService.lua
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,6 @@

local require = require(script.Parent.loader).load(script)

local Players = game:GetService("Players")

local Maid = require("Maid")
local GameProductServiceHelper = require("GameProductServiceHelper")
local GameConfigAssetTypeUtils = require("GameConfigAssetTypeUtils")
Expand All @@ -37,7 +35,7 @@ function GameProductService:Init(serviceBag)

-- External
self._gameConfigService = self._serviceBag:GetService(require("GameConfigService"))
self._receiptProcessingService = self._serviceBag:GetService(require("ReceiptProcessingService"))
self._serviceBag:GetService(require("ReceiptProcessingService"))

-- Internal
self._binders = self._serviceBag:GetService(require("GameProductBindersServer"))
Expand Down Expand Up @@ -84,10 +82,6 @@ function GameProductService:Start()
exposeSignal(self.AssetPurchased, GameConfigAssetTypes.ASSET)
exposeSignal(self.BundlePurchased, GameConfigAssetTypes.BUNDLE)
end))

self._maid:GiveTask(self._receiptProcessingService:RegisterReceiptProcessor(function(receiptInfo)
return self:_handleProcessReceipt(receiptInfo)
end))
end

--[=[
Expand Down Expand Up @@ -200,23 +194,6 @@ function GameProductService:ObservePlayerOwnership(player, assetType, idOrKey)
return self._helper:ObservePlayerOwnership(player, assetType, idOrKey)
end

function GameProductService:_handleProcessReceipt(receiptInfo)
local player = Players:GetPlayerByUserId(receiptInfo.PlayerId)
if not player then
-- The player probably left the game
-- If they come back, the callback will be called again
return Enum.ProductPurchaseDecision.NotProcessedYet
end

local productManager = self._binders.PlayerProductManager:Get(player)
if productManager then
return productManager:HandleProcessReceipt(player, receiptInfo)
end

-- Free money?
return Enum.ProductPurchaseDecision.PurchaseGranted
end

--[=[
Cleans up the game product service
]=]
Expand Down
20 changes: 10 additions & 10 deletions src/gameproductservice/src/Server/Manager/PlayerProductManager.lua
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,12 @@
local require = require(script.Parent.loader).load(script)

local BaseObject = require("BaseObject")
local EnumUtils = require("EnumUtils")
local GameConfigAssetTypes = require("GameConfigAssetTypes")
local GameConfigAssetTypeUtils = require("GameConfigAssetTypeUtils")
local GameConfigService = require("GameConfigService")
local PlayerMarketeer = require("PlayerMarketeer")
local ReceiptProcessingService = require("ReceiptProcessingService")
local Remoting = require("Remoting")

local PlayerProductManager = setmetatable({}, BaseObject)
Expand All @@ -30,6 +32,7 @@ function PlayerProductManager.new(player, serviceBag)

self._serviceBag = assert(serviceBag, "No serviceBag")
self._gameConfigService = self._serviceBag:GetService(GameConfigService)
self._receiptProcessingService = self._serviceBag:GetService(ReceiptProcessingService)

self._marketeer = PlayerMarketeer.new(self._obj, self._gameConfigService:GetConfigPicker())
self._maid:GiveTask(self._marketeer)
Expand All @@ -45,6 +48,10 @@ function PlayerProductManager.new(player, serviceBag)
self:_handlePromptFinished(...)
end))

self._maid:GiveTask(self._receiptProcessingService:ObserveReceiptProcessedForPlayer(self._obj):Subscribe(function(receiptInfo, result)
self:_handleProcessReceipt(receiptInfo, result)
end))

-- Initialize attributes
self._marketeer:GetOwnershipTrackerOrError(GameConfigAssetTypes.PASS):SetWriteAttributesEnabled(true)

Expand Down Expand Up @@ -73,23 +80,16 @@ function PlayerProductManager:_handlePromptFinished(player, assetType, assetId,
assetTracker:HandlePurchaseEvent(assetId, isPurchased)
end

--[=[
Handles the receipt processing. Not expected to be called immediately
@param player number
@param receiptInfo table
@return ProductPurchaseDecision
]=]
function PlayerProductManager:HandleProcessReceipt(player, receiptInfo)
assert(self._obj == player, "Bad player")
function PlayerProductManager:_handleProcessReceipt(receiptInfo, productPurchaseDecision)
assert(type(receiptInfo) == "table", "Bad receiptInfo")
assert(EnumUtils.isOfType(Enum.ProductPurchaseDecision, productPurchaseDecision), "Bad decision")

local assetTracker = self._marketeer:GetAssetTrackerOrError(GameConfigAssetTypes.PRODUCT)

-- Notify the player
self._remoting.NotifyReceiptProcessed:FireClient(self._obj, receiptInfo)

return assetTracker:HandleProcessReceipt(player, receiptInfo)
assetTracker:HandleProcessReceipt(self._obj, receiptInfo)
end

return PlayerProductManager
Original file line number Diff line number Diff line change
Expand Up @@ -265,16 +265,12 @@ end
@param player Player
@param receiptInfo ReceiptInfo
@return ProductPurchaseDecision
]=]
function PlayerAssetMarketTracker:HandleProcessReceipt(player, receiptInfo)
assert(typeof(player) == "Instance", "Bad player")
assert(self._receiptProcessingExpected, "No receiptProcessingExpected")

self:_handlePurchaseEvent(receiptInfo.ProductId, true, true)

-- Always grant...
return Enum.ProductPurchaseDecision.PurchaseGranted
end

return PlayerAssetMarketTracker
Loading

0 comments on commit 08c01fd

Please sign in to comment.