Feedback on alternate account detection script

I made a relatively easy to use system to catch alternate accounts. It’s easy to expand on and you can change values based on your needs.

It uses a table with a couple of functions, each of which returns true or false. If it returns true, the heat associated with that function (stored in the key) is added to totalHeat, which is then checked after all functions run.

Some of these functions have negative heat values, which means that they remove from the total heat if they return true. This is especially important because it removes the amount of false cases that occur by just checking account age.

In my opinion, it’s safer and better than using just the player’s account age to determine if they are an alt. This poses a couple problems:

  1. It isn’t friendly with people with new accounts that aren’t alternate accounts (new roblox players)
  2. Most people who are serious about using alts have alts that are way older than a month, which is the time that people typically use to determine if a player is an alt.

I want to expand this so it also saves people flagged, and then checks mutual friend groups between all people it flags. I can also add other things like checking their currency (I’m pretty sure we don’t have permissions to use this API, but I’m not sure.),
seeing if any of these people were banned for exploiting, and seeing if any group of these flagged accounts joined at the same time as one another.


Before I do this, though, I want to see if a system like this is practical, or if I should worry this much about alternate accounts at all, which is why I’m posting this here.

local Players = game:GetService("Players")
local HttpService = game:GetService("HttpService")
local DataStore = game:GetService("DataStoreService"):GetDataStore("Test")

local checks = { -- key: heat, value: function which takes player as an argument
	[-5] = function(player)
		local url = ("https://devforum.rprxy.xyz/u/%s.json/"):format(player.Name)
		
		local success, result = pcall(function()
			return HttpService:JSONDecode(HttpService:GetAsync(url)).user.trust_level
		end)
		
		return success and tonumber(result) >= 1 or false
	end,
	
	[-2] = function(player)
		return player.MembershipType == Enum.MembershipType.Premium
	end,

	[2] = function(player)
		local url = ("https://friends.rprxy.xyz/v1/users/%s/followers/count")
			:format(tostring(player.UserId))
		
		local success, result = pcall(function()
			return HttpService:JSONDecode(HttpService:GetAsync(url)).count
		end)
		
		return success and result <= 1 or false
	end,

	[3] = function(player)
		local url = ("https://badges.rprxy.xyz/v1/users/%s/badges")
			:format(tostring(player.UserId))
		
		local success, result = pcall(function()
			return #HttpService:JSONDecode(HttpService:GetAsync(url))
		end)

		-- broken atm
        return false
	end,

	[4] = function(player)
		return player.AccountAge < 32
	end,
	
	[5] = function(player)
		local url = ("https://friends.rprxy.xyz/v1/users/%s/friends/count")
			:format(tostring(player.UserId))
		
		local success, result = pcall(function()
			return HttpService:JSONDecode(HttpService:GetAsync(url)).count
		end)
		
		return success and result <= 1 or false
	end
}

local function checkPlayer(player)
	local success, result = xpcall(function()
		local data = DataStore:GetAsync(player.UserId)
		-- not checked if no entry
		return data.previouslyChecked or false
		
	end, function(err)
		warn("Unable to get data \n", err)
	end)
	
	 -- use true to skip it since datastore is down
	return result or true
end

Players.PlayerAdded:Connect(function(player)
	-- has been checked before
	if checkPlayer(player) then return end
	
	local totalHeat = 0
	for heat, func in pairs(checks) do
		-- if it returns true, add the heat
		totalHeat = func(player) and totalHeat + heat or totalHeat
	end
	
	if totalHeat >= maxHeat  then
		-- player is probably an alt, maybe save them in a datastore
        -- or report them to a discord channel using a webhook?
	end
end)
--// thanks for stopping by

Note: all these values are temporary.

17 Likes

This seems really cool, I might use it for my game. Can you give a more in-depth explanation of how this works, though?

This looks good in my opinion. You could also check if a player is an alt if they are dressed exactly like a default character but it’s probably just an optional idea.

1 Like

I’m pretty sure this is against TOS so I’m not continuing on this.

also @ArtFoundation I was thinking of that but it probably won’t be that effective since many people change how they look on alts, and many people that aren’t alts keep the default look.

This is against TOS? Where does it say that for my curiosity?

Not sure if it directly states it, but I think it counts as discrimination though.

1 Like