Steam 接入工具类

之前有项目接入steam平台,这儿整理了常用到的WebApi封装,可以参考

usage

     $steam = new SteamUtils([
     'appid' => $this->currentConfig['appid'],
     'appkey' => $this->currentConfig['appkey'],
     'steamid' => $this->steamid,
     'ticket' => $this->params['encrypted_loginkey'] ? :Cache::redis_get('_STEAM_LOGIN_'.$this->steamid),
     ]);
     $ret = $steam->ISteamUserAuth->AuthenticateUserTicket();
     if ( 0!==strcasecmp($ret['response']['params']['result'], 'OK') ){
         // TODO u business
     }
/**
 * SteamUtils
 * present by YCZ
 * Author: Nomandia
 * Date: 2020/6/19 13:53
 * @see https://partner.steamgames.com/doc/features/microtransactions/implementation#error_codes 错误代码
 *
 * @property SteamUtils_IBroadcastService IBroadcastService
 * @property SteamUtils_IGameInventory IGameInventory
 * @property SteamUtils_ISteam ISteam
 * @property SteamUtils_ISteamApps ISteamApps
 * @property SteamUtils_ISteamCommunity ISteamCommunity
 * @property SteamUtils_ISteamEconomy ISteamEconomy
 * @property SteamUtils_ISteamGameServerStats ISteamGameServerStats
 * @property SteamUtils_ISteamMicroTxn ISteamMicroTxn
 * @property SteamUtils_ISteamNews ISteamNews
 * @property SteamUtils_ISteamUser ISteamUser
 * @property SteamUtils_ISteamUserAuth ISteamUserAuth
 * @property SteamUtils_ISteamUserStats ISteamUserStats
 * @property SteamUtils_ISteamWebAPIUtil ISteamWebAPIUtil
 *
 * @usage
 *     $steam = new SteamUtils([
 *        'appid' => $this->currentConfig['appid'],
 *        'appkey' => $this->currentConfig['appkey'],
 *        'steamid' => $this->steamid,
 *        'ticket' => $this->params['encrypted_loginkey'] ? :Cache::redis_get('_STEAM_LOGIN_'.$this->steamid),
 *     ]);
 *     $ret = $steam->ISteamUserAuth->AuthenticateUserTicket();
 *     if ( 0!==strcasecmp($ret['response']['params']['result'], 'OK') ){
 *         // TODO u business
 *     }
 */
class SteamUtils
{
    /**
     * @var string appid
     */
    public $appid;

    /**
     * @var string appkey
     */
    public $appkey;

    /**
     * @var string ticket
     */
    public $ticket;

    /**
     * @var string gameid
     */
    public $gameid;

    /**
     * @var string steamid
     */
    public $steamid;

    /**
     * @var bool use_ssl 开启SSL(https)
     */
    public $use_ssl = false;

    /**
     * @var bool return_json 返回JSON数据,否则返回文本
     */
    public $return_json = true;

    /**
     * @var string language 语言代码
     * @see https://baike.baidu.com/item/ISO%20639-1/8292914?fr=aladdin
     */
    public $language = 'zh';

    /**
     * @var string currency Steam支持的币种(默认软妹币,单位分即100的整数倍)
     * @see https://partner.steamgames.com/doc/store/pricing/currencies
     */
    public $currency = 'CNY';

    /**
     * @var bool sandbox 是否开启沙箱(MicroTxn用到,仅改变URL)
     */
    public $sandbox = false;

    /**
     * Author: Great Nomandia
     * Created At 2020/6/19 14:36
     */
    function __construct()
    {
        if (is_array($func = func_get_arg(0))) {
            $this->appid = $func['appid'];
            $this->appkey = $func['appkey'];
            $this->steamid = $func['steamid'];
            $this->ticket = $func['ticket'];
        } else if (func_num_args() > 3) {
            $this->appid = func_get_arg(0);
            $this->appkey = func_get_arg(1);
            $this->steamid = func_get_arg(2);
            $this->ticket = func_get_arg(3);
        }
    }

    function __destruct()
    {
        static::$implements = null;
        $this->appid = $this->appkey = $this->steamid = $this->ticket = null;
    }

    /*********** ALIAS *************/

    protected static $implements = [];

    /**
     * @param string $name
     * @return mixed
     * @throws SteamException
     * Author: Great Nomandia
     * Created At 2020/6/19 15:16
     */
    function __get($name)
    {
        if (in_array($name, static::$implements)) {
            return static::$implements[$name];
        }
        $clazz = 'SteamUtils_' . $name; // 增加一个前缀
        if (class_exists($clazz) || !($clazz instanceof SteamUtils_ISteam)) {
            /** @var SteamUtils_ISteam $implements */
            static::$implements[$name] = new $clazz();
            return static::$implements[$name]->bind($this);
        }
        throw new SteamException('Interface[' . $name . '] not exists', 502);
    }

    /*********** CURL TOOLS *************/

    /**
     * @param string $url
     * @param mixed $params
     * @param bool $json
     * @param string $cookie
     * @param bool $use_ssl
     * @return string
     * Author: Great Nomandia
     * Created At 2020/6/19 14:06
     */
    static function get($url, $params = null, $json = true, $cookie = '', $use_ssl = false)
    {
        return $json ?
            static::requestJson($url, $params, 'GET', $cookie, $use_ssl) :
            static::request($url, $params, 'GET', $cookie, $use_ssl);
    }

    /**
     * @param string $url
     * @param mixed $params
     * @param bool $json
     * @param string $cookie
     * @param bool $use_ssl
     * @return string
     * Author: Great Nomandia
     * Created At 2020/6/19 14:06
     */
    static function post($url, $params = null, $json = true, $cookie = '', $use_ssl = false)
    {
        return $json ?
            static::requestJson($url, $params, 'POST', $cookie, $use_ssl) :
            static::request($url, $params, 'POST', $cookie, $use_ssl);
    }

    /**
     * @var int _curl_port 默认请求端口
     */
    static $_curl_port = 0;

    /**
     * @var array _curl_headers 附加的Header数据
     */
    static $_curl_headers = [];

    /**
     * @var int _curl_connect_timeout  连接超时时间
     */
    static $_curl_connect_timeout = 2;

    /**
     * @var int _curl_timeout 执行超时时间
     */
    static $_curl_timeout = 5;

    /**
     * @var mixed fetch_result
     */
    static $fetch_result;

    /**
     * @var mixed fetch_error
     */
    static $fetch_error;

    /**
     * @param string $url
     * @param mixed $params
     * @param string $method
     * @param string $cookie
     * @param bool $use_ssl
     * @return mixed
     * Author: Great Nomandia
     * Created At 2020/6/19 14:47
     */
    static function requestJson($url, $params = null, $method = 'GET', $cookie = '', $use_ssl = false)
    {
        $ret = static::request($url, $params, $method, $cookie, $use_ssl);
        return json_decode($ret, 1);
    }

    /**
     * @param string $url
     * @param mixed $params
     * @param string $method
     * @param string $cookie
     * @param bool $use_ssl
     * @return string
     * Author: Great Nomandia
     * Created At 2020/6/19 14:06
     */
    static function request($url, $params = null, $method = 'GET', $cookie = '', $use_ssl = false)
    {
        $ch = curl_init();
        if ('GET' == strtoupper($method)) {
            $param_str = '';
//            默认范文为ipv4
            curl_setopt($ch, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);

            if (is_array($params)) {
                $param_str = http_build_query($params);
            } else if (is_string($params) && strlen($params) > 0) {
                $param_str = $params;
            }
            $url .= $param_str ? '?' . trim($param_str) : '';
            curl_setopt($ch, CURLOPT_URL, $url);
        } else {
            curl_setopt_array($ch, array(
                CURLOPT_URL => $url,
                CURLOPT_POST => 1,
                CURLOPT_POSTFIELDS => $params,
            ));
        }

        curl_setopt_array($ch, array(
            CURLOPT_HEADER => false,
            CURLOPT_RETURNTRANSFER => true, // 成功时返回取到的结果(如HTML或json)
            CURLOPT_CONNECTTIMEOUT => self::$_curl_connect_timeout,
            CURLOPT_TIMEOUT => self::$_curl_timeout,
            CURLOPT_HTTPHEADER => array(
                'Expect:',
            ),
            CURLOPT_SSL_VERIFYPEER => false,
            CURLOPT_SSL_VERIFYHOST => false,
        ));

        if (!empty(self::$_curl_headers)) {
            curl_setopt_array($ch, array(
                CURLOPT_HTTPHEADER => self::$_curl_headers,
            ));
        }

        // disable 100-continue
        if (!empty($cookie)) {
            if (is_array($cookie)) {
                $cs = [];
                foreach ($cookie as $k => $v) {
                    $cs[] = $k . '=' . $v;
                }
                $cookie = join('; ', $cs);
            }
            curl_setopt($ch, CURLOPT_COOKIE, $cookie);
        }
        // 关闭SSL设置,通常这样就可以直接访问HTTPS地址了
        if (!$use_ssl) {
            curl_setopt_array($ch, array(
                CURLOPT_SSL_VERIFYPEER => false,
                CURLOPT_SSL_VERIFYHOST => false,
            ));
        }
        if (self::$_curl_port) {
            curl_setopt($ch, CURLOPT_PORT, intval(self::$_curl_port));
        }
        self::$fetch_result = curl_exec($ch);
        self::$fetch_error = curl_error($ch);
        curl_close($ch);

        // 需要恢复的配置
        self::$_curl_port = 0;

        return self::$fetch_result ?: self::$fetch_error;
    }
}

/*********** EXCEPTION *************/
class SteamException extends Exception
{
}

/*********** SUPPORT INTERFACE *************/
abstract class SteamUtils_ISteam
{
    /**
     * @var SteamUtils steam
     */
    protected static $steam;

