sbpp / sourcebans-pp

Admin, ban, and comms management system for the Source engine
https://sbpp.github.io/
Creative Commons Attribution Share Alike 4.0 International
338 stars 173 forks source link

Replace the Steam2 ID format with Steam Account ID #604

Open Groruk opened 5 years ago

Groruk commented 5 years ago

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)

TheByKotik commented 5 years ago

Good idea. I have long wanted to offer it.

rumblefrog commented 5 years ago

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;
}
geominorai commented 5 years ago

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.

borzaka commented 5 years ago

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

CrazyHackGUT commented 5 years ago

SB++ already has own implementation.

rumblefrog commented 5 years ago

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