Open Groruk opened 5 years ago
Good idea. I have long wanted to offer it.
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;
}
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.
Check out this PHP library as well to work with SteamIDs: https://github.com/xPaw/SteamID.php
SB++ already has own implementation.
iirc, I think we are looking to move to xPaw's library.
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)