    function bind(&$steam)
    {
        static::$steam = $steam;
        return $this;
    }

    /**
     * @param string $url
     * @param array $params
     * @param bool $no_merge 不增加默认参数表
     * @return string|array|mixed
     * Author: Great Nomandia
     * Created At 2020/6/19 15:42
     */
    function post($url, $params = [], $no_merge = false)
    {
        return (static::$steam)::post($url, $no_merge ? $params : array_merge([
            'key' => static::$steam->appkey,
            'appid' => static::$steam->appid,
            'steamid' => static::$steam->steamid,
        ], array_filter($params)), static::$steam->return_json);
    }

    /**
     * @param string $url
     * @param array $params
     * @param bool $no_merge
     * @return string|array|mixed
     * Author: Great Nomandia
     * Created At 2020/6/19 17:11
     */
    function get($url, $params = [], $no_merge = false)
    {
        return (static::$steam)::get($url, $no_merge ? $params : array_merge([
            'key' => static::$steam->appkey,
            'appid' => static::$steam->appid,
            'steamid' => static::$steam->steamid,
        ], array_filter($params)), static::$steam->return_json);
    }

    /**
     * @param string $time
     * @return false|string
     * Author: Great Nomandia
     * Created At 2020/6/19 15:49
     */
    static function rfc3339($time)
    {
        return date('Y-m-d\TH:i:s\Z', strtotime($time));
    }
}

/*********** SUPPORT IMPLEMENTS *************/

/**
 * YCZ - Class IBroadcastService - 提供对 Steam 直播的访问
 * @see https://partner.steamgames.com/doc/webapi/IBroadcastService
 * Author: Great Nomandia
 * Created At 2020/6/19 14:42
 */
class SteamUtils_IBroadcastService extends SteamUtils_ISteam
{
    /**
     * @var string
     */
    CONST URL_BROADCAST_SERVER = 'https://partner.steam-api.com/IBroadcastService/PostGameDataFrame/v1/';

    /**
     * @param mixed $broadcast_id
     * @param mixed $data
     * Author: Great Nomandia
     * Created At 2020/6/19 14:43
     * @return string|array|mixed
     */
    function PostGameDataFrame($broadcast_id, $data)
    {
        return $this->post(static::URL_BROADCAST_SERVER, [
            'broadcast_id' => $broadcast_id,
            'frame_data' => $data
        ]);
    }
}

/**
 * YCZ - Class SteamUtils_IGameInventory 这是与 Steam 经济体交互的主接口
 * @see https://partner.steamgames.com/doc/webapi/IGameInventory
 * Author: Great Nomandia
 * Created At 2020/6/22 10:13
 */
class SteamUtils_IGameInventory extends SteamUtils_ISteam
{
    CONST URL_GAME_INVENTORY_GET_HISTORY_COMMAND_DETAILS = 'https://partner.steam-api.com/IGameInventory/GetHistoryCommandDetails/v1/';

    /**
     * @param string $command 在该资产上运行的命令
     * @param int $contextid 要获取历史记录的上下文
     * @param string $arguments 一开始与命令一起提供的参数
     * @return array|mixed|string
     * @see https://partner.steamgames.com/doc/webapi/IGameInventory#GetHistoryCommandDetails
     * Author: Great Nomandia
     * Created At 2020/6/22 10:13
     */
    function GetHistoryCommandDetails($command, $contextid, $arguments)
    {
        return $this->get(self::URL_GAME_INVENTORY_GET_HISTORY_COMMAND_DETAILS, [
            'command' => $command,
            'contextid' => $contextid,
            'arguments' => $arguments,
        ]);
    }

    CONST URL_GAME_INVENTORY_GET_USER_HISTORY = 'https://partner.steam-api.com/IGameInventory/GetUserHistory/v1/';

    /**
     * @param int $contextid 要获取历史记录的上下文
     * @param int $starttime 要获取的历史记录的开始时间
     * @param int $endtime 要获取的历史记录的结束时间
     * @return array|mixed|string
     * @see https://partner.steamgames.com/doc/webapi/IGameInventory#GetUserHistory
     * Author: Great Nomandia
     * Created At 2020/6/22 10:15
     */
    function GetUserHistory($contextid, $starttime = null, $endtime = null)
    {
        return $this->get(self::URL_GAME_INVENTORY_GET_USER_HISTORY, [
            'contextid' => $contextid,
            'starttime' => $starttime ?: mktime(0, 0, 0),
            'endtime' => $endtime ?: $_SERVER['REQUEST_TIME'],
        ]);
    }

    CONST URL_GAME_INVENTORY_HISTORY_EXECUTE_COMMANDS = 'https://partner.steam-api.com/IGameInventory/HistoryExecuteCommands/v1/';

    /**
     * @param int $contextid 要获取历史记录的上下文
     * @param int $actorid 供客服人员执行命令的唯一 32 位 ID
     * @return array|mixed|string
     * @see https://partner.steamgames.com/doc/webapi/IGameInventory#HistoryExecuteCommands
     * Author: Great Nomandia
     * Created At 2020/6/22 10:17
     */
    function HistoryExecuteCommands($contextid, $actorid)
    {
        return $this->get(self::URL_GAME_INVENTORY_GET_HISTORY_COMMAND_DETAILS, [
            'contextid' => $contextid,
            'actorid' => $actorid,
        ]);
    }

    CONST URL_GAME_INVENTORY_SUPPORT_GET_ASSET_HISTORY = 'https://partner.steam-api.com/IGameInventory/SupportGetAssetHistory/v1/';

    /**
     * @param int $assetid 要操作的资产 ID
     * @param int $contextid 要获取历史记录的上下文
     * @return array|mixed|string
     * @https://partner.steamgames.com/doc/webapi/IGameInventory#SupportGetAssetHistory
     * Author: Great Nomandia
     * Created At 2020/6/22 10:20
     */
    function SupportGetAssetHistory($assetid, $contextid)
    {
        return $this->get(self::URL_GAME_INVENTORY_SUPPORT_GET_ASSET_HISTORY, [
            'key' => static::$steam->appkey,
            'appid' => static::$steam->appid,
            'assetid' => $assetid,
            'contextid' => $contextid,
        ], true);
    }

    CONST URL_GAME_INVENTORY_UPDATE_ITEM_DEFS = 'https://partner.steam-api.com/IGameInventory/UpdateItemDefs/v0001';

    /**
     * @param string $itemdefs 待更新或创建的一个或多个物品定义,以 JSON 数组显示
     * @return array|mixed|string
     * @see https://partner.steamgames.com/doc/webapi/IGameInventory#UpdateItemDefs
     * Author: Great Nomandia
     * Created At 2020/6/22 10:21
     */
    function UpdateItemDefs($itemdefs)
    {
        /**
         * 请求值
         * curl --request POST \
         * --header "Content-Type: application/x-www-form-urlencoded" \
         * --form appid=30400 \
         * --form 'itemdefs=[{"appid":"30400","itemdefid":"418","type":"item","display_type":"bag","name":"Bag of Stuff","description":"This bag contains stuff.","background_color":"993300","tradable": true,"marketable": true,"commodity": true,"tags":"class:human;type:bag"}, {"appid": "30400","itemdefid":"403","type":"item","display_type":"cat","name":"Cat of Bags","description":"This cat contains multitudes."}]'
         * "https://api.steampowered.com/IGameInventory/UpdateItemDefs/v0001?key=xxxxxx"
         */
        /**
         * 返回值
         * {
         * "result": {
         * "updated": [
         * "418",
         * "403"
         * ],
         * "failed": [],
         * "success": true
         * }
         * }
         */
        return $this->get(self::URL_GAME_INVENTORY_UPDATE_ITEM_DEFS, [
            'key' => static::$steam->appkey,
            'appid' => static::$steam->appid,
            'itemdefs' => $itemdefs,
        ], true);
    }
}

/**
 * YCZ - Class SteamUtils_ISteamApps - 用于访问 Steam 上的应用程序的数据
 * Author: Great Nomandia
 * Created At 2020/6/19 18:16
 */
class SteamUtils_ISteamApps extends SteamUtils_ISteam
{
    CONST URL_GET_APP_BETAS = 'https://partner.steam-api.com/ISteamApps/GetAppBetas/v1/';

    /**
     * 为指定应用程序获取所有测试版分支
     * @see https://partner.steamgames.com/doc/webapi/ISteamApps#GetAppBetas
     * @return array|mixed|string
     * Author: Great Nomandia
     * Created At 2020/6/19 18:18
     */
    function GetAppBetas()
    {
        return $this->get(static::URL_GET_APP_BETAS, [
            'key' => static::$steam->appkey,
            'appid' => static::$steam->appid,
        ]);
    }

    CONST URL_GET_APP_BUILDS = 'https://partner.steam-api.com/ISteamApps/GetAppBuilds/v1/';

    /**
     * 获取应用程序的生成版本历史。
     * @see https://partner.steamgames.com/doc/webapi/ISteamApps#GetAppBuilds
     * @param int $count 要获取的生成版本数量,默认为 10。
     * @return array|mixed|string
     * Author: Great Nomandia
     * Created At 2020/6/19 18:25
     */
    function GetAppBuilds($count = 10)
    {
        return $this->get(static::URL_GET_APP_BUILDS, [
            'key' => static::$steam->appkey,
            'appid' => static::$steam->appid,
            'count' => $count,
        ]);
    }

    CONST URL_GET_APP_DEPOT_VERSIONS = 'https://partner.steam-api.com/ISteamApps/GetAppDepotVersions/v1/';

    /**
     * 为指定应用程序获取所有 depot 的所有版本
     * @see https://partner.steamgames.com/doc/webapi/ISteamApps#GetAppDepotVersions
     * @return array|mixed|string
     * Author: Great Nomandia
     * Created At 2020/6/19 18:26
     */
    function GetAppDepotVersions()
    {
        return $this->get(static::URL_GET_APP_DEPOT_VERSIONS);
    }

