mirror of
https://github.com/copyrighttxt/watrbx-game-engine.git
synced 2026-09-05 05:07:48 +00:00
GEEKING
This commit is contained in:
@@ -0,0 +1,286 @@
|
||||
--[[
|
||||
// FriendsData.lua
|
||||
|
||||
// Caches the current friends pagination to used by anyone in the app
|
||||
// polls every POLL_DELAY and gets the latest pagination
|
||||
|
||||
// TODO:
|
||||
Need polling to update friends. How are we going to handle all the cases
|
||||
like the person you're selecting going offline, etc..
|
||||
]]
|
||||
local CoreGui = game:GetService("CoreGui")
|
||||
local GuiRoot = CoreGui:FindFirstChild("RobloxGui")
|
||||
local Modules = GuiRoot:FindFirstChild("Modules")
|
||||
local Players = game:GetService('Players')
|
||||
local HttpService = game:GetService('HttpService')
|
||||
local PlatformService = nil
|
||||
pcall(function() PlatformService = game:GetService('PlatformService') end)
|
||||
|
||||
local Http = require(Modules:FindFirstChild('Http'))
|
||||
local Utility = require(Modules:FindFirstChild('Utility'))
|
||||
local EventHub = require(Modules:FindFirstChild('EventHub'))
|
||||
local UserData = require(Modules:FindFirstChild('UserData'))
|
||||
local SortData = require(Modules:FindFirstChild('SortData'))
|
||||
local Strings = require(Modules:FindFirstChild('LocalizedStrings'))
|
||||
|
||||
-- NOTE: This is just required for fixing Usernames in auto-generatd games
|
||||
local GameData = require(Modules:FindFirstChild('GameData'))
|
||||
local ConvertMyPlaceNameInXboxAppFlag = Utility.IsFastFlagEnabled("ConvertMyPlaceNameInXboxApp")
|
||||
|
||||
local FriendsData = {}
|
||||
|
||||
|
||||
local pollDelay = Utility.GetFastVariable("XboxFriendsPolling")
|
||||
if pollDelay then
|
||||
pollDelay = tonumber(pollDelay)
|
||||
end
|
||||
|
||||
local POLL_DELAY = pollDelay or 30
|
||||
local STATUS = {
|
||||
UNKNOWN = "Unknown";
|
||||
ONLINE = "Online";
|
||||
OFFLINE = "Offline";
|
||||
AWAY = "Away";
|
||||
}
|
||||
|
||||
local isOnlineFriendsPolling = false
|
||||
local myCurrentFriendsData = nil
|
||||
local updateEventCns = {}
|
||||
|
||||
local function filterXboxFriends(friendsData)
|
||||
local titleId = PlatformService and tostring(PlatformService:GetTitleId()) or ''
|
||||
local onlineRobloxFriendsData = {}
|
||||
local onlineRobloxFriendsUserIds = {}
|
||||
local onlineFriendsData = {}
|
||||
-- filter into two list, those online in roblox and those online
|
||||
-- for those online, also get their roblox userId
|
||||
for i = 1, #friendsData do
|
||||
local data = friendsData[i]
|
||||
if data["status"] and data["status"] == STATUS.ONLINE then
|
||||
if data["rich"] then
|
||||
-- get rich presence table, last entry is most recent activity from user
|
||||
local richTbl = data["rich"]
|
||||
richTbl = richTbl[#richTbl]
|
||||
if richTbl["titleId"] == titleId then
|
||||
table.insert(onlineRobloxFriendsData, data)
|
||||
table.insert(onlineRobloxFriendsUserIds, data["robloxuid"])
|
||||
else
|
||||
table.insert(onlineFriendsData, data)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- now get roblox friends presence in roblox
|
||||
local robloxPresence = {}
|
||||
if #onlineRobloxFriendsUserIds > 0 then
|
||||
local jsonTable = {}
|
||||
jsonTable["userIds"] = onlineRobloxFriendsUserIds
|
||||
local jsonPostBody = HttpService:JSONEncode(jsonTable)
|
||||
robloxPresence = Http.GetUsersOnlinePresenceAsync(jsonPostBody)
|
||||
if robloxPresence and robloxPresence["UserPresences"] then
|
||||
robloxPresence = robloxPresence["UserPresences"]
|
||||
end
|
||||
end
|
||||
|
||||
-- now append roblox presence data to each users data
|
||||
for i = 1, #onlineRobloxFriendsData do
|
||||
if robloxPresence[i] then
|
||||
local data = onlineRobloxFriendsData[i]
|
||||
-- make sure we have the right person
|
||||
for j = 1, #robloxPresence do
|
||||
local rbxPresenceData = robloxPresence[j]
|
||||
local rbxUserId = rbxPresenceData["VisitorId"]
|
||||
if rbxUserId == data["robloxuid"] then
|
||||
if rbxPresenceData["IsOnline"] == true then
|
||||
local placeId = rbxPresenceData["PlaceId"]
|
||||
local lastLocation = rbxPresenceData["LastLocation"]
|
||||
|
||||
-- If the lastLocation for a user is some user place with a GeneratedUsername in it
|
||||
-- then replace it with the actual creator name!
|
||||
if ConvertMyPlaceNameInXboxAppFlag and placeId and lastLocation and GameData:ExtractGeneratedUsername(lastLocation) then
|
||||
local gameCreator = GameData:GetGameCreatorAsync(placeId)
|
||||
if gameCreator then
|
||||
lastLocation = GameData:GetFilteredGameName(lastLocation, gameCreator)
|
||||
end
|
||||
end
|
||||
|
||||
-- If the user is not in a featured game, then hide their presence
|
||||
if placeId and not SortData:IsFeaturedGameAsync(placeId) then
|
||||
data["IsPrivateSession"] = true
|
||||
lastLocation = Strings:LocalizedString("PrivateSessionPhrase")
|
||||
end
|
||||
|
||||
data["PlaceId"] = placeId
|
||||
data["LastLocation"] = lastLocation
|
||||
end
|
||||
-- remove from list and gtfo
|
||||
table.remove(robloxPresence, j)
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- now sort those in roblox
|
||||
table.sort(onlineRobloxFriendsData, function(a, b)
|
||||
if a["PlaceId"] and b["PlaceId"] then
|
||||
return a["display"] < b["display"]
|
||||
end
|
||||
if a["PlaceId"] then
|
||||
return true
|
||||
end
|
||||
if b["PlaceId"] then
|
||||
return false
|
||||
end
|
||||
|
||||
return a["display"] < b["display"]
|
||||
end)
|
||||
|
||||
-- now sort all other friends
|
||||
table.sort(onlineFriendsData, function(a, b)
|
||||
return a["display"] < b["display"]
|
||||
end)
|
||||
|
||||
-- now concat tables
|
||||
for i = 1, #onlineFriendsData do
|
||||
onlineRobloxFriendsData[#onlineRobloxFriendsData + 1] = onlineFriendsData[i]
|
||||
end
|
||||
|
||||
return onlineRobloxFriendsData
|
||||
end
|
||||
|
||||
--[[
|
||||
// Returns table with an array with the key friends
|
||||
// Keys
|
||||
// xuid - number, xbox user id
|
||||
// gamertage - string, users gamertag
|
||||
// display - string, users display name (depends on user settings, could be same as gamertag)
|
||||
// robloxuid - number, users roblox userId
|
||||
// status - string (Online, Away, Offline, Unknown)
|
||||
// rich - array of rich presence, might currently be empty?
|
||||
// timestamp - number, UTC timestamp of record
|
||||
// device - string, XboxOne, Windows8, etc.
|
||||
// title - string, of game
|
||||
// playing - boolean, are they playing the game
|
||||
// presence - string, rich presence string from that title
|
||||
]]
|
||||
local function fetchXboxFriendsAsync()
|
||||
local success, result = pcall(function()
|
||||
if PlatformService then
|
||||
return PlatformService:BeginFetchFriends(Enum.UserInputType.Gamepad1)
|
||||
end
|
||||
end)
|
||||
if success then
|
||||
return HttpService:JSONDecode(result)
|
||||
else
|
||||
print("fetchXboxFriends failed because", result)
|
||||
end
|
||||
end
|
||||
|
||||
local function getOnlineFriends()
|
||||
if UserSettings().GameSettings:InStudioMode() then
|
||||
-- Roblox Friends - leaving this in for testing purposes in studio
|
||||
local result = Http.GetOnlineFriendsAsync()
|
||||
if not result then
|
||||
-- TODO: Error code
|
||||
return nil
|
||||
end
|
||||
--
|
||||
local myOnlineFriends = {}
|
||||
|
||||
for i = 1, #result do
|
||||
local data = result[i]
|
||||
local friend = {
|
||||
Name = Players:GetNameFromUserIdAsync(data["VisitorId"]);
|
||||
UserId = data["VisitorId"];
|
||||
LastLocation = data["LastLocation"];
|
||||
PlaceId = data["PlaceId"];
|
||||
LocationType = data["LocationType"];
|
||||
GameId = data["GameId"];
|
||||
}
|
||||
table.insert(myOnlineFriends, friend)
|
||||
end
|
||||
|
||||
local function sortFunc(a, b)
|
||||
if a.LocationType == b.LocationType then
|
||||
return a.Name:lower() < b.Name:lower()
|
||||
end
|
||||
return a.LocationType > b.LocationType
|
||||
end
|
||||
|
||||
table.sort(myOnlineFriends, sortFunc)
|
||||
|
||||
return myOnlineFriends
|
||||
elseif game:GetService('UserInputService'):GetPlatform() == Enum.Platform.XBoxOne then
|
||||
-- Xbox Friends
|
||||
local myXboxFriends = fetchXboxFriendsAsync()
|
||||
local myOnlineFriends = {}
|
||||
if myXboxFriends then
|
||||
myXboxFriends = myXboxFriends["friends"]
|
||||
myOnlineFriends = filterXboxFriends(myXboxFriends)
|
||||
end
|
||||
|
||||
return myOnlineFriends
|
||||
end
|
||||
end
|
||||
|
||||
--[[ Public API ]]--
|
||||
FriendsData.OnFriendsDataUpdated = Utility.Signal()
|
||||
|
||||
local isFetchingFriends = false
|
||||
function FriendsData.GetOnlineFriendsAsync()
|
||||
-- can only make one call into PlatformService:BeginFetchFriends() at a time
|
||||
while isFetchingFriends do
|
||||
wait()
|
||||
end
|
||||
-- we have current data, this will be updated when polling
|
||||
if myCurrentFriendsData then
|
||||
return myCurrentFriendsData
|
||||
end
|
||||
isFetchingFriends = true
|
||||
|
||||
myCurrentFriendsData = getOnlineFriends()
|
||||
-- spawn polling on first request
|
||||
if not isOnlineFriendsPolling then
|
||||
FriendsData.BeginPolling()
|
||||
end
|
||||
|
||||
isFetchingFriends = false
|
||||
|
||||
return myCurrentFriendsData
|
||||
end
|
||||
|
||||
function FriendsData.BeginPolling()
|
||||
if not isOnlineFriendsPolling then
|
||||
isOnlineFriendsPolling = true
|
||||
local requesterId = UserData:GetRbxUserId()
|
||||
spawn(function()
|
||||
wait(POLL_DELAY)
|
||||
while requesterId == UserData:GetRbxUserId() do
|
||||
myCurrentFriendsData = getOnlineFriends()
|
||||
FriendsData.OnFriendsDataUpdated:fire(myCurrentFriendsData)
|
||||
wait(POLL_DELAY)
|
||||
end
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
||||
-- we make connections through this function so we can clean them all up upon
|
||||
-- clearing the friends data
|
||||
function FriendsData.ConnectUpdateEvent(cbFunc)
|
||||
local cn = FriendsData.OnFriendsDataUpdated:connect(cbFunc)
|
||||
table.insert(updateEventCns, cn)
|
||||
end
|
||||
|
||||
function FriendsData.Reset()
|
||||
isOnlineFriendsPolling = false
|
||||
myCurrentFriendsData = nil
|
||||
for index,cn in pairs(updateEventCns) do
|
||||
cn = Utility.DisconnectEvent(cn)
|
||||
updateEventCns[index] = nil
|
||||
end
|
||||
print('FriendsData: Cleared last users FriendsData')
|
||||
end
|
||||
|
||||
return FriendsData
|
||||
Reference in New Issue
Block a user