sourcebans-pp icon indicating copy to clipboard operation
sourcebans-pp copied to clipboard

Replace the Steam2 ID format with Steam Account ID

Open Groruk opened this issue 5 years ago • 6 comments

Is your feature request related to a problem? Please describe.

SteamID formats are all over the place, some games use Steam3, others use Steam2 and the Steam WebAPIs commonly use the Steam64 format. Handling the different formats can be quite tricky and has caused some Problems in the past (e,g see #568).

Describe the solution you'd like

To combat this it would be a good idea to only save the Steam Account ID aka the truly unique part in Steam's ID System and use that to create the needed ID format. A small change to make working with SourceBans++ just a bit more easy.

Additional context

All 3 SteamID formats are present in SourceBans++ (Steam2 / Steam3 mostly when it comes to interactions with a gameserver and Steam64 in the event we need to call a Steam WebAPI)

Groruk avatar Sep 24 '19 09:09 Groruk

Good idea. I have long wanted to offer it.

TheByKotik avatar Sep 24 '19 09:09 TheByKotik

Along with this, we could add a function to accept all other types and unify them to one type (account ID), similar to what SM does.

/*
 * Converts Steam2 id, Steam3 id, or SteamId64 to unified, legacy
 * admin identity format. (account id part of Steam2 format)
 */
bool AdminCache::GetUnifiedSteamIdentity(const char *ident, char *out, size_t maxlen)
{
	int len = strlen(ident);
	if (!strcmp(ident, "BOT"))
	{
		// Bots
		strncopy(out, ident, maxlen);
		return true;
	}
	else if (len >= 11 && !strncmp(ident, "STEAM_", 6) && ident[8] != '_')
	{
		// non-bot/lan Steam2 Id, strip off the STEAM_* part
		ke::SafeStrcpy(out, maxlen, &ident[8]);
		return true;
	}
	else if (len >= 7 && !strncmp(ident, "[U:", 3) && ident[len-1] == ']')
	{
		// Steam3 Id, replicate the Steam2 Post-"STEAM_" part
		uint32_t accountId = strtoul(&ident[5], nullptr, 10);
		ke::SafeSprintf(out, maxlen, "%u:%u", accountId & 1, accountId >> 1);
		return true;
	}
	else
	{
		// 64-bit CSteamID, replicate the Steam2 Post-"STEAM_" part

		// some constants from steamclientpublic.h
		static const uint32_t k_EAccountTypeIndividual = 1;
		static const int k_EUniverseInvalid = 0;
		static const int k_EUniverseMax = 5;
		static const unsigned int k_unSteamUserWebInstance	= 4;
		
		uint64_t steamId = strtoull(ident, nullptr, 10);
		if (steamId > 0)
		{
			// Make some attempt at being sure it's a valid id rather than other number,
			// even though we're only going to use the lower 32 bits.
			uint32_t accountId = steamId & 0xFFFFFFFF;
			uint32_t accountType = (steamId >> 52) & 0xF;
			int universe = steamId >> 56;
			uint32_t accountInstance = (steamId >> 32) & 0xFFFFF;
			if (accountId > 0
				&& universe > k_EUniverseInvalid && universe < k_EUniverseMax
				&& accountType == k_EAccountTypeIndividual && accountInstance <= k_unSteamUserWebInstance
				)
			{
				ke::SafeSprintf(out, maxlen, "%u:%u", accountId & 1, accountId >> 1);
				return true;
			}
		}
	}
	
	return false;
}

rumblefrog avatar Sep 24 '19 20:09 rumblefrog

The already bundled Steam ID library at https://github.com/sbpp/sourcebans-pp/tree/v1.x/web/includes/SteamID has conversion functions that should be useful.

geominorai avatar Sep 24 '19 21:09 geominorai

Check out this PHP library as well to work with SteamIDs: https://github.com/xPaw/SteamID.php

borzaka avatar Oct 07 '19 20:10 borzaka

SB++ already has own implementation.

CrazyHackGUT avatar Oct 07 '19 21:10 CrazyHackGUT

iirc, I think we are looking to move to xPaw's library.

rumblefrog avatar Oct 07 '19 22:10 rumblefrog