    CONST URL_GET_APP_LIST = 'https://api.steampowered.com/ISteamApps/GetAppList/v2/';

    /**
     * 获取公开应用的完整列表
     * @see https://partner.steamgames.com/doc/webapi/ISteamApps#GetAppList
     * @return array|mixed|string
     * Author: Great Nomandia
     * Created At 2020/6/19 18:27
     */
    function GetAppList()
    {
        /**
         * applist
         * apps - 包含应用程序的列表。
         * appid - uint32 - 此应用程序的 App ID。
         * name - string - 此应用程序的名称
         */
        return $this->get(static::URL_GET_APP_DEPOT_VERSIONS, null, true);
    }

    CONST URL_GET_CHEATING_REPORTS = 'https://partner.steam-api.com/ISteamApps/GetCheatingReports/v1/';

    /**
     * 获取就此应用提交的作弊举报的列表
     * @see https://partner.steamgames.com/doc/webapi/ISteamApps#GetCheatingReports
     * @param int $timebegin 时间范围开始
     * @param int $timeend 时间范围结束
     * @param bool $includereports 包括不是封禁的举报
     * @param bool $includebans 包括是封禁的举报
     * @param null $reportidmin 最少的举报 ID
     * @return array|mixed|string
     * Author: Great Nomandia
     * Created At 2020/6/19 18:30
     */
    function GetCheatingReports($timebegin, $timeend, $includereports = true, $includebans = true, $reportidmin = null)
    {
        return $this->get(static::URL_GET_CHEATING_REPORTS, [
            'key' => static::$steam->appkey,
            'appid' => static::$steam->appid,
            'timebegin' => $timebegin,
            'timeend' => $timeend,
            'includereports' => $includereports,
            'includebans' => $includebans,
            'reportidmin' => $reportidmin,
        ], true);
    }

    CONST URL_GET_PARTNER_APP_LIST_FOR_WEB_API_KEY = 'https://partner.steam-api.com/ISteamApps/GetPartnerAppListForWebAPIKey/v1/';

    /**
     * Get a list of appIDs associated with a WebAPI key. Type_filter can used to specify certain app types to be returned. Possible values are "game,application,tool,demo,dlc,music". When type_filter is blank or not used, all apps are returned.
     * @see https://partner.steamgames.com/doc/webapi/ISteamApps#GetPartnerAppListForWebAPIKey
     * @param string $type_filter Optional comma separated list of types to filter on
     * @return array|mixed|string
     * Author: Great Nomandia
     * Created At 2020/6/19 18:34
     */
    function GetPartnerAppListForWebAPIKey($type_filter)
    {
        /**
         * {"applist":{"apps":{"app":[{
         * "appid": 500,
         * "app_type": "game"
         * },
         * {
         * "appid": 222840,
         * "app_type": "tool"
         * },
         * {
         * "appid": 222860,
         * "app_type": "tool"
         * }    ]}}}
         */
        return $this->get(static::URL_GET_PARTNER_APP_LIST_FOR_WEB_API_KEY, [
            'key' => static::$steam->appkey,
            'type_filter' => $type_filter,
        ], true);
    }

    CONST URL_GET_PLAYERS_BANNED = 'https://partner.steam-api.com/ISteamApps/GetPlayersBanned/v1/';

    /**
     * 获取本封禁的玩家id
     * @see https://partner.steamgames.com/doc/webapi/ISteamApps#GetPlayersBanned
     * @return array|mixed|string
     * Author: Great Nomandia
     * Created At 2020/6/19 18:36
     */
    function GetPlayersBanned()
    {
        return $this->get(static::URL_GET_PLAYERS_BANNED, [
            'key' => static::$steam->appkey,
            'appid' => static::$steam->appid,
        ]);
    }

    CONST URL_GET_SERVER_LIST = 'https://partner.steam-api.com/ISteamApps/GetServerList/v1/';

    /**
     * 获取服务器列表
     * @see https://partner.steamgames.com/doc/webapi/ISteamApps#GetServerList
     * @param string $filter
     * @param int $limit
     * @return array|mixed|string
     * Author: Great Nomandia
     * Created At 2020/6/19 18:37
     */
    function GetServerList($filter, $limit = 100)
    {
        return $this->get(static::URL_GET_SERVER_LIST, [
            'key' => static::$steam->appkey,
            'filter' => $filter,
            'limit' => $limit
        ]);
    }

    CONST URL_GET_SERVERS_AT_ADDRESS = 'https://api.steampowered.com/ISteamApps/GetServersAtAddress/v1/';

    /**
     * @see https://partner.steamgames.com/doc/webapi/ISteamApps#GetServersAtAddress
     * @param $addr
     * @return array|mixed|string
     * Author: Great Nomandia
     * Created At 2020/6/19 18:39
     */
    function GetServersAtAddress($addr)
    {
        return $this->get(static::URL_GET_SERVERS_AT_ADDRESS, [
            'addr' => $addr,
        ], true);
    }

    CONST URL_SET_APP_BUILD_LIVE = 'https://partner.steam-api.com/ISteamApps/SetAppBuildLive/v1/';

    /**
     * 设置App版本
     * @see https://partner.steamgames.com/doc/webapi/ISteamApps#SetAppBuildLive
     * @param int $buildid
     * @param string $betakey
     * @param string $description
     * @return array|mixed|string
     * Author: Great Nomandia
     * Created At 2020/6/19 18:41
     */
    function SetAppBuildLive($buildid, $betakey, $description = null)
    {
        return $this->get(static::URL_SET_APP_BUILD_LIVE, [
            'key' => static::$steam->appkey,
            'appid' => static::$steam->appid,
            'buildid' => $buildid,
            'betakey' => $betakey,
            'description' => $description
        ], true);
    }

    CONST URL_UP_TO_DATE_CHECK = 'https://api.steampowered.com/ISteamApps/UpToDateCheck/v1/';

    /**
     * @see https://partner.steamgames.com/doc/webapi/ISteamApps#UpToDateCheck
     * @param int $version
     * @return array|mixed|string
     * Author: Great Nomandia
     * Created At 2020/6/19 18:43
     */
    function UpToDateCheck($version)
    {
        return $this->get(static::URL_SET_APP_BUILD_LIVE, [
            'appid' => static::$steam->appid,
            'version' => $version,
        ], true);
    }
}

/**
 * YCZ - Class SteamUtils_ISteamCommunity - 提供对 Steam 社区功能的访问限制
 * @see https://partner.steamgames.com/doc/webapi/ISteamCommunity
 * Author: Great Nomandia
 * Created At 2020/6/22 9:42
 */
class SteamUtils_ISteamCommunity extends SteamUtils_ISteam
{

    CONST URL_COMMUNITY_REPORT_ABUSE = 'https://partner.steam-api.com/ISteamCommunity/ReportAbuse/v1/';

    /**
     * 允许发行商报告在其社区中心中举止不当的用户
     * @param mixed $steamidActor
     * @param mixed $steamidTarget
     * @param int $abuseType
     * @param int $contentType
     * @param string $description
     * @param int $gid
     * @return array|mixed|string
     * Author: Great Nomandia
     * Created At 2020/6/22 9:46
     */
    function ReportAbuse($steamidActor, $steamidTarget, $abuseType, $contentType, $description, $gid)
    {
        return $this->post(static::URL_COMMUNITY_REPORT_ABUSE, [
            'key' => static::$steam->appkey,
            'steamidActor' => $steamidActor,
            'steamidTarget' => $steamidTarget,
            'appid' => static::$steam->appid,
            'abuseType' => $abuseType,
            'contentType' => $contentType,
            'description' => $description,
            'gid' => $gid,
        ], true);
    }
}

/**
 * YCZ - Class SteamUtils_ISteamEconomy - 与 Steam 经济体交互的次级接口
 * @see https://partner.steamgames.com/doc/webapi/ISteamEconomy
 * @see https://partner.steamgames.com/doc/features/inventory/economy
 * Author: Great Nomandia
 * Created At 2020/6/22 9:47
 */
class SteamUtils_ISteamEconomy extends SteamUtils_ISteam
{

    CONST URL_ECONOMY_CAN_TRADE = 'https://partner.steam-api.com/ISteamEconomy/CanTrade/v1/';

    /**
     * @param mixed $targetid 交易邀请的目标用户的 steamID。
     * @param mixed $steamid 尝试发起交易的用户的 steamID。
     * @return array|mixed|string
     * @see https://partner.steamgames.com/doc/webapi/ISteamEconomy#CanTrade
     * Author: Great Nomandia
     * Created At 2020/6/22 9:50
     */
    function CanTrade($targetid, $steamid = null)
    {
        return $this->get(static::URL_ECONOMY_CAN_TRADE, [
            'targetid' => $targetid,
            'steamid' => $steamid ?: static::$steam->steamid,
        ]);
    }

    CONST URL_ECONOMY_FINALIZE_ASSET_TRANSACTION = 'https://partner.steam-api.com/ISteamEconomy/FinalizeAssetTransaction/v1/';

    /**
     * @param mixed $txnid 交易 ID
     * @param mixed $steamid 购买用户的 SteamID
     * @param mixed $language 用户的本地语言
     * @return array|mixed|string
     * @see https://partner.steamgames.com/doc/webapi/ISteamEconomy#FinalizeAssetTransaction
     * Author: Great Nomandia
     * Created At 2020/6/22 9:53
     */
    function FinalizeAssetTransaction($txnid, $steamid = null, $language = null)
    {
        return $this->post(self::URL_ECONOMY_FINALIZE_ASSET_TRANSACTION, [
            'txnid' => $txnid,
            'steamid' => $steamid ?: static::$steam->steamid,
            'language' => $language ?: static::$steam->language,
        ]);
    }

