How would I send a data between a lobby and reserved place?

Hey there. So I’m currently making a party system that teleport a player to a reserved place and it goes very well.
But i want to get a data from the created party room and send it to the reserved place. Basically you can customize the map you want to play in from the lobby and when you are teleported to the reserved place, the map that you choose from the lobby is the one that shows up.
I have no idea to get this thing work so any help would be appreciated!!!.

2 Likes

That is done through MessageService. Once you reserve a private server, publish the data that you want to pass along using the private server’s id. Example:

– Sending server (lobby)

    local success, teleportResult = pcall(function() 
		return TeleportService:TeleportAsync(Place_Id, playersToTeleport, options)
	end)
	if success then
		MessagingService:PublishAsync(teleportResult.PrivateServerId, teleportData)
	end

– Receiving server (game)

MessagingService:SubscribeAsync(game.PrivateServerId, function(data)
   -- stuff goes here
end

With MessagingService you have to worry about timing the message after the reserved server is actually running, as if you fire prematurely the data will be lost.
For this reason, I recommend passing party data through the TeleportData parameter of TeleportToPrivateServer().
You can literally just pass a dictionary through containing all necessary data like so:

local tpdata = {Map = "Default", Difficulty = 3}
TeleportService:TeleportToPrivateServer(id, accessCode, players, "", tpdata)
1 Like

TeleportData is not replicated through the server so you would have to rely on clients to get it, which isn’t reliable. MessagingService is currently the most reliable option to go through for this kind of job. Also, once you open the server using reserve private server, it is ready to listen to :PublishAsync, so that scenario would be unlikely to happen.

This isn’t true. You can access TeleportData from the server with Player:GetJoinData()

Ah yes, I forgot about that. It still isn’t reliable since data gets mixed up between teleportations (I’ve already experienced it). Listening to that specific private server id is way more reliable.

wdym it gets mixed up? I have never experienced such a thing


" As this data is transmitted by the client, it can still potentially be abused by an exploiter. Sensitive data such as player currency should be transmitted via a secure solution like Memory Stores."

party options are not sensitive data

It is. You can load a map that you haven’t unlocked yet, or switch up the leader’s name (if there are benefits to hosting a party). Also, which player are you going to get the data from? You would have to wait until a player joins before loading in the map.

There is nothing stopping you from validating the party options on the server, and not allowing the player to pick a map they haven’t unlocked. It would make sense to take the data from the first player who joins the game.

That would be bad in a group setting. Would you kick everyone because one person messed up with the teleport data? Or load in a default map which isn’t what the host chose?

There are advantages to both approaches. MessagingService delivery is stated to be “best effort and not guaranteed” in the documentation. I guess it depends on the developer’s priorities. Sure, there’s a small chance an exploiter could join their friend’s party and override the host’s decisions, but you’re only gonna form parties with your trusted friends more than likely anyway. On the contrary, if MessagingService doesn’t fail, you can trust everything that comes from the transmission since it is all server side. But when it does fail you’re just left with a useless private server.
My advice to @SHARPTHRIX is to pick whichever solution suits his needs the best.

2 Likes

You could use the MemoryStoreService. It’s quite similar to DataStoreService, except it’s intended for temporary data storage, where DataStoreService is meant for permanent data storage.

If you want to store a dictionary that looks like this:

local data = {
    Map = "MapName",
    PlayerCount = 20,
    TimeLimit = 300,
    ScoreLimit = 50
}

Do this:

local MemoryStoreService = game:GetService("MemoryStoreService")
local reservedServers = MemoryStoreService:GetHashMap("ReservedServers")

local DATA_EXPIRATION_TIME = 120
reservedServers:SetAsync(privateServerId, data, DATA_EXPIRATION_TIME)

If you want to store a value, in this case the data variable, and you don’t necessarily care what order it’s in, you should call the GetHashMap function on the MemoryStoreService. A HashMap is the exact same thing as what the data variable is, a dictionary, which is a table with keys/indexes that are anything other than a number. When you call the GetHashMap function you just give it a name.

It works pretty much the exact same as a DataStore, though it’s faster than DataStore(read that somewhere in the docs). You give it a name and call GetAsync and SetAsync on it.

Whenever you call TeleportAsync it’ll return a TeleportAsyncResult object, which has a PrivateServerId property. This is a string, and you can use it as a key when using SetAsync on the HashMap, as you can see in the above code. This allows you to easily pinpoint which dictionary belongs to which server.

Whenever you call SetAsync on a MemoryStoreHashMap, it’s important you of course specify not only the key and the value, but also the expiration, which is the third value you pass in. I think the default is 45 days, which is 3.8 million seconds, but for this, a good time would be 2 minutes or 120 seconds.

Whenever a server first starts, you can run this code:

local MemoryStoreService = game:GetService("MemoryStoreService")
local reservedServers = MemoryStoreService:GetHashMap("ReservedServers")

-- Gotta make sure the PrivateServerId isn't blank, meaning it's either a reserved
-- or private server, and if the PrivateServerOwnerId is 0 that means it's a reserved server.
if (game.PrivateServerId ~= "" and game.PrivateServerOwnerId == 0) then
    local data = reservedServers:GetAsync(game.PrivateServerId)
    if (data) then
        for index, value in pairs(data) do
            print(index, value)
        end
    end
end

And there you go. That’s how you can reliably set up a system where you can quickly set data from the old server and get that data from that new server. The GetJoinData function of the Player object can be spoofed by exploiters looking to ruin the game, so don’t rely on that for the transmission of crucial data.

2 Likes

Oh woww I didnt expect that alot of solution to be posted here lol. Thanks guys I will try them one by one and i will let you guys know about it if anything works!!!
appreciate it alot!!

Edit:
So far the solution given by @goldenguy9 works the best for me.
Buuut the solution that Rinpix and NotTrulyEpic gaves also can work the best as an alternative :+1:

3 Likes

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.