private static async Task<string> ResponseRedeem(ulong steamID, string botName, string message, ERedeemFlags redeemFlags = ERedeemFlags.None) { if ((steamID == 0) || string.IsNullOrEmpty(botName) || string.IsNullOrEmpty(message)) { Logging.LogNullError(nameof(steamID) + " || " + nameof(botName) + " || " + nameof(message)); return null; } Bot bot; if (Bots.TryGetValue(botName, out bot)) { return await bot.ResponseRedeem(steamID, message, redeemFlags).ConfigureAwait(false); } if (IsOwner(steamID)) { return "Couldn't find any bot named " + botName + "!"; } return null; }
private async Task<string> ResponseRedeem(ulong steamID, string message, ERedeemFlags redeemFlags = ERedeemFlags.None) { if ((steamID == 0) || string.IsNullOrEmpty(message)) { Logging.LogNullError(nameof(steamID) + " || " + nameof(message), BotName); return null; } if (!IsMaster(steamID)) { return null; } bool forward = !redeemFlags.HasFlag(ERedeemFlags.SkipForwarding) && (redeemFlags.HasFlag(ERedeemFlags.ForceForwarding) || BotConfig.ForwardKeysToOtherBots); bool distribute = !redeemFlags.HasFlag(ERedeemFlags.SkipDistribution) && (redeemFlags.HasFlag(ERedeemFlags.ForceDistribution) || BotConfig.DistributeKeys); message = message.Replace(",", Environment.NewLine); StringBuilder response = new StringBuilder(); using (StringReader reader = new StringReader(message)) { using (IEnumerator<Bot> enumerator = Bots.OrderBy(bot => bot.Key).Select(bot => bot.Value).GetEnumerator()) { string key = reader.ReadLine(); Bot currentBot = this; while (!string.IsNullOrEmpty(key) && (currentBot != null)) { if (redeemFlags.HasFlag(ERedeemFlags.Validate) && !IsValidCdKey(key)) { key = reader.ReadLine(); // Next key continue; // Keep current bot } if ((redeemFlags.HasFlag(ERedeemFlags.SkipInitial) && (currentBot == this)) || !currentBot.IsConnectedAndLoggedOn) { currentBot = null; // Either bot will be changed, or loop aborted } else { ArchiHandler.PurchaseResponseCallback result = await currentBot.ArchiHandler.RedeemKey(key).ConfigureAwait(false); if (result == null) { response.Append(Environment.NewLine + "<" + currentBot.BotName + "> Key: " + key + " | Status: " + ArchiHandler.PurchaseResponseCallback.EPurchaseResult.Timeout); currentBot = null; // Either bot will be changed, or loop aborted } else { switch (result.PurchaseResult) { case ArchiHandler.PurchaseResponseCallback.EPurchaseResult.DuplicatedKey: case ArchiHandler.PurchaseResponseCallback.EPurchaseResult.InvalidKey: case ArchiHandler.PurchaseResponseCallback.EPurchaseResult.OK: case ArchiHandler.PurchaseResponseCallback.EPurchaseResult.SteamWalletCode: case ArchiHandler.PurchaseResponseCallback.EPurchaseResult.Timeout: case ArchiHandler.PurchaseResponseCallback.EPurchaseResult.Unknown: if (result.PurchaseResult == ArchiHandler.PurchaseResponseCallback.EPurchaseResult.SteamWalletCode) { // If it's a wallet code, try to redeem it, and forward the result // The result is final, there is no place for forwarding result.PurchaseResult = await currentBot.ArchiWebHandler.RedeemWalletKey(key).ConfigureAwait(false); } response.Append(Environment.NewLine + "<" + currentBot.BotName + "> Key: " + key + " | Status: " + result.PurchaseResult + ((result.Items != null) && (result.Items.Count > 0) ? " | Items: " + string.Join("", result.Items) : "")); key = reader.ReadLine(); // Next key if (result.PurchaseResult == ArchiHandler.PurchaseResponseCallback.EPurchaseResult.OK) { break; // Next bot (if needed) } continue; // Keep current bot case ArchiHandler.PurchaseResponseCallback.EPurchaseResult.AlreadyOwned: case ArchiHandler.PurchaseResponseCallback.EPurchaseResult.BaseGameRequired: case ArchiHandler.PurchaseResponseCallback.EPurchaseResult.OnCooldown: case ArchiHandler.PurchaseResponseCallback.EPurchaseResult.RegionLocked: response.Append(Environment.NewLine + "<" + currentBot.BotName + "> Key: " + key + " | Status: " + result.PurchaseResult + ((result.Items != null) && (result.Items.Count > 0) ? " | Items: " + string.Join("", result.Items) : "")); if (!forward) { key = reader.ReadLine(); // Next key break; // Next bot (if needed) } if (distribute) { break; // Next bot, without changing key } Dictionary<uint, string> items = result.Items ?? new Dictionary<uint, string>(); Bot previousBot = currentBot; bool alreadyHandled = false; foreach (Bot bot in Bots.Where(bot => (bot.Value != previousBot) && (!redeemFlags.HasFlag(ERedeemFlags.SkipInitial) || (bot.Value != this)) && bot.Value.IsConnectedAndLoggedOn && ((items.Count == 0) || items.Keys.Any(packageID => !bot.Value.OwnedPackageIDs.Contains(packageID)))).OrderBy(bot => bot.Key).Select(bot => bot.Value)) { ArchiHandler.PurchaseResponseCallback otherResult = await bot.ArchiHandler.RedeemKey(key).ConfigureAwait(false); if (otherResult == null) { response.Append(Environment.NewLine + "<" + bot.BotName + "> Key: " + key + " | Status: Timeout!"); continue; } switch (otherResult.PurchaseResult) { case ArchiHandler.PurchaseResponseCallback.EPurchaseResult.DuplicatedKey: case ArchiHandler.PurchaseResponseCallback.EPurchaseResult.InvalidKey: case ArchiHandler.PurchaseResponseCallback.EPurchaseResult.OK: alreadyHandled = true; // This key is already handled, as we either redeemed it or we're sure it's dupe/invalid break; } response.Append(Environment.NewLine + "<" + bot.BotName + "> Key: " + key + " | Status: " + otherResult.PurchaseResult + ((otherResult.Items != null) && (otherResult.Items.Count > 0) ? " | Items: " + string.Join("", otherResult.Items) : "")); if (alreadyHandled) { break; } if (otherResult.Items == null) { continue; } foreach (KeyValuePair<uint, string> item in otherResult.Items) { items[item.Key] = item.Value; } } key = reader.ReadLine(); // Next key break; // Next bot (if needed) } } } if (!distribute && !redeemFlags.HasFlag(ERedeemFlags.SkipInitial)) { continue; } do { currentBot = enumerator.MoveNext() ? enumerator.Current : null; } while ((currentBot == this) || ((currentBot != null) && !currentBot.IsConnectedAndLoggedOn)); } } } return response.Length == 0 ? null : response.ToString(); }