    CONST URL_ECONOMY_GET_ASSET_CLASS_INFO = 'https://api.steampowered.com/ISteamEconomy/GetAssetClassInfo/v1/';

    /**
     * @param int $class_count 请求的类数量。 必须至少为 1
     * @param int $classid0 nth 类的类 ID
     * @param string $language 用户的本地语言
     * @param int $instanceid0 nth 类的实例 ID
     * @return array|mixed|string
     * @see https://partner.steamgames.com/doc/webapi/ISteamEconomy#GetAssetClassInfo
     * Author: Great Nomandia
     * Created At 2020/6/22 9:56
     */
    function GetAssetClassInfo($class_count, $classid0, $language = null, $instanceid0 = null)
    {
        return $this->get(self::URL_ECONOMY_GET_ASSET_CLASS_INFO, [
            'key' => static::$steam->appkey,
            'appid' => static::$steam->appid,
            'language' => $language ?: static::$steam->language,
            'class_count' => $class_count,
            'classid0' => $classid0,
            'instanceid0' => $instanceid0,
        ], true);
    }

    CONST URL_ECONOMY_GET_ASSET_PRICES = 'https://api.steampowered.com/ISteamEconomy/GetAssetPrices/v1/';

    /**
     * 返回用户能够购买的物品的价格与类型
     * @param string $currency 要筛选的货币
     * @param string $language 用户的本地语言
     * @return array|mixed|string
     * @see https://partner.steamgames.com/doc/webapi/ISteamEconomy#GetAssetPrices
     * Author: Great Nomandia
     * Created At 2020/6/22 9:59
     */
    function GetAssetPrices($currency = null, $language = null)
    {
        return $this->get(self::URL_ECONOMY_GET_ASSET_PRICES, [
            'key' => static::$steam->appkey,
            'appid' => static::$steam->appid,
            'currency' => $currency ?: static::$steam->currency,
            'language' => $language ?: static::$steam->language,
        ]);
    }

    CONST URL_ECONOMY_GET_EXPORTED_ASSETS_FOR_USER = 'https://partner.steam-api.com/ISteamEconomy/GetExportedAssetsForUser/v1/';

    /**
     * 从另一个游戏获取资产清单以导入
     * @param mixed $contextid 要导出物品的上下文
     * @param mixed $steamid 用户的 SteamID
     * @return array|mixed|string
     * @see https://partner.steamgames.com/doc/webapi/ISteamEconomy#GetExportedAssetsForUser
     * Author: Great Nomandia
     * Created At 2020/6/22 10:01
     */
    function GetExportedAssetsForUser($contextid, $steamid = null)
    {
        return $this->get(static::URL_ECONOMY_GET_EXPORTED_ASSETS_FOR_USER, [
            'steamid' => $steamid ?: static::$steam->steamid,
            'contextid' => $contextid
        ]);
    }

    CONST URL_ECONOMY_GET_MARKET_PRICES = 'https://partner.steam-api.com/ISteamEconomy/GetMarketPrices/v1/';

    /**
     * @see https://partner.steamgames.com/doc/webapi/ISteamEconomy#GetMarketPrices
     * Author: Great Nomandia
     * Created At 2020/6/22 10:02
     */
    function GetMarketPrices()
    {
        return $this->get(self::URL_ECONOMY_GET_MARKET_PRICES, [
            'key' => static::$steam->appkey,
            'appid' => static::$steam->appid,
        ], true);
    }

    CONST URL_ECONOMY_START_ASSET_TRANSACTION = 'https://partner.steamgames.com/doc/webapi/ISteamEconomy#StartAssetTransaction';

    /**
     * @param mixed $assetid0 用户购买的第一个资产的 ID。必须有至少一个 ID
     * @param int $assetquantity0 用户购买的 assetid0 的数量
     * @param string $currency 用户的本地货币
     * @param string $language 用户的本地语言
     * @param string $ipaddress 用户的 IP 地址
     * @param string $referrer 引用 URL
     * @param bool $clientauth 若为 true(默认为 false),授权将显示在用户的 Steam 客户端界面上,而非以网页形式显示,因此对那些有产品嵌入的商店有用
     * @return array|mixed|string
     * @see https://partner.steamgames.com/doc/webapi/ISteamEconomy#StartAssetTransaction
     * Author: Great Nomandia
     * Created At 2020/6/22 10:07
     */
    function StartAssetTransaction($assetid0, $assetquantity0, $currency = null, $language = null, $ipaddress = null, $referrer = null, $clientauth = false)
    {
        return $this->post(self::URL_ECONOMY_START_ASSET_TRANSACTION, [
            'assetid0' => $assetid0,
            'assetquantity0' => $assetquantity0,
            'currency' => $currency ?: static::$steam->currency,
            'language' => $language ?: static::$steam->language,
            'ipaddress' => $ipaddress ?: Utils::ip(),
            'referrer' => $referrer ?: $_SERVER['HTTP_REFERER'],
            'clientauth' => $clientauth,
        ]);
    }

    CONST URL_ECONOMY_START_TRADE = 'https://partner.steam-api.com/ISteamEconomy/StartTrade/v1/';

    /**
     * @param string $partya
     * @param string $partyb
     * @return array|mixed|string
     * @see https://partner.steamgames.com/doc/webapi/ISteamEconomy#StartTrade
     * Author: Great Nomandia
     * Created At 2020/6/22 10:09
     */
    function StartTrade($partya, $partyb)
    {
        return $this->get(self::URL_ECONOMY_START_TRADE, [
            'key' => static::$steam->appkey,
            'appid' => static::$steam->appid,
            'partya' => $partya,
            'partyb' => $partyb
        ]);
    }
}

/**
 * YCZ - Class SteamUtils_ISteamGameServerStats 获取游戏服务器统计数据并与之交互的接口
 * @see https://partner.steamgames.com/doc/webapi/ISteamGameServerStats
 * Author: Great Nomandia
 * Created At 2020/6/22 10:24
 */
class SteamUtils_ISteamGameServerStats extends SteamUtils_ISteam
{
    CONST URL_GAME_SERVER_STATS_GET_GAME_SERVER_PLAYER_STATS_FOR_GAME = 'https://partner.steam-api.com/ISteamGameServerStats/GetGameServerPlayerStatsForGame/v1/';

    /**
     * @param int $gameid 要获取统计的 game ID;若非模组,可在此安全使用 AppID
     * @param string $rangestart 范围的起始日期/时间(格式:YYYY-MM-DD HH:MM:SS 西雅图本地时间)
     * @param string $rangeend 范围的结束日期/时间(格式:YYYY-MM-DD HH:MM:SS 西雅图本地时间)
     * @param int $maxresult 返回的结果的最大数量(不超过 1000)
     * @return array|mixed|string
     * Author: Great Nomandia
     * Created At 2020/6/22 10:27
     */
    function GetGameServerPlayerStatsForGame($gameid, $rangestart = null, $rangeend = null, $maxresult = 1000)
    {
        return $this->get(static::URL_GAME_SERVER_STATS_GET_GAME_SERVER_PLAYER_STATS_FOR_GAME, [
            'key' => static::$steam->appkey,
            'gameid' => $gameid ?: static::$steam->appid,
            'appid' => static::$steam->appid,
            'rangestart' => $rangestart ?: date('Y-m-d 00:00:00'),
            'rangeend' => $rangeend ?: date('Y-m-d 23:59:59'),
        ]);
    }
}

/**
 * YCZ - Class SteamUtils_ISteamMicroTxn - 这是用于支持小额交易(游戏内购)的接口
 * 注意: 此调用需要发行商 API 密钥以使用此方法。 因此,此 API 必须通过安全服务器调用,且绝不能由客户端直接调用!
 * @see https://partner.steamgames.com/doc/webapi/ISteamMicroTxn
 * Author: Great Nomandia
 * Created At 2020/6/19 15:21
 */
class SteamUtils_ISteamMicroTxn extends SteamUtils_ISteam
{

    CONST URL_MICRO_TXN_ADJUST_AGREEMENT = 'https://partner.steam-api.com/ISteamMicroTxn/AdjustAgreement/v1/';

    /**
     * 解析URL自动调整Sandbox的请求接口
     * @see https://partner.steamgames.com/doc/webapi/ISteamMicroTxnSandbox
     * @param string $url
     * @return string
     * Author: Great Nomandia
     * Created At 2020/6/19 18:13
     */
    static function parseUrl($url)
    {
        return static::$steam->sandbox ?
            strtr($url, ['ISteamMicroTxn' => 'ISteamMicroTxnSandbox']) : $url;
    }

    /**
     * 向扣款类型为“Steam”的协议的结算时间表添加时间
     * @see https://partner.steamgames.com/doc/webapi/ISteamMicroTxn#AdjustAgreement
     * @param mixed $agreementid Steam 扣款协议的唯一 ID
     * @param string $nextprocessdate 下个循环订阅扣款应开始的日期, 格式为 YYYYMMDD。
     * 日期只能向之后调整,表示您希望为订阅添加时间。 如果日期超出订阅的结束时间,结束时间将延长。
     * @return string|array|mixed
     * Author: Great Nomandia
     * Created At 2020/6/19 15:32
     */
    function AdjustAgreement($agreementid, $nextprocessdate)
    {
        /**
         * 返回值
         * response
         *     result - 操作结果。 (OK 或 Failure)
         *     params
         *         agreementid - 唯一的 64 位 Steam 扣款协议 ID。
         *         nextprocessdate - 下个循环订阅扣款开始的日期, 格式为 YYYYMMDD。
         *     error - 可选。仅在结果为 Failure 时返回。
         *         errorcode - 错误或事件代码。 参见:附录 B :错误代码
         *         errordesc - 错误或事件的消息。
         *
         * @TODO 下文省略了 result 和 error 项目,因为所有接口都会返回
         */
        return $this->post(static::parseUrl(static::URL_MICRO_TXN_ADJUST_AGREEMENT), [
            'agreementid' => $agreementid,
            'nextprocessdate' => $nextprocessdate
        ]);
    }

