Messaging Service and MarketPlace Service

I am trying to make a dev product, when bought will run a certain event to everyone in every server except you. I have worked out the event part but not the messaging service. My problem is that I need uses receipt info in my event but the event is used in the subscribe async. The event has to stay inside the marketplace service function but the subscribe async has to be above it as then the only way to subscribe is if a player ran the marketplace function. Also, the event is only running halfway even though it works fine in a normal server without cross-server messaging

script:

game:GetService("MarketplaceService").ProcessReceipt = function(receiptInfo)
	local function troll()
			for i, player in ipairs(game.Players:GetPlayers()) do
				local g = game:GetService("Players"):GetNameFromUserIdAsync(receiptInfo.PlayerId)
			wait(3)
			local text = " Has Bought The Multi-Server Troll"
			player.PlayerGui.MainGui.Trolls.Dying.LastStage.Text = g .. text
			player.PlayerGui.MainGui.Trolls.Dying:TweenPosition(UDim2.new(0.5, 0,0.5, 0),"Out","Quad",0.5,true)
				wait(3)
				player.PlayerGui.MainGui.Trolls.Dying:TweenPosition(UDim2.new(0.5, 0,-0.2, 0),"Out","Quad",0.5,true)		
				wait(0.5)
			local hum = (player.Character ~= nil) and player.Character:FindFirstChild("Humanoid") or nil
			if (hum ~= nil and player.UserId ~= receiptInfo.PlayerId) then
				local function takeback1()
					for i,play in ipairs(game.Players:GetPlayers())do
						if play.UserId ~= receiptInfo.PlayerId then
						
							play.leaderstats.Stage.Value = play.leaderstats.Stage.Value - 5
							wait()
							if play.leaderstats.Stage.Value < 0 then
								 play.leaderstats.Stage.Value = 0
							end
								print("Player's Stage Value Minused By 5")
								
						
						
						end
						
					end
				end
				takeback1()
				wait(0.5)
				hum.Health = 0

			end
		end	
		end
		ms:SubscribeAsync("MultiServerTroll",function(message)
			print("Subscribing")
			wait(1)
			troll()
	print(message.Data)
			print(message.Sent)
			
		end)
if receiptInfo.ProductId == *id of product* then
		print(receiptInfo.PlayerId)
		
		wait(5)
		
		ms:PublishAsync("MultiServerTroll","Multi-Server Troll")
		return Enum.ProductPurchaseDecision.PurchaseGranted 
	end
end

Right now, you essentially create a new subscription every time someone buys a product. This will cause other servers not to react until at least one player has purchased the product, and on top, if multiple purchases have been done on a server, the server will react to the message multiple times.

You should generally avoid creating any kind of connection / subscription inside functions which are connected themselves. Creating connections / subscriptions means “listening and reacting” to an event / message.

You’d want all servers to listen and react to the messages exactly one time, so first move the MessagingService subscription out of the Marketplace callback:

game:GetService("MarketplaceService").ProcessReceipt = process
ms:SubscribeAsync("MultiServerTroll", troll)
-- Obviously, troll should also become a function of the global scope.

As for the troll function, since you said you’d want the purchasee not to be affected, you’d probably be best off submitting their name via MessagingService. Here are drafts of what process and troll could look like (define before connecting them with the code snippet above):

function process(receipt) -- Send the message on purchase
    local player = game.Players:GetPlayerByUserId(receipt.PlayerId)
    if receipt.ProductId == *id of product* then
        ms:PublishAsync("MultiServerTroll", player.Name) -- Send the player name to exclude
    end
end

function troll(message) -- Process incoming messages
    local exclude = message.Data
    for i,p in pairs(game.Players:GetPlayers()) do
         if p.Name ~= exclude then -- Exclude the player who sent it
             -- Do the trolling magic
         end
    end
end
1 Like