requestRichPresence(appid, steamIDs, language, callback) {
		if (!Array.isArray(steamIDs)) {
			steamIDs = [steamIDs];
		}

		if (typeof language == 'function') {
			callback = language;
			language = null;
		}

		return StdLib.Promises.timeoutCallbackPromise(10000, null, callback, (resolve, reject) => {
			this._send({
				// Header
				msg: EMsg.ClientRichPresenceRequest,
				proto: {routing_appid: appid},
			}, {
				// Request
				steamid_request: steamIDs.map(sid => Helpers.steamID(sid).getSteamID64())
			}, async (body) => {
				// Response
				let response = {};
				body.rich_presence = body.rich_presence || [];
				for (let rp of body.rich_presence) {
					let kv = rp.rich_presence_kv;
					if (!kv || !rp.steamid_user) {
						continue;
					}

					try {
						let kvObj = BinaryKVParser.parse(kv); // This will throw in the event of there being no RP data (e.g. user not in game)
						if (kvObj && kvObj.RP) {
							response[rp.steamid_user] = {
								richPresence: kvObj.RP,
								localizedString: null,
							};
							// Do this separately as it will reject if it cannot localize
							response[rp.steamid_user].localizedString = await this._getRPLocalizedString(appid, kvObj.RP, language);
						}
					} catch (e) {
						// don't care, there's nothing here
					}
				}

				resolve({users: response});
			});
		});
	}
Request rich presence data of one or more users for an appid.
@param {int} appid - The appid to get rich presence data for
@param {SteamID[]|string[]|SteamID|string} steamIDs - SteamIDs of users to request rich presence data for
@param {string} [language] - Language to get localized strings in. Defaults to language passed to constructor.
@param {function} [callback] - Called or resolved with 'users' property with each key being a SteamID and value being the rich presence response if received
@return Promise