    CONST URL_MICRO_TXN_CANCEL_AGREEMENT = 'https://partner.steam-api.com/ISteamMicroTxn/CancelAgreement/v1/';

    /**
     * 取消循环扣款协议(订阅)
     * @see https://partner.steamgames.com/doc/webapi/ISteamMicroTxn#CancelAgreement
     * @param string $agreementid 唯一的64位Steam扣款协议ID
     * @return string|array|mixed
     * Author: Great Nomandia
     * Created At 2020/6/19 15:36
     */
    function CancelAgreement($agreementid)
    {
        /**
         * 返回值
         * params
         *     agreementid - 唯一的 64 位 Steam 扣款协议 ID。
         */
        return $this->post(static::parseUrl(static::URL_MICRO_TXN_ADJUST_AGREEMENT), [
            'agreementid' => $agreementid,
        ]);
    }

    CONST URL_MICRO_TXN_FINALIZE_TXN = 'https://partner.steam-api.com/ISteamMicroTxn/FinalizeTxn/v2/';

    /**
     * 完成之前通过 InitTxn API 开始的购买。
     * @see https://partner.steamgames.com/doc/webapi/ISteamMicroTxn#FinalizeTxn
     * @see https://partner.steamgames.com/doc/webapi/ISteamMicroTxn#InitTxn 关于InitTxn
     * @param mixed $orderid 订单的唯一 64 位 ID( version2开始支持字符串)
     * @return string|array|mixed
     * Author: Great Nomandia
     * Created At 2020/6/19 15:39
     */
    function FinalizeTxn($orderid)
    {
        /**
         * 返回值
         * params
         *     orderid - 订单的唯一 64 位 ID。
         *     transid - 唯一的 64 位 Steam 交易 ID。
         */
        return $this->post(static::parseUrl(static::URL_MICRO_TXN_FINALIZE_TXN), [
            'orderid' => $orderid,
        ]);
    }

    CONST URL_MICRO_TXN_GET_REPORT = 'https://partner.steam-api.com/ISteamMicroTxn/GetReport/v4/';

    /**
     * Steam 提供可下载的交易报告,供您进行对账。 这些报告含有各项交易中涉及资金结算入您的账户的详细信息。
     * @see https://partner.steamgames.com/doc/webapi/ISteamMicroTxn#GetReport
     * @param string $datetime 报告的开始时间(Y-m-d H:i:s)。(RFC 3339 UTC 格式,如:2010-01-01T00:00:00Z, 此处由方法处理)
     * @param string $type 报告类型(以下其中之一:“GAMESALES”, “STEAMSTORESALES”, “SETTLEMENT”)
     * @param int $maxresults 报告中返回的结果的最大数量 (Default is 1000 if no value is set)
     * @return array|mixed|string
     * Author: Great Nomandia
     * Created At 2020/6/19 15:45
     */
    function GetReport($datetime, $type = 'GAMESALES', $maxresults = 1000)
    {
        /**
         * 返回值
         *    params
         *        time - Time of transaction (RFC 3339 UTC formatted like: 2010-01-01T00:00:00Z)
         *        orderid - Unique 64-bit ID for order. (This will be 0 for recurring subscriptions initiated from the Steam store, use transid instead.)
         *        transid - Unique 64-bit Steam transaction ID.
         *        steamid - The Steam ID of user that the order/transaction belongs to.
         *        status - Status of the order. See: 附录 A:状态值
         *        currency - ISO 4217 currency code.
         *        time - Time of the transaction. (RFC 3339 UTC formatted like: 2010-01-01T00:00:00Z)
         *        country - ISO 3166-1-alpha-2 country code.
         *        usstate - US State. Empty for non-US countries.
         *    items
         *        itemid - Game ID number of item.
         *        qty - Quantity of this item.
         *        amount - Total cost to user minus VAT (in cents). (199 = 1.99)
         *        vat - Total VAT or tax (in cents). (19 = .19)
         *        itemstatus - Status of items within the order.
         *        storepurchasereference - Optional, only returned if the purchase was via a DLC on the store that is connected to an in-game microtransaction item id.
         *            packageid - The DLC package that was purchased on the store.
         *            referenceid - The transid associated with the order.
         *            amount - The price paid by the user.
         *            vat - VAT taxes if applicable for the purchase.
         *            currency - The currency that was used to make the purchase.
         */
        return $this->post(static::parseUrl(static::URL_MICRO_TXN_GET_REPORT), [
            'time' => static::rfc3339($datetime),
            'type' => $type,
            'maxresults' => (int)$maxresults,
        ]);
    }

    /**
     * 获取销售报告
     * @param string $datetime
     * @param int $maxresults
     * @return array|mixed|string
     * Author: Great Nomandia
     * Created At 2020/6/19 15:57
     */
    function GetReport4GameSales($datetime, $maxresults = 1000)
    {
        return $this->GetReport($datetime, 'GAMESALES', $maxresults);
    }

    /**
     * 获取Steam商店销售报告
     * @param string $datetime
     * @param int $maxresults
     * @return array|mixed|string
     * Author: Great Nomandia
     * Created At 2020/6/19 15:58
     */
    function GetReport4SteamStoreSales($datetime, $maxresults = 1000)
    {
        return $this->GetReport($datetime, 'STEAMSTORESALES', $maxresults);
    }

    /**
     * 获取Steam结算数据
     * @param string $datetime
     * @param int $maxresults
     * @return array|mixed|string
     * Author: Great Nomandia
     * Created At 2020/6/19 15:59
     */
    function GetReport4Settlement($datetime, $maxresults = 1000)
    {
        return $this->GetReport($datetime, 'SETTLEMENT', $maxresults);
    }

    CONST URL_MICRO_TXN_GET_USER_AGREEMENT_INFO = 'https://partner.steam-api.com/ISteamMicroTxn/GetUserAgreementInfo/v1/';

    /**
     * Get detailed information of all recurring billing agreements (subscriptions) for a user.
     * 获取订阅明细
     * @see https://partner.steamgames.com/doc/webapi/ISteamMicroTxn#GetUserAgreementInfo
     * @param mixed $steamid 客户端的 Steam ID(不指定则用值域steamid)
     * @return array|mixed|string
     * Author: Great Nomandia
     * Created At 2020/6/19 16:03
     */
    function GetUserAgreementInfo($steamid = null)
    {
        /**
         * 返回值
         *    params
         *        agreements
         *            agreement
         *                agreementid - Unique 64-bit Steam billing agreement ID.
         *                itemid - Game ID number of item
         *                status - Active or canceled.
         *                period - Period of agreement.
         *                frequency - Interval of period.
         *                startdate - Date that recurring payment processing starts. Format is YYYYMMDD.
         *                enddate - Date that recurring payment processing ends. Format is YYYYMMDD.
         *                recurringamt - Amount to bill (in cents) at each recurring interval.
         *                currency - ISO 4217 currency code of prices.
         *                timecreated - Date that agreement was created in YYYYMMDD format.
         *                lastpayment - Date of last successful payment in YYYYMMDD format.
         *                lastamount - Amount of last successful payment in cents.
         *                nextpayment - Date of next scheduled payment in YYYYMMDD format.
         *                outstanding - Current outstanding balance in cents.
         *                failedattempts - Number of failed billing attempts on outstanding balance.
         */
        return $this->post(static::parseUrl(static::URL_MICRO_TXN_GET_USER_AGREEMENT_INFO), [
            'steamid' => $steamid,
        ]);
    }

    CONST URL_MICRO_TXN_GET_USER_INFO = 'https://partner.steam-api.com/ISteamMicroTxn/GetUserInfo/v2/';

    /**
     * 获取用户付费信息
     * @see https://partner.steamgames.com/doc/webapi/ISteamMicroTxn#GetUserInfo
     * @param mixed $steamid 进行购买的用户的 Steam ID
     * @param mixed $ipaddress 用户的 IP 地址,使用字符串格式 (xxx.xxx.xxx.xxx)。 只在 InitTxn 的 usersession 设为 web 时才需要。
     * @return array|mixed|string
     * Author: Great Nomandia
     * Created At 2020/6/19 16:09
     */
    function GetUserInfo($steamid = null, $ipaddress = null)
    {
        /**
         * 返回值
         * params
         *     state - US State. Empty for non-US countries.
         *     country - ISO 3166-1-alpha-2 country code.
         *     currency - ISO 4217 currency code of prices.
         *     status - Status of the account. Can be either Active or Trusted. Trusted accounts have a have a known, good purchase history within Steam. Use this flag to relax your own fraud checking as appropriate.
         */
        return $this->post(static::parseUrl(static::URL_MICRO_TXN_GET_USER_INFO), [
            'key' => static::$steam->appkey,
            'steamid' => $steamid,
            '$ipaddress' => $ipaddress,
        ], true);
    }

    CONST URL_MICRO_TXN_INIT_TXN = 'https://partner.steam-api.com/ISteamMicroTxn/InitTxn/v3/';

    /**
     * 创建一个Steam订单(此方法仅支持单个商品)
     * @see https://partner.steamgames.com/doc/webapi/ISteamMicroTxn#InitTxn
     * @param array $params
     * @return array|mixed|string
     * Author: Great Nomandia
     * Created At 2020/6/19 16:18
     */
    function InitTxn($params)
    {
        /**
         * 返回值
         * params
         *     orderid - Unique 64-bit ID for order. 自己的订单号
         *     transid - Unique 64-bit Steam transaction ID. 事务Token
         *     steamurl - Optional URL returned when the usersession input is set to web. This URL can be used to redirect the user's web session to Steam so that the user can approve the transaction.
         *                steamurl在web版支付页面时候用,Client下自己拉起Sdk窗即可
         */
        return $this->post(static::parseUrl(static::URL_MICRO_TXN_INIT_TXN), [
            'orderid' => $params['orderid'],    // 订单的 64 位唯一 ID
            'itemcount' => $params['orderid'],  // 购物车中的物品数量
            'itemid[0]' => $params['itemid[0]'], // 物品的第三方 ID
            'qty[0]' => $params['qty[0]'], // 物品的数量, // 物品数量在v3时支持16bit数字, 65535
            'amount[0]' => $params['amount[0]'], // 总价格
            'description[0]' => $params['description[0]'], // 物品的描述

            // 默认配置,可以在SteamUtils方法调用前修改
            'language' => $params['language'] ?: static::$steam->language, // 物品描述的 ISO 639-1 语言代码
            'currency' => $params['currency'] ?: static::$steam->currency,  // ISO 4217 货币代码。 参见支持币种 @see https://partner.steamgames.com/doc/store/pricing/currencies

            // 非必须参数
            'usersession' => $params['usersession'], // 用户将授权交易的会话。 有效选项为“client” 或 “web”。 如果未提供此参数,接口将假设是通过一个当前登录的 Steam 客户端会话进行。
            'ipaddress' => $params['ipaddress'], // 用户的 IP 地址,使用字符串格式 (xxx.xxx.xxx.xxx)。 只有在 [param]usersession[/param] 设为 web 时需要
            'category[0]' => $params['category[0]'], // 可选参数。物品的类别
            'associated_bundle[0]' => $params['associated_bundle[0]'], // 可选参数。相关联的捆绑包的 bundleid
            'billingtype[0]' => $params['billingtype[0]'], // 可选参数。循环扣款类型
            'startdate[0]' => $params['startdate[0]'], // 可选参数。循环扣款的开始日期
            'enddate[0]' => $params['enddate[0]'], //可选参数。循环扣款的开始日期
            'period[0]' => $params['period[0]'], //可选参数。循环扣款的开始日期
            'frequency[0]' => $params['frequency[0]'], // 可选参数。循环扣款的开始日期
            'recurringamt[0]' => $params['recurringamt[0]'], //可选参数。循环扣款的开始日期
            'bundlecount' => $params['bundlecount'], // 购物车中的捆绑包数量
            'bundleid[0]' => $params['bundleid[0]'], // 捆绑包的第三方 ID, 与第三方物品有相同的 ID 空间
            'bundle_qty[0]' => $params['bundle_qty[0]'], // 捆绑包的数量
            'bundle_desc[0]' => $params['bundle_desc[0]'], // 捆绑包的数量
            'bundle_category[0]' => $params['bundle_category[0]'], //   捆绑包的数量
        ]);
    }

    CONST URL_MICRO_TXN_PROCESS_AGREEMENT = 'https://partner.steam-api.com/ISteamMicroTxn/ProcessAgreement/v1/';

    /**
     * 申请一个订阅订单
     * @see https://partner.steamgames.com/doc/webapi/ISteamMicroTxn#ProcessAgreement
     * @param string $orderid 订单的 64 位唯一 ID。 对于通过 Steam 商店发起的循环订阅,此字段将为 0
     * @param string $agreementid 唯一的 64 位 Steam 扣款协议 ID
     * @param int $amount 总费用(以分表示)。 此值与向用户立即收取的初始一次性金额一致
     * @param string $currency 价格的 ISO 4217 货币代码
     * @return array|mixed|string
     * Author: Great Nomandia
     * Created At 2020/6/19 16:39
     */
    function ProcessAgreement($orderid, $agreementid, $amount, $currency = null)
    {
        /**
         * 返回值
         * params
         *     orderid - Unique 64-bit ID for order. 自己的订单号
         *     transid - Unique 64-bit Steam transaction ID. 事务Token
         *     agreementid - Steam单号
         */
        return $this->post(static::parseUrl(static::URL_MICRO_TXN_PROCESS_AGREEMENT), [
            'orderid' => $orderid,
            'agreementid' => $agreementid,
            'amount' => $amount,
            'currency' => $currency ?: static::$steam->currency,
        ]);
    }

    CONST URL_MICRO_TXN_QUERY_TXN = 'https://partner.steam-api.com/ISteamMicroTxn/QueryTxn/v2/';

    /**
     * 查询交易(返回的是数组)
     * @see https://partner.steamgames.com/doc/webapi/ISteamMicroTxn#QueryTxn
     * @param string $orderid
     * @param string $transid
     * @return array|mixed|string
     * Author: Great Nomandia
     * Created At 2020/6/19 16:45
     */
    function QueryTxn($orderid = null, $transid = null)
    {
        /**
         * 返回值
         * params
         *     orderid - 订单的唯一 64 位 ID。
         *         transid - 唯一的 64 位 Steam 交易 ID。
         *         steamid - The Steam ID of user that the order/transaction belongs to.
         *         status - Status of the order. See: 附录 A:状态值
         *         currency - ISO 4217 currency code.
         *         time - Time of transaction (RFC 3339 UTC formatted like: 2010-01-01T00:00:00Z)
         *         country - ISO 3166-1-alpha-2 country code.
         *         usstate - US State. Empty for non-US countries.
         *         items
         *             itemid - Game ID number of item.
         *             qty - Quantity of this item.
         *             amount - Total cost to user minus VAT (in cents). (199 = 1.99)
         *             vat - Total VAT or tax (in cents). (19 = .19)
         *             itemstatus - Status of items within the order.
         */
        return $this->post(static::parseUrl(static::URL_MICRO_TXN_QUERY_TXN), [
            'key' => static::$steam->appkey,
            'appid' => static::$steam->appid,
            'orderid' => $orderid,
            'transid' => $transid,
        ], true);
    }

    CONST URL_MICRO_TXN_REFUND_TXN = 'https://partner.steam-api.com/ISteamMicroTxn/RefundTxn/v2/';

    /**
     * 退单
     * @see https://partner.steamgames.com/doc/webapi/ISteamMicroTxn#RefundTxn
     * @param string $orderid
     * @return array|mixed|string
     * Author: Great Nomandia
     * Created At 2020/6/19 16:48
     */
    function RefundTxn($orderid)
    {
        /**
         * 返回值
         * params
         *     orderid - 订单的唯一 64 位 ID。
         *     transid - 唯一的 64 位 Steam 交易 ID。
         */
        return $this->post(static::parseUrl(static::URL_MICRO_TXN_REFUND_TXN), [
            'key' => static::$steam->appkey,
            'appid' => static::$steam->appid,
            'orderid' => $orderid,
        ], true);
    }
}

/**
 * YCZ - Class SteamUtils_ISteamNews 提供对 Steam 新闻功能的访问
 * @see https://partner.steamgames.com/doc/webapi/ISteamNews
 * Author: Great Nomandia
 * Created At 2020/6/22 10:32
 */
class SteamUtils_ISteamNews extends SteamUtils_ISteam
{
    CONST URL_NEWS_GET_NEWS_FOR_APP = 'https://api.steampowered.com/ISteamNews/GetNewsForApp/v2/';

    /**
     * 获得指定应用的新闻
     * @param int $enddate 获取此日期之前的文章(unix 时间戳)
     * @param int $count 要获取的文章数量(默认为 20)
     * @param string $feeds 要返回新闻的 feed 名称列表,以逗号分隔
     * @param int $maxlength 返回的内容的最大长度。如果为 0,返回完整内容。如果最大长度不够,则生成一个符合长度的片断
     * @return array|mixed|string
     * @see https://partner.steamgames.com/doc/webapi/ISteamNews#GetNewsForApp
     * Author: Great Nomandia
     * Created At 2020/6/22 10:30
     */
    function GetNewsForApp($enddate = null, $count = 20, $feeds = null, $maxlength = 0)
    {
        return $this->get(self::URL_NEWS_GET_NEWS_FOR_APP, [
            'appid' => static::$steam->appid,
            'maxlength' => $maxlength,
            'enddate' => $enddate,
            'count' => $count,
            'feeds' => $feeds,
        ]);
    }

    CONST URL_NEWS_GET_NEWS_FOR_APP_AUTHED = 'https://partner.steam-api.com/ISteamNews/GetNewsForAppAuthed/v2/';

    /**
     * 获得指定应用的新闻(旧版接口不再支持了, 目前实现为新版的接口)
     * @param int $enddate 获取此日期之前的文章(unix 时间戳)
     * @param int $count 要获取的文章数量(默认为 20)
     * @param string $feeds 要返回新闻的 feed 名称列表,以逗号分隔
     * @param int $maxlength 返回的内容的最大长度。如果为 0,返回完整内容。如果最大长度不够,则生成一个符合长度的片断
     * @return array|mixed|string
     * @see https://partner.steamgames.com/doc/webapi/ISteamNews#GetNewsForAppAuthed
     * Author: Great Nomandia
     * Created At 2020/6/22 10:34
     */
    function GetNewsForAppAuthed($enddate = null, $count = 20, $feeds = null, $maxlength = 0)
    {
        return $this->GetNewsForApp($enddate, $count, $feeds, $maxlength);
    }
}

/**
 * YCZ - Class SteamUtils_ISteamUserAuth - 访问用户相关的信息
 * @see https://partner.steamgames.com/doc/webapi/ISteamUserAuth
 * Author: Great Nomandia
 * Created At 2020/6/19 17:04
 */
class SteamUtils_ISteamUserAuth extends SteamUtils_ISteam
{
    CONST URL_AUTHENTICATE_USER = 'https://api.steampowered.com/ISteamUserAuth/AuthenticateUser/v1/';

    /**
     * 验证登录
     * @see https://partner.steamgames.com/doc/webapi/ISteamUserAuth#AuthenticateUser
     * @param string $steamid
     * @param string $encrypted_loginkey
     * @return array|mixed|string
     * Author: Great Nomandia
     * Created At 2020/6/19 17:07
     */
    function AuthenticateUser($steamid, $encrypted_loginkey)
    {
        return $this->post(static::URL_AUTHENTICATE_USER, [
            'steamid' => $steamid,
            'sessionkey' => $sessionkey, // 随机RSA文本
            'encrypted_loginkey' => $encrypted_loginkey,
        ], true);
    }

    CONST URL_AUTHENTICATE_USER_TICKET = 'https://api.steampowered.com/ISteamUserAuth/AuthenticateUserTicket/v1/';

    /**
     * 验证票据
     * @see https://partner.steamgames.com/doc/webapi/ISteamUserAuth#AuthenticateUserTicket
     * @param string $ticket 将 GetAuthSessionTicket 的 ticket 从二进制转换为十六进制,转换为大小合适的字节字符数组,并将结果作为此 ticket 参数传递进来。
     * @return string
     * Author: Great Nomandia
     * Created At 2020/6/19 17:11
     */
    function AuthenticateUserTicket($ticket)
    {
        return $this->get(static::URL_AUTHENTICATE_USER_TICKET, [
            'key' => static::$steam->appkey,
            'appid' => static::$steam->appid,
            'ticket' => $ticket,
        ], true);
    }
}

/**
 * YCZ - Class SteamUtils_ISteamUserStats - 用于访问关于用户的信息
 * @see https://partner.steamgames.com/doc/webapi/ISteamUserStats
 * Author: Great Nomandia
 * Created At 2020/6/19 17:13
 */
class SteamUtils_ISteamUserStats extends SteamUtils_ISteam
{
    CONST URL_GET_GLOBAL_ACHIEVEMENT_PERCENTAGE_FOR_APP = 'https://api.steampowered.com/ISteamUserStats/GetGlobalAchievementPercentagesForApp/v2/';

    /**
     * 为指定应用获取全局成就百分比
     * @see https://partner.steamgames.com/doc/webapi/ISteamUserStats#GetGlobalAchievementPercentagesForApp
     * @param int $gameid 要获取成就百分比的 GameID
     * @return string|array|mixed
     * Author: Great Nomandia
     * Created At 2020/6/19 17:16
     */
    function GetGlobalAchievementPercentagesForApp($gameid)
    {
        return $this->get(static::URL_GET_GLOBAL_ACHIEVEMENT_PERCENTAGE_FOR_APP, [
            'gameid' => $gameid ?: static::$steam->gameid
        ], true);
    }

    CONST URL_GET_GLOBAL_STATS_FOR_GAME = 'https://api.steampowered.com/ISteamUserStats/GetGlobalStatsForGame/v1/';

    /**
     * Retrieves the global stats percentages for the specified app
     * @see https://partner.steamgames.com/doc/webapi/ISteamUserStats#GetGlobalStatsForGame
     * @param int $count 要获取数据的统计的数量
     * @param string $name 要获取数据的统计的名称
     * @param int $startdate 每日合计的开始日期(unix 时间戳)
     * @param int $enddate 每日合计的结束日期(unix 时间戳)
     * @return string|array|mixed
     * Author: Great Nomandia
     * Created At 2020/6/19 17:18
     */
    function GetGlobalStatsForGame($count, $name, $startdate, $enddate)
    {
        return $this->get(static::URL_GET_GLOBAL_STATS_FOR_GAME, [
            'appid' => static::$steam->appid,
            'count' => $count,
            'name[0]' => $name,
            'startdate' => $startdate,
            'enddate' => $enddate,
        ], true);
    }

    CONST URL_GET_NUMBER_OF_CURRENT_PLAYERS = 'https://api.steampowered.com/ISteamUserStats/GetNumberOfCurrentPlayers/v1/';

    /**
     * 获得指定应用当前在 Steam 上的活跃玩家的总数量
     * @see https://partner.steamgames.com/doc/webapi/ISteamUserStats#GetNumberOfCurrentPlayers
     * @return array|mixed|string
     * Author: Great Nomandia
     * Created At 2020/6/19 17:21
     */
    function GetNumberOfCurrentPlayers()
    {
        return $this->get(static::URL_GET_NUMBER_OF_CURRENT_PLAYERS, [
            'appid' => static::$steam->appid,
        ], true);
    }

    CONST URL_GET_PLAYER_ACHIEVEMENTS = 'https://api.steampowered.com/ISteamUserStats/GetPlayerAchievements/v1/';

    /**
     * 获得指定用户在一个应用中已解锁的成就列表
     * @see https://partner.steamgames.com/doc/webapi/ISteamUserStats#GetPlayerAchievements
     * @param string $steamid
     * @param string $language 返回字符串的语言
     * @return array|mixed|string
     * Author: Great Nomandia
     * Created At 2020/6/19 17:24
     */
    function GetPlayerAchievements($steamid = null, $language = null)
    {
        return $this->get(static::URL_GET_PLAYER_ACHIEVEMENTS, [
            'steamid' => $steamid,
            'l' => $language ?: static::$steam->language,
        ]);
    }

    CONST URL_GET_SCHEMA_FOR_GAME = 'https://api.steampowered.com/ISteamUserStats/GetSchemaForGame/v2/';

    /**
     * 获得指定游戏的统计与成就的完整列表
     * @see https://partner.steamgames.com/doc/webapi/ISteamUserStats#GetSchemaForGame
     * @param string $language
     * @return array|mixed|string
     * Author: Great Nomandia
     * Created At 2020/6/19 17:25
     */
    function GetSchemaForGame($language = null)
    {
        return $this->get(static::URL_GET_PLAYER_ACHIEVEMENTS, [
            'key' => static::$steam->appkey,
            'appid' => static::$steam->appid,
            'l' => $language ?: static::$steam->language,
        ], true);
    }

    CONST URL_GET_USER_STATS_FOR_GAME = 'https://api.steampowered.com/ISteamUserStats/GetUserStatsForGame/v2/';

    /**
     * 获得指定用户在一个应用中设置的统计列表
     * @see https://partner.steamgames.com/doc/webapi/ISteamUserStats#GetUserStatsForGame
     * @param string $steamid
     * @return array|mixed|string
     * Author: Great Nomandia
     * Created At 2020/6/19 17:27
     */
    function GetUserStatsForGame($steamid = null)
    {
        return $this->get(static::URL_GET_USER_STATS_FOR_GAME, [
            'steamid' => $steamid,
        ]);
    }

    CONST URL_SET_USER_STATS_FOR_GAME = 'https://partner.steam-api.com/ISteamUserStats/SetUserStatsForGame/v1/';

    /**
     * 为游戏设置指定用户的统计
     * @see https://partner.steamgames.com/doc/webapi/ISteamUserStats#SetUserStatsForGame
     * @param int $count 要设置值的统计与成就的数量(名称/值参数对)
     * @param string $name 要设置的统计与成就的名称
     * @param int $value 要设置的值
     * @param string $steamid
     * @return array|mixed|string
     * Author: Great Nomandia
     * Created At 2020/6/19 17:28
     */
    function SetUserStatsForGame($count, $name, $value, $steamid = null)
    {
        return $this->post(static::URL_SET_USER_STATS_FOR_GAME, [
            'steamid' => $steamid,
            'count' => $count,
            'name[0]' => $name,
            'value[0]' => $value,
        ]);
    }
}

/**
 * YCZ - Class SteamUtils_ISteamUser - 用于访问信息并与用户交互
 * @see https://partner.steamgames.com/doc/webapi/ISteamUser
 * Author: Great Nomandia
 * Created At 2020/6/19 17:32
 */
class SteamUtils_ISteamUser extends SteamUtils_ISteam
{

    CONST URL_CHECK_APP_OWNER_SHIP = 'https://partner.steam-api.com/ISteamUser/CheckAppOwnership/v2/';

    /**
     * 查看是否指定用户拥有该应用
     * @see https://partner.steamgames.com/doc/webapi/ISteamUser#CheckAppOwnership
     * @param string $steamid
     * @return array|mixed|string
     * Author: Great Nomandia
     * Created At 2020/6/19 17:33
     */
    function CheckAppOwnership($steamid = null)
    {
        /**
         * 返回值
         * ownsapp:指明用户是实际所有者或应用
         * permanent:Indicates if the user owns the app permanently.
         * timestamp:获取该应用的时间
         * ownersteamid:指明该应用的真正所有者
         * sitelicense:Indicates if user is borrowing this license from a PC Cafe site
         */
        return $this->get(static::URL_CHECK_APP_OWNER_SHIP, [
            'steamid' => $steamid,
        ]);
    }

    CONST URL_GET_APP_PRICE_INFO = 'https://partner.steam-api.com/ISteamUser/GetAppPriceInfo/v1/';

    /**
     * 获取APP的价格信息
     * @see https://partner.steamgames.com/doc/webapi/ISteamUser#GetAppPriceInfo
     * @param string $appids appid逗号,分隔
     * @param string $steamid
     * @return array|mixed|string
     * Author: Great Nomandia
     * Created At 2020/6/19 17:36
     */
    function GetAppPriceInfo($appids, $steamid = null)
    {
        return $this->get(static::URL_GET_APP_PRICE_INFO, [
            'key' => static::$steam->appkey,
            'steamid' => $steamid ?: static::$steam->steamid,
            'appids' => $appids,
        ], true);
    }

    CONST URL_GET_FRIEND_LIST = 'https://api.steampowered.com/ISteamUser/GetFriendList/v1/';

    /**
     * 获取好友列表
     * @see https://partner.steamgames.com/doc/webapi/ISteamUser#GetFriendList
     * @param string $relationship
     * @param string $steamid
     * @return array|mixed|string
     * Author: Great Nomandia
     * Created At 2020/6/19 17:39
     */
    function GetFriendList($relationship, $steamid = null)
    {
        return $this->get(static::URL_GET_FRIEND_LIST, [
            'key' => static::$steam->appkey,
            'steamid' => $steamid ?: static::$steam->steamid,
            'relationship' => $relationship,
        ], true);
    }

    CONST URL_GET_PLAY_BANS = 'https://api.steampowered.com/ISteamUser/GetPlayerBans/v1/';

    /**
     * 获取账号屏蔽信息
     * @see https://partner.steamgames.com/doc/webapi/ISteamUser#GetPlayerBans
     * @param string $steamids
     * @return array|mixed|string
     * Author: Great Nomandia
     * Created At 2020/6/19 17:41
     */
    function GetPlayerBans($steamids)
    {
        return $this->get(static::URL_GET_PLAY_BANS, [
            'key' => static::$steam->appkey,
            'steamids' => $steamids,
        ], true);
    }

    CONST URL_GET_PLAYER_SUMMARIES = 'https://api.steampowered.com/ISteamUser/GetPlayerSummaries/v2/';

    /**
     * 获取玩家汇总数据
     * @see https://partner.steamgames.com/doc/webapi/ISteamUser#GetPlayerSummaries
     * @param string $steamids
     * @return array|mixed|string
     * Author: Great Nomandia
     * Created At 2020/6/19 17:43
     */
    function GetPlayerSummaries($steamids)
    {
        /**
         * 返回值类似
         * "response":{
         * "players":[
         * {
         * "steamid":"77561198355051011",
         * "communityvisibilitystate":1,
         * "profilestate":1,
         * "personaname":"Mister Manager",
         * "lastlogoff":1556305001,
         * "profileurl":"https://steamcommunity.com/profiles/77561198355051011/",
         * "avatar":"https://steamcdn-a.akamaihd.net/steamcommunity/public/images/avatars/32/32f70a383a437d03af91d2f01a0776adf75201b5.jpg",
         * "avatarmedium":"https://steamcdn-a.akamaihd.net/steamcommunity/public/images/avatars/32/32f70a383a437d03af91d2f01a0776adf75201b5_medium.jpg",
         * "avatarfull":"https://steamcdn-a.akamaihd.net/steamcommunity/public/images/avatars/32/32f70a383a437d03af91d2f01a0776adf75201b5_full.jpg",
         * }
         * ]
         * }
         */
        return $this->get(static::URL_GET_PLAYER_SUMMARIES, [
            'key' => static::$steam->appkey,
            'steamids' => $steamids,
        ], true);
    }

    CONST URL_GET_PUBLISHER_APP_OWNERSHIP = 'https://partner.steam-api.com/ISteamUser/GetPublisherAppOwnership/v3/';

    /**
     * 获取玩家拥有的app
     * @see https://partner.steamgames.com/doc/webapi/ISteamUser#GetPublisherAppOwnership
     * @param string $steamid
     * @return array|mixed|string
     * Author: Great Nomandia
     * Created At 2020/6/19 17:46
     */
    function GetPublisherAppOwnership($steamid = null)
    {
        /**
         * "appownership":{
         * "apps":[
         * {
         * "appid":60,
         * "ownsapp":true, // 是否买了此游戏,Whether the user currently owns your game. 将对通过购买、序列号、家庭共享、免费周末以及站点许可获得的所有权有效。
         * "permanent":true, // 购买时效,true=永久 Whether the user permanetly owns your game. 对通过家庭共享、免费周末、站点许可获得的所有权无效。
         * "timestamp":"2005-04-03T17:50:29Z", // GMT time for when the user first accquired the appID
         * "ownersteamid":"76561197978236369", //    SteamID for the actual owner. If the app is owned via Family Sharing, ownersteamid will be the actual owner. Otherwise will be the same steamID passed in
         * "sitelicense":"false" // 指明用户是否从商用站点借用此许可。
         * }
         * ]
         * }
         */
        return $this->get(static::URL_GET_PUBLISHER_APP_OWNERSHIP, [
            'key' => static::$steam->appkey,
            'steamid' => $steamid ?: static::$steam->steamid,
        ], true);
    }

    CONST URL_GET_PUBLISHER_APP_OWNERSHIP_CHANGES = 'https://partner.steam-api.com/ISteamUser/GetPublisherAppOwnershipChanges/v1/';

    /**
     * 获取哪些用户可以对指定版本具有所有权
     * @see https://partner.steamgames.com/doc/webapi/ISteamUser#GetPublisherAppOwnershipChanges
     * @param string $packagerowversion
     * @param string $cdkeyrowversion
     * @return array|mixed|string
     * Author: Great Nomandia
     * Created At 2020/6/19 17:50
     */
    function GetPublisherAppOwnershipChanges($packagerowversion, $cdkeyrowversion)
    {
        /**
         * "ownershipchanges": {
         * "steamids": [
         * {
         * "steamid": "76561198114498811"
         * },
         * {
         * "steamid": "76561198114498812"
         * },
         * ...
         * ],
         * "packagerowversion": "12448390228",
         * "cdkeyrowversion": "49857241147",
         * "moredata": true
         * }
         */
        return $this->get(static::URL_GET_PUBLISHER_APP_OWNERSHIP_CHANGES, [
            'key' => static::$steam->appkey,
            'packagerowversion' => $packagerowversion,
            'cdkeyrowversion' => $cdkeyrowversion,
        ], true);
    }

    CONST URL_GET_USER_GROUP_LIST = 'https://api.steampowered.com/ISteamUser/GetUserGroupList/v1/';

    /**
     * 获取用户所在的分组
     * @see https://partner.steamgames.com/doc/webapi/ISteamUser#GetUserGroupList
     * @param string $steamid
     * @return array|mixed|string
     * Author: Great Nomandia
     * Created At 2020/6/19 17:54
     */
    function GetUserGroupList($steamid = null)
    {
        return $this->get(static::URL_GET_USER_GROUP_LIST, [
            'key' => static::$steam->appkey,
            'steamid' => $steamid ?: static::$steam->steamid,
        ], true);
    }

    CONST URL_GRANT_PACKAGE = 'https://partner.steam-api.com/ISteamUser/GrantPackage/v1/';

    /**
     * 第三方发放授权包?
     * @see https://partner.steamgames.com/doc/webapi/ISteamUser#GrantPackage
     * @param string $packageid PackageID to grant
     * @param string $ipaddress ip address of user in string format (xxx.xxx.xxx.xxx).
     * @param string $thirdpartykey Optionally associate third party key during grant. 'thirdpartyappid' will have to be set.
     * @param string $thirdpartyappid Has to be set if 'thirdpartykey' is set. The appid associated with the 'thirdpartykey'.
     * @param null $steamid
     * @return array|mixed|string
     * Author: Great Nomandia
     * Created At 2020/6/19 17:56
     */
    function GrantPackage($packageid, $ipaddress, $thirdpartykey, $thirdpartyappid, $steamid = null)
    {
        return $this->get(static::URL_GET_USER_GROUP_LIST, [
            'key' => static::$steam->appkey,
            'steamid' => $steamid ?: static::$steam->steamid,
            'packageid' => $packageid,
            'ipaddress' => $ipaddress,
            'thirdpartykey' => $thirdpartykey,
            'thirdpartyappid' => $thirdpartyappid,
        ], true);
    }

    CONST URL_RESOLVE_VANITY_URL = 'https://api.steampowered.com/ISteamUser/ResolveVanityURL/v1/';

    /**
     * 解析一个伪地址(应该是返回一个链接)
     * @see https://partner.steamgames.com/doc/webapi/ISteamUser#ResolveVanityURL
     * @param string $vanityurl 虚拟URL The vanity URL to get a SteamID for
     * @param int $url_type The type of vanity URL. 1 (default): 玩家信息Individual profile, 2: 分组Group, 3: 官网Official game group
     * Author: Great Nomandia
     * Created At 2020/6/19 17:58
     * @return array|mixed|string
     */
    function ResolveVanityURL($vanityurl, $url_type = 1)
    {
        return $this->get(static::URL_GET_USER_GROUP_LIST, [
            'key' => static::$steam->appkey,
            'vanityurl' => $vanityurl,
            'url_type' => $url_type,
        ], true);
    }
}

/**
 * YCZ - Class SteamUtils_ISteamWebAPIUtil - 获取Steam相关数据
 * @see https://partner.steamgames.com/doc/webapi/ISteamWebAPIUtil
 * Author: Great Nomandia
 * Created At 2020/6/19 18:06
 */
class SteamUtils_ISteamWebAPIUtil extends SteamUtils_ISteam
{
    CONST URL_GET_SERVER_INFO = 'https://api.steampowered.com/ISteamWebAPIUtil/GetServerInfo/v1/';

    /**
     * 获取(Steam)服务器信息?
     * @see https://partner.steamgames.com/doc/webapi/ISteamWebAPIUtil#GetServerInfo
     * @return array|mixed|string
     * Author: Great Nomandia
     * Created At 2020/6/19 18:07
     */
    function GetServerInfo()
    {
        return $this->get(static::URL_GET_SERVER_INFO);
    }

    CONST URL_GET_SUPPORT_API_LIST = 'https://api.steampowered.com/ISteamWebAPIUtil/GetSupportedAPIList/v1/';

    /**
     * 获取支持的API列表
     * @see https://partner.steamgames.com/doc/webapi/ISteamWebAPIUtil#GetSupportedAPIList
     * @return array|mixed|string
     * Author: Great Nomandia
     * Created At 2020/6/19 18:08
     */
    function GetSupportedAPIList()
    {
        return $this->get(static::URL_GET_SUPPORT_API_LIST);
    }
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,454评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,553评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,921评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,648评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,770评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,950评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,090评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,817评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,275评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,592评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,724评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,409评论 4 333
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,052评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,815评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,043评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,503评论 2 361
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,627评论 2 350