private static void PrintImportants(SteamApps.PICSChangesCallback callback) { // Apps var important = callback.AppChanges.Keys.Intersect(Application.ImportantApps.Keys); foreach (var app in important) { var appName = Steam.GetAppName(app, out var appType); IRC.Instance.AnnounceImportantAppUpdate(app, $"{appType} update: {Colors.BLUE}{appName}{Colors.NORMAL} -{Colors.DARKBLUE} {SteamDB.GetAppUrl(app, "history")}"); if (Settings.Current.CanQueryStore) { Steam.Instance.UnifiedMessages.SendMessage("ChatRoom.SendChatMessage#1", new CChatRoom_SendChatMessage_Request { chat_group_id = 1147, chat_id = 10208600, message = $"{appType} update: {appName}\n<{SteamDB.GetAppUrl(app, "history")}?changeid={callback.CurrentChangeNumber}>" }); } } // Packages important = callback.PackageChanges.Keys.Intersect(Application.ImportantSubs.Keys); foreach (var package in important) { IRC.Instance.SendMain($"Package update: {Colors.BLUE}{Steam.GetPackageName(package)}{Colors.NORMAL} -{Colors.DARKBLUE} {SteamDB.GetPackageUrl(package, "history")}"); } }
public override async Task OnCommand(CommandArguments command) { uint subID; if (command.Message.Length == 0 || !uint.TryParse(command.Message, out subID)) { command.Reply("Usage:{0} sub <subid>", Colors.OLIVE); return; } var job = await Steam.Instance.Apps.PICSGetProductInfo(null, subID, false, false); var callback = job.Results.FirstOrDefault(x => x.Packages.ContainsKey(subID)); if (callback == null) { command.Reply("Unknown SubID: {0}{1}{2}", Colors.BLUE, subID, LicenseList.OwnedSubs.ContainsKey(subID) ? SteamDB.StringCheckmark : string.Empty); return; } var info = callback.Packages[subID]; info.KeyValues.SaveToFile(Path.Combine(Application.Path, "sub", string.Format("{0}.vdf", info.ID)), false); command.Reply("{0}{1}{2} -{3} {4}{5} - Dump:{6} {7}{8}{9}{10}", Colors.BLUE, Steam.GetPackageName(info.ID), Colors.NORMAL, Colors.DARKBLUE, SteamDB.GetPackageURL(info.ID), Colors.NORMAL, Colors.DARKBLUE, SteamDB.GetRawPackageURL(info.ID), Colors.NORMAL, info.MissingToken ? SteamDB.StringNeedToken : string.Empty, LicenseList.OwnedSubs.ContainsKey(info.ID) ? SteamDB.StringCheckmark : string.Empty ); }
public override async Task OnCommand(CommandArguments command) { if (command.Message.Length == 0 || !uint.TryParse(command.Message, out var subID)) { command.Reply($"Usage:{Colors.OLIVE} sub <subid>"); return; } var info = await GetPackageData(subID); if (info == null) { command.Reply($"Unknown SubID: {Colors.BLUE}{subID}{(LicenseList.OwnedSubs.ContainsKey(subID) ? SteamDB.StringCheckmark : string.Empty)}"); return; } if (!info.KeyValues.Children.Any()) { command.Reply($"No package info returned for SubID: {Colors.BLUE}{subID}{(info.MissingToken ? SteamDB.StringNeedToken : string.Empty)}{(LicenseList.OwnedSubs.ContainsKey(subID) ? SteamDB.StringCheckmark : string.Empty)}"); return; } info.KeyValues.SaveToFile(Path.Combine(Application.Path, "sub", $"{info.ID}.vdf"), false); command.Reply($"{Colors.BLUE}{Steam.GetPackageName(info.ID)}{Colors.NORMAL} -{Colors.DARKBLUE} {SteamDB.GetPackageUrl(info.ID)}{Colors.NORMAL} - Dump:{Colors.DARKBLUE} {SteamDB.GetRawPackageUrl(info.ID)}{Colors.NORMAL}{(info.MissingToken ? SteamDB.StringNeedToken : string.Empty)}{(LicenseList.OwnedSubs.ContainsKey(info.ID) ? SteamDB.StringCheckmark : string.Empty)}"); }
private void OnFreeLicenseCallback(SteamApps.FreeLicenseCallback callback) { JobManager.TryRemoveJob(callback.JobID); var packageIDs = callback.GrantedPackages; var appIDs = callback.GrantedApps; Log.WriteDebug("FreeLicense", "Received free license: {0} ({1} apps: {2}, {3} packages: {4})", callback.Result, appIDs.Count, string.Join(", ", appIDs), packageIDs.Count, string.Join(", ", packageIDs)); if (appIDs.Any()) { JobManager.AddJob(() => Steam.Instance.Apps.PICSGetAccessTokens(appIDs, Enumerable.Empty <uint>())); } if (packageIDs.Any()) { JobManager.AddJob(() => Steam.Instance.Apps.PICSGetProductInfo(Enumerable.Empty <uint>(), packageIDs)); TaskManager.RunAsync(() => { RefreshPackageNames(); foreach (var subID in packageIDs) { IRC.Instance.SendAnnounce("New free license granted: {0}{1}{2} -{3} {4}", Colors.BLUE, Steam.GetPackageName(subID), Colors.NORMAL, Colors.DARKBLUE, SteamDB.GetPackageURL(subID) ); } }); } }
public override async Task OnCommand(CommandArguments command) { if (command.Message.Length == 0 || !uint.TryParse(command.Message, out var subID)) { command.Reply($"Usage:{Colors.OLIVE} sub <subid>"); return; } var tokenTask = Steam.Instance.Apps.PICSGetAccessTokens(null, subID); tokenTask.Timeout = TimeSpan.FromSeconds(10); var tokenCallback = await tokenTask; SteamApps.PICSRequest request; if (tokenCallback.PackageTokens.ContainsKey(subID)) { request = PICSTokens.NewPackageRequest(subID, tokenCallback.PackageTokens[subID]); } else { request = PICSTokens.NewPackageRequest(subID); } var infoTask = Steam.Instance.Apps.PICSGetProductInfo(Enumerable.Empty <SteamApps.PICSRequest>(), new List <SteamApps.PICSRequest> { request }); infoTask.Timeout = TimeSpan.FromSeconds(10); var job = await infoTask; var callback = job.Results?.FirstOrDefault(x => x.Packages.ContainsKey(subID)); if (callback == null) { command.Reply($"Unknown SubID: {Colors.BLUE}{subID}{(LicenseList.OwnedSubs.ContainsKey(subID) ? SteamDB.StringCheckmark : string.Empty)}"); return; } var info = callback.Packages[subID]; if (!info.KeyValues.Children.Any()) { command.Reply($"No package info returned for SubID: {Colors.BLUE}{subID}{(info.MissingToken ? SteamDB.StringNeedToken : string.Empty)}{(LicenseList.OwnedSubs.ContainsKey(subID) ? SteamDB.StringCheckmark : string.Empty)}"); return; } info.KeyValues.SaveToFile(Path.Combine(Application.Path, "sub", $"{info.ID}.vdf"), false); command.Reply($"{Colors.BLUE}{Steam.GetPackageName(info.ID)}{Colors.NORMAL} -{Colors.DARKBLUE} {SteamDB.GetPackageUrl(info.ID)}{Colors.NORMAL} - Dump:{Colors.DARKBLUE} {SteamDB.GetRawPackageUrl(info.ID)}{Colors.NORMAL}{(info.MissingToken ? SteamDB.StringNeedToken : string.Empty)}{(LicenseList.OwnedSubs.ContainsKey(info.ID) ? SteamDB.StringCheckmark : string.Empty)}"); }
public override async Task OnCommand(CommandArguments command) { if (command.Message.Length == 0 || !uint.TryParse(command.Message, out var subID)) { command.Reply("Usage:{0} sub <subid>", Colors.OLIVE); return; } var tokenTask = Steam.Instance.Apps.PICSGetAccessTokens(null, subID); tokenTask.Timeout = TimeSpan.FromSeconds(10); var tokenCallback = await tokenTask; SteamApps.PICSRequest request; if (tokenCallback.PackageTokens.ContainsKey(subID)) { request = PICSTokens.NewPackageRequest(subID, tokenCallback.PackageTokens[subID]); } else { request = PICSTokens.NewPackageRequest(subID); } var infoTask = Steam.Instance.Apps.PICSGetProductInfo(Enumerable.Empty <SteamApps.PICSRequest>(), new List <SteamApps.PICSRequest> { request }); infoTask.Timeout = TimeSpan.FromSeconds(10); var job = await infoTask; var callback = job.Results.FirstOrDefault(x => x.Packages.ContainsKey(subID)); if (callback == null) { command.Reply("Unknown SubID: {0}{1}{2}", Colors.BLUE, subID, LicenseList.OwnedSubs.ContainsKey(subID) ? SteamDB.StringCheckmark : string.Empty); return; } var info = callback.Packages[subID]; info.KeyValues.SaveToFile(Path.Combine(Application.Path, "sub", string.Format("{0}.vdf", info.ID)), false); command.Reply("{0}{1}{2} -{3} {4}{5} - Dump:{6} {7}{8}{9}{10}", Colors.BLUE, Steam.GetPackageName(info.ID), Colors.NORMAL, Colors.DARKBLUE, SteamDB.GetPackageUrl(info.ID), Colors.NORMAL, Colors.DARKBLUE, SteamDB.GetRawPackageUrl(info.ID), Colors.NORMAL, info.MissingToken ? SteamDB.StringNeedToken : string.Empty, LicenseList.OwnedSubs.ContainsKey(info.ID) ? SteamDB.StringCheckmark : string.Empty ); }
private void OnFreeLicenseCallback(SteamApps.FreeLicenseCallback callback) { JobManager.TryRemoveJob(callback.JobID); var packageIDs = callback.GrantedPackages; var appIDs = callback.GrantedApps; Log.WriteDebug(nameof(FreeLicense), "Received free license: {0} ({1} apps: {2}, {3} packages: {4})", callback.Result, appIDs.Count, string.Join(", ", appIDs), packageIDs.Count, string.Join(", ", packageIDs)); if (appIDs.Count > 0) { JobManager.AddJob( () => Steam.Instance.Apps.PICSGetAccessTokens(appIDs, Enumerable.Empty <uint>()), new PICSTokens.RequestedTokens { Apps = appIDs.ToList() }); foreach (var appid in appIDs) { LocalConfig.Current.FreeLicensesToRequest.Remove(appid); } LocalConfig.Save(); } if (packageIDs.Count > 0) { JobManager.AddJob( () => Steam.Instance.Apps.PICSGetAccessTokens(Enumerable.Empty <uint>(), packageIDs), new PICSTokens.RequestedTokens { Packages = packageIDs.ToList() }); TaskManager.RunAsync(async() => { await RefreshPackageNames(); foreach (var subID in packageIDs) { IRC.Instance.SendAnnounce("New free license granted: {0}{1}{2} -{3} {4}", Colors.BLUE, Steam.GetPackageName(subID), Colors.NORMAL, Colors.DARKBLUE, SteamDB.GetPackageUrl(subID) ); } }); } }
public override async void OnCommand(CommandArguments command) { uint subID; if (command.Message.Length == 0 || !uint.TryParse(command.Message, out subID)) { CommandHandler.ReplyToCommand(command, "Usage:{0} sub <subid>", Colors.OLIVE); return; } var count = PICSProductInfo.ProcessedSubs.Count; if (count > 100) { CommandHandler.ReplyToCommand(command, "There are currently {0} packages awaiting to be processed, try again later.", count); return; } var job = await Steam.Instance.Apps.PICSGetProductInfo(null, subID, false, false); var callback = job.Results.First(x => !x.ResponsePending); if (!callback.Packages.ContainsKey(subID)) { CommandHandler.ReplyToCommand(command, "Unknown SubID: {0}{1}{2}", Colors.BLUE, subID, LicenseList.OwnedSubs.ContainsKey(subID) ? SteamDB.StringCheckmark : string.Empty); return; } var info = callback.Packages[subID]; info.KeyValues.SaveToFile(Path.Combine(Application.Path, "sub", string.Format("{0}.vdf", info.ID)), false); CommandHandler.ReplyToCommand(command, "{0}{1}{2} -{3} {4}{5} - Dump:{6} {7}{8}{9}{10}", Colors.BLUE, Steam.GetPackageName(info.ID), Colors.NORMAL, Colors.DARKBLUE, SteamDB.GetPackageURL(info.ID), Colors.NORMAL, Colors.DARKBLUE, SteamDB.GetRawPackageURL(info.ID), Colors.NORMAL, info.MissingToken ? SteamDB.StringNeedToken : string.Empty, LicenseList.OwnedSubs.ContainsKey(info.ID) ? SteamDB.StringCheckmark : string.Empty ); }
private static void PrintImportants(SteamApps.PICSChangesCallback callback) { // Apps var important = callback.AppChanges.Keys.Intersect(Application.ImportantApps); foreach (var app in important) { var changeNumber = callback.AppChanges[app].ChangeNumber; TaskManager.Run(async() => await Utils.SendWebhook(new { Type = "ImportantAppUpdate", AppID = app, ChangeNumber = changeNumber, Url = $"{SteamDB.GetAppUrl(app, "history")}?changeid={changeNumber}", })); var appName = Steam.GetAppName(app, out var appType); IRC.Instance.SendAnnounce($"{appType} update: {Colors.BLUE}{appName}{Colors.NORMAL} -{Colors.DARKBLUE} {SteamDB.GetAppUrl(app, "history")}"); } // Packages important = callback.PackageChanges.Keys.Intersect(Application.ImportantSubs); foreach (var package in important) { var changeNumber = callback.PackageChanges[package].ChangeNumber; TaskManager.Run(async() => await Utils.SendWebhook(new { Type = "ImportantSubUpdate", SubID = package, ChangeNumber = changeNumber, Url = $"{SteamDB.GetPackageUrl(package, "history")}?changeid={changeNumber}", })); var subName = Steam.GetPackageName(package); IRC.Instance.SendAnnounce($"Package update: {Colors.BLUE}{subName}{Colors.NORMAL} -{Colors.DARKBLUE} {SteamDB.GetPackageUrl(package, "history")}"); } }
private void OnFreeLicenseCallback(SteamApps.FreeLicenseCallback callback) { JobManager.TryRemoveJob(callback.JobID); var packageIDs = callback.GrantedPackages; var appIDs = callback.GrantedApps; Log.WriteDebug(nameof(FreeLicense), $"Received free license: {callback.Result} ({appIDs.Count} apps: {string.Join(", ", appIDs)}, {packageIDs.Count} packages: {string.Join(", ", packageIDs)})"); if (appIDs.Count > 0) { JobManager.AddJob( () => Steam.Instance.Apps.PICSGetAccessTokens(appIDs, Enumerable.Empty <uint>()), new PICSTokens.RequestedTokens { Apps = appIDs.ToList() }); var removed = false; foreach (var appid in appIDs) { if (FreeLicensesToRequest.Remove(appid)) { removed = true; } } if (removed) { TaskManager.Run(Save); } } if (packageIDs.Count > 0) { JobManager.AddJob( () => Steam.Instance.Apps.PICSGetAccessTokens(Enumerable.Empty <uint>(), packageIDs), new PICSTokens.RequestedTokens { Packages = packageIDs.ToList() }); TaskManager.Run(async() => { await RefreshPackageNames(); foreach (var subID in packageIDs) { IRC.Instance.SendAnnounce($"New free license granted: {Colors.BLUE}{Steam.GetPackageName(subID)}{Colors.NORMAL} -{Colors.DARKBLUE} {SteamDB.GetPackageUrl(subID)}"); } }); } }
public override void OnCommand(CommandArguments command) { if (command.CommandType != ECommandType.IRC || !IRC.IsRecipientChannel(command.Recipient)) { CommandHandler.ReplyToCommand(command, "This command is only available in channels."); return; } var channel = command.Recipient; var s = command.Message.Split(' '); var count = s.Length; if (count > 0) { switch (s[0]) { case "reload": { Application.ReloadImportant(command); PICSTokens.Reload(command); FileDownloader.ReloadFileList(); return; } case "add": { if (count < 3) { break; } uint id; if (!uint.TryParse(s[2], out id)) { break; } switch (s[1]) { case "app": { List <string> channels; var exists = Application.ImportantApps.TryGetValue(id, out channels); if (exists && channels.Contains(channel)) { CommandHandler.ReplyToCommand(command, "App {0}{1}{2} ({3}) is already important in {4}{5}{6}.", Colors.BLUE, id, Colors.NORMAL, Steam.GetAppName(id), Colors.BLUE, channel, Colors.NORMAL); } else { if (exists) { Application.ImportantApps[id].Add(channel); } else { Application.ImportantApps.Add(id, new List <string> { channel }); } using (var db = Database.GetConnection()) { db.Execute("INSERT INTO `ImportantApps` (`AppID`, `Channel`) VALUES (@AppID, @Channel)", new { AppID = id, Channel = channel }); } CommandHandler.ReplyToCommand(command, "Marked app {0}{1}{2} ({3}) as important in {4}{5}{6}.", Colors.BLUE, id, Colors.NORMAL, Steam.GetAppName(id), Colors.BLUE, channel, Colors.NORMAL); } return; } case "sub": { if (Application.ImportantSubs.ContainsKey(id)) { CommandHandler.ReplyToCommand(command, "Package {0}{1}{2} ({3}) is already important.", Colors.BLUE, id, Colors.NORMAL, Steam.GetPackageName(id)); } else { Application.ImportantSubs.Add(id, 1); using (var db = Database.GetConnection()) { db.Execute("INSERT INTO `ImportantSubs` (`SubID`) VALUES (@SubID)", new { SubID = id }); } CommandHandler.ReplyToCommand(command, "Marked package {0}{1}{2} ({3}) as important.", Colors.BLUE, id, Colors.NORMAL, Steam.GetPackageName(id)); } return; } } break; } case "remove": { if (count < 3) { break; } uint id; if (!uint.TryParse(s[2], out id)) { break; } switch (s[1]) { case "app": { List <string> channels; if (!Application.ImportantApps.TryGetValue(id, out channels) || !channels.Contains(channel)) { CommandHandler.ReplyToCommand(command, "App {0}{1}{2} ({3}) is not important in {4}{5}{6}.", Colors.BLUE, id, Colors.NORMAL, Steam.GetAppName(id), Colors.BLUE, channel, Colors.NORMAL); } else { if (channels.Count > 1) { Application.ImportantApps[id].Remove(channel); } else { Application.ImportantApps.Remove(id); } using (var db = Database.GetConnection()) { db.Execute("DELETE FROM `ImportantApps` WHERE `AppID` = @AppID AND `Channel` = @Channel", new { AppID = id, Channel = channel }); } CommandHandler.ReplyToCommand(command, "Removed app {0}{1}{2} ({3}) from the important list in {4}{5}{6}.", Colors.BLUE, id, Colors.NORMAL, Steam.GetAppName(id), Colors.BLUE, channel, Colors.NORMAL); } return; } case "sub": { if (!Application.ImportantSubs.ContainsKey(id)) { CommandHandler.ReplyToCommand(command, "Package {0}{1}{2} ({3}) is not important.", Colors.BLUE, id, Colors.NORMAL, Steam.GetPackageName(id)); } else { Application.ImportantSubs.Remove(id); using (var db = Database.GetConnection()) { db.Execute("DELETE FROM `ImportantSubs` WHERE `SubID` = @SubID", new { SubID = id }); } CommandHandler.ReplyToCommand(command, "Removed package {0}{1}{2} ({3}) from the important list.", Colors.BLUE, id, Colors.NORMAL, Steam.GetPackageName(id)); } return; } } break; } case "queue": { if (count < 3) { break; } uint id; if (!uint.TryParse(s[2], out id)) { break; } switch (s[1]) { case "app": { string name; using (var db = Database.GetConnection()) { name = db.ExecuteScalar <string>("SELECT `Name` FROM `Apps` WHERE `AppID` = @AppID", new { AppID = id }); } if (!string.IsNullOrEmpty(name)) { StoreQueue.AddAppToQueue(id); CommandHandler.ReplyToCommand(command, "App {0}{1}{2} ({3}) has been added to the store update queue.", Colors.BLUE, id, Colors.NORMAL, Utils.RemoveControlCharacters(name)); return; } CommandHandler.ReplyToCommand(command, "This app is not in the database."); return; } case "sub": { if (id == 0) { CommandHandler.ReplyToCommand(command, "Sub 0 can not be queued."); return; } string name; using (var db = Database.GetConnection()) { name = db.ExecuteScalar <string>("SELECT `Name` FROM `Subs` WHERE `SubID` = @SubID", new { SubID = id }); } if (!string.IsNullOrEmpty(name)) { StoreQueue.AddPackageToQueue(id); CommandHandler.ReplyToCommand(command, "Package {0}{1}{2} ({3}) has been added to the store update queue.", Colors.BLUE, id, Colors.NORMAL, Utils.RemoveControlCharacters(name)); return; } CommandHandler.ReplyToCommand(command, "This package is not in the database."); return; } } break; } } } CommandHandler.ReplyToCommand(command, "Usage:{0} important reload {1}or{2} important <add/remove/queue> <app/sub> <id>", Colors.OLIVE, Colors.NORMAL, Colors.OLIVE); }
public void OnMessage(CommandArguments command) { var matches = SteamLinkMatch.Matches(command.Message); foreach (Match match in matches) { var page = match.Groups["page"].Value; // Ignore sub pages, easier to do it here rather than in regex if (!string.IsNullOrEmpty(page)) { continue; } var appType = string.Empty; var id = uint.Parse(match.Groups["id"].Value); var isPackage = match.Groups["type"].Value == "sub"; string name; if (isPackage) { name = Steam.GetPackageName(id); } else { App data; using (var db = Database.GetConnection()) { data = db.Query <App>("SELECT `AppID`, `Apps`.`Name`, `LastKnownName`, `AppsTypes`.`DisplayName` as `AppTypeString` FROM `Apps` JOIN `AppsTypes` ON `Apps`.`AppType` = `AppsTypes`.`AppType` WHERE `AppID` = @AppID", new { AppID = id }).SingleOrDefault(); } if (data.AppID == 0) { continue; } name = string.IsNullOrEmpty(data.LastKnownName) ? data.Name : data.LastKnownName; name = Utils.RemoveControlCharacters(name); appType = data.AppTypeString; } if (command.Message.IndexOf(name, StringComparison.CurrentCultureIgnoreCase) >= 0) { continue; } string priceInfo = isPackage ? string.Empty : GetFormattedPrices(id); if (command.CommandType == ECommandType.SteamChatRoom) { Steam.Instance.Friends.SendChatRoomMessage(command.ChatRoomID, EChatEntryType.ChatMsg, string.Format("» {0} {1} — {2}{3}", isPackage ? "Package" : "App", id, Colors.StripColors(name), priceInfo)); continue; } if (!isPackage && command.Recipient == "#steamlug" && (appType == "Game" || appType == "Application")) { using (var db = Database.GetConnection()) { var status = db.ExecuteScalar <string>("SELECT `Status` FROM `LinuxSupport` WHERE `AppID` = @AppID", new { AppID = id }); switch (status) { case "working": priceInfo += " (✓ Confirmed for Linux)"; break; case "beta": priceInfo += " (Has a public Linux βeta)"; break; default: priceInfo += " (✘ Unknown Linux status)"; break; } } } IRC.Instance.SendReply(command.Recipient, string.Format("{0}» {1}{2} {3} —{4} {5}{6}{7}", Colors.OLIVE, Colors.NORMAL, isPackage ? "Package" : appType, id, Colors.BLUE, name, Colors.LIGHTGRAY, priceInfo ), false ); } }
private void PrintImportants(SteamApps.PICSChangesCallback callback) { // Apps var important = callback.AppChanges.Keys.Intersect(Application.ImportantApps.Keys); foreach (var app in important) { var appName = Steam.GetAppName(app, out var appType); IRC.Instance.AnnounceImportantAppUpdate(app, "{0} update: {1}{2}{3} -{4} {5}", appType, Colors.BLUE, appName, Colors.NORMAL, Colors.DARKBLUE, SteamDB.GetAppURL(app, "history")); if (Settings.Current.CanQueryStore) { Steam.Instance.UnifiedMessages.SendMessage("ChatRoom.SendChatMessage#1", new CChatRoom_SendChatMessage_Request { chat_group_id = 1147, chat_id = 10208600, message = $"[Changelist {callback.CurrentChangeNumber}] {appType} update: {appName}\n{SteamDB.GetAppURL(app, "history")}?utm_source=Steam&utm_medium=Steam&utm_campaign=SteamDB%20Group%20Chat" }); } } // Packages important = callback.PackageChanges.Keys.Intersect(Application.ImportantSubs.Keys); foreach (var package in important) { IRC.Instance.AnnounceImportantPackageUpdate(package, "Package update: {0}{1}{2} -{3} {4}", Colors.BLUE, Steam.GetPackageName(package), Colors.NORMAL, Colors.DARKBLUE, SteamDB.GetPackageURL(package, "history")); } }
public void OnMessage(CommandArguments command) { var matches = SteamLinkMatch.Matches(command.Message); foreach (Match match in matches) { var page = match.Groups["page"].Value; // Ignore sub pages, easier to do it here rather than in regex if (!string.IsNullOrEmpty(page)) { continue; } var id = uint.Parse(match.Groups["id"].Value); var isPackage = match.Groups["type"].Value == "sub"; var name = isPackage ? Steam.GetPackageName(id) : Steam.GetAppName(id); if (command.Message.Contains(name)) { continue; } string priceInfo = string.Empty; if (!isPackage) { List <Price> prices; using (var db = Database.GetConnection()) { prices = db.Query <Price>("SELECT `Country`, `PriceFinal`, `PriceDiscount` FROM `Store` WHERE `AppID` = @AppID AND `Country` IN ('us', 'uk', 'it')", new { AppID = id }).ToList(); } if (prices.Any()) { priceInfo = string.Format(" ({0})", string.Join(" / ", prices.Select(x => x.Format()))); } } if (command.CommandType == ECommandType.SteamChatRoom) { Steam.Instance.Friends.SendChatRoomMessage(command.ChatRoomID, EChatEntryType.ChatMsg, string.Format("» {0} {1} — {2}{3}", isPackage ? "Package" : "App", id, Colors.StripColors(name), priceInfo)); } else { IRC.Instance.SendReply(command.Recipient, string.Format("{0}» {1}{2} {3} —{4} {5}{6}{7}", Colors.OLIVE, Colors.NORMAL, isPackage ? "Package" : "App", id, Colors.BLUE, name, Colors.LIGHTGRAY, priceInfo ), false ); } } }
private static void HandlePackageToken(uint id, ulong accessToken) { if (!PackageTokens.TryGetValue(id, out var existingToken)) { PackageTokens.Add(id, accessToken); IRC.Instance.SendOps($"{Colors.GREEN}[Tokens]{Colors.NORMAL} Added a new package token that the bot got itself:{Colors.BLUE} {id} {Colors.NORMAL}({Steam.GetPackageName(id)})"); Log.WriteInfo(nameof(PICSTokens), "New token for subid {0}", id); using var db = Database.Get(); db.Execute("INSERT INTO `PICSTokensSubs` (`SubID`, `Token`) VALUES(@SubID, @Token)", new PICSToken { SubID = id, Token = accessToken } ); } else if (existingToken != accessToken) { Log.WriteWarn(nameof(PICSTokens), $"New token for subid {id} that mismatches the existing one ({existingToken} != {accessToken})"); IRC.Instance.SendOps($"{Colors.RED}[Tokens] Bot got a package token that mismatches the one in database:{Colors.BLUE} {id} ({existingToken} != {accessToken})"); PackageTokens[id] = accessToken; using var db = Database.Get(); db.Execute("UPDATE `PICSTokensSubs` SET `Token` = @Token WHERE `SubID` = @SubID", new PICSToken { SubID = id, Token = accessToken } ); } }
public override async Task OnCommand(CommandArguments command) { var s = command.Message.Split(' '); if (s.Length < 2) { command.Reply("Usage:{0} queue <app/sub> <id>", Colors.OLIVE); return; } if (!uint.TryParse(s[1], out var id)) { command.Reply("Your ID does not look like a number."); return; } switch (s[0]) { case "app": var appName = Steam.GetAppName(id); if (!string.IsNullOrEmpty(appName)) { await StoreQueue.AddAppToQueue(id); command.Reply("App {0}{1}{2} ({3}) has been added to the store update queue.", Colors.BLUE, id, Colors.NORMAL, appName); return; } command.Reply("This app is not in the database."); return; case "package": case "sub": if (id == 0) { command.Reply("Sub 0 can not be queued."); return; } var subName = Steam.GetPackageName(id); if (!string.IsNullOrEmpty(subName)) { await StoreQueue.AddPackageToQueue(id); command.Reply("Package {0}{1}{2} ({3}) has been added to the store update queue.", Colors.BLUE, id, Colors.NORMAL, subName); return; } command.Reply("This package is not in the database."); return; default: command.Reply("You can only queue apps and packages."); return; } }
public void OnMessage(CommandArguments command) { var matches = SteamLinkMatch.Matches(command.Message); foreach (Match match in matches) { var page = match.Groups["page"].Value; // Ignore sub pages, easier to do it here rather than in regex if (!string.IsNullOrEmpty(page)) { continue; } var appType = string.Empty; var id = uint.Parse(match.Groups["id"].Value); var isPackage = match.Groups["type"].Value == "sub"; var name = isPackage ? Steam.GetPackageName(id) : Steam.GetAppName(id, out appType); if (command.Message.Contains(name)) { continue; } string priceInfo = isPackage ? string.Empty : GetFormattedPrices(id); if (command.CommandType == ECommandType.SteamChatRoom) { Steam.Instance.Friends.SendChatRoomMessage(command.ChatRoomID, EChatEntryType.ChatMsg, string.Format("» {0} {1} — {2}{3}", isPackage ? "Package" : "App", id, Colors.StripColors(name), priceInfo)); continue; } if (!isPackage && command.Recipient == "#steamlug" && (appType == "Game" || appType == "Application")) { using (var db = Database.GetConnection()) { var status = db.ExecuteScalar <string>("SELECT `Status` FROM `LinuxSupport` WHERE `AppID` = @AppID", new { AppID = id }); switch (status) { case "working": priceInfo += " (✓ Confirmed for Linux)"; break; case "beta": priceInfo += " (Has a public Linux βeta)"; break; default: priceInfo += " (✘ Unknown Linux status)"; break; } } } IRC.Instance.SendReply(command.Recipient, string.Format("{0}» {1}{2} {3} —{4} {5}{6}{7}", Colors.OLIVE, Colors.NORMAL, isPackage ? "Package" : "App", id, Colors.BLUE, name, Colors.LIGHTGRAY, priceInfo ), false ); } }
private void PrintImportants(SteamApps.PICSChangesCallback callback) { // Apps var important = callback.AppChanges.Keys.Intersect(Application.ImportantApps.Keys); string appType; string appName; foreach (var app in important) { appName = Steam.GetAppName(app, out appType); IRC.Instance.AnnounceImportantAppUpdate(app, "{0} update: {1}{2}{3} -{4} {5}", appType, Colors.BLUE, appName, Colors.NORMAL, Colors.DARKBLUE, SteamDB.GetAppURL(app, "history")); } // Packages important = callback.PackageChanges.Keys.Intersect(Application.ImportantSubs.Keys); foreach (var package in important) { IRC.Instance.AnnounceImportantPackageUpdate(package, "Package update: {0}{1}{2} -{3} {4}", Colors.BLUE, Steam.GetPackageName(package), Colors.NORMAL, Colors.DARKBLUE, SteamDB.GetPackageURL(package, "history")); } }
private static void HandlePackageToken(uint id, ulong accessToken) { if (!PackageTokens.ContainsKey(id)) { PackageTokens.Add(id, accessToken); IRC.Instance.SendOps($"{Colors.GREEN}[Tokens]{Colors.NORMAL} Added a new package token that the bot got itself:{Colors.BLUE} {id} {Colors.NORMAL}({Steam.GetPackageName(id)})"); Log.WriteInfo(nameof(PICSTokens), "New token for subid {0}", id); using var db = Database.Get(); db.Execute("INSERT INTO `PICSTokensSubs` (`SubID`, `Token`) VALUES(@SubID, @Token)", new PICSToken { SubID = id, Token = accessToken } ); } else if (PackageTokens[id] != accessToken) { IRC.Instance.SendOps($"{Colors.GREEN}[Tokens]{Colors.NORMAL} Bot got a package token that mismatches the one in database: {PackageTokens[id]} != {accessToken}"); } }
public override async Task OnCommand(CommandArguments command) { var s = command.Message.Split(' '); var count = s.Length; if (count > 0) { uint id; switch (s[0]) { case "reload": await Application.ReloadImportant(); await PICSTokens.Reload(); command.Notice("Reloaded important apps and pics tokens"); return; case "fullrun": _ = TaskManager.Run(async() => { command.Reply("Started full metadata scan, this will take a while…"); await FullUpdateProcessor.FullUpdateAppsMetadata(true); command.Reply("App full scan finished, starting packages, this will take even longer…"); await FullUpdateProcessor.FullUpdatePackagesMetadata(); command.Reply("Full metadata scan finished."); }); return; case "add": if (count < 3) { break; } if (!uint.TryParse(s[2], out id)) { break; } switch (s[1]) { case "app": if (Application.ImportantApps.Contains(id)) { command.Reply($"App {Colors.BLUE}{id}{Colors.NORMAL} ({Steam.GetAppName(id)}) is already important."); } else { Application.ImportantApps.Add(id); await using (var db = await Database.GetConnectionAsync()) { await db.ExecuteAsync("INSERT INTO `ImportantApps` (`AppID`) VALUES (@AppID)", new { AppID = id }); } command.Reply($"Marked app {Colors.BLUE}{id}{Colors.NORMAL} ({Steam.GetAppName(id)}) as important."); } return; case "sub": if (Application.ImportantSubs.Contains(id)) { command.Reply($"Package {Colors.BLUE}{id}{Colors.NORMAL} ({Steam.GetPackageName(id)}) is already important."); } else { Application.ImportantSubs.Add(id); await using (var db = await Database.GetConnectionAsync()) { await db.ExecuteAsync("INSERT INTO `ImportantSubs` (`SubID`) VALUES (@SubID)", new { SubID = id }); } command.Reply($"Marked package {Colors.BLUE}{id}{Colors.NORMAL} ({Steam.GetPackageName(id)}) as important."); } return; } break; case "remove": if (count < 3) { break; } if (!uint.TryParse(s[2], out id)) { break; } switch (s[1]) { case "app": if (!Application.ImportantApps.Contains(id)) { command.Reply($"App {Colors.BLUE}{id}{Colors.NORMAL} ({Steam.GetAppName(id)}) is not important."); } else { Application.ImportantApps.Remove(id); await using (var db = await Database.GetConnectionAsync()) { await db.ExecuteAsync("DELETE FROM `ImportantApps` WHERE `AppID` = @AppID", new { AppID = id }); } command.Reply($"Removed app {Colors.BLUE}{id}{Colors.NORMAL} ({Steam.GetAppName(id)}) from the important list."); } return; case "sub": if (!Application.ImportantSubs.Contains(id)) { command.Reply($"Package {Colors.BLUE}{id}{Colors.NORMAL} ({Steam.GetPackageName(id)}) is not important."); } else { Application.ImportantSubs.Remove(id); await using (var db = await Database.GetConnectionAsync()) { await db.ExecuteAsync("DELETE FROM `ImportantSubs` WHERE `SubID` = @SubID", new { SubID = id }); } command.Reply($"Removed package {Colors.BLUE}{id}{Colors.NORMAL} ({Steam.GetPackageName(id)}) from the important list."); } return; } break; } } command.Reply($"Usage:{Colors.OLIVE} important reload {Colors.NORMAL}or{Colors.OLIVE} important <add/remove> <app/sub> <id> {Colors.NORMAL}or{Colors.OLIVE} important fullrun"); }
public override async Task OnCommand(CommandArguments command) { if (command.CommandType != ECommandType.IRC || !IRC.IsRecipientChannel(command.Recipient)) { command.Reply("This command is only available in channels."); return; } var channel = command.Recipient; var s = command.Message.Split(' '); var count = s.Length; if (count > 0) { uint id; switch (s[0]) { case "reload": await Application.ReloadImportant(command); PICSTokens.Reload(command); return; case "add": if (count < 3) { break; } if (!uint.TryParse(s[2], out id)) { break; } switch (s[1]) { case "app": var exists = Application.ImportantApps.TryGetValue(id, out var channels); if (exists && channels.Contains(channel)) { command.Reply($"App {Colors.BLUE}{id}{Colors.NORMAL} ({Steam.GetAppName(id)}) is already important in {Colors.BLUE}{channel}{Colors.NORMAL}."); } else { if (exists) { Application.ImportantApps[id].Add(channel); } else { Application.ImportantApps.Add(id, new List <string> { channel }); } await using (var db = await Database.GetConnectionAsync()) { await db.ExecuteAsync("INSERT INTO `ImportantApps` (`AppID`, `Channel`) VALUES (@AppID, @Channel)", new { AppID = id, Channel = channel }); } command.Reply($"Marked app {Colors.BLUE}{id}{Colors.NORMAL} ({Steam.GetAppName(id)}) as important in {Colors.BLUE}{channel}{Colors.NORMAL}."); } return; case "sub": if (Application.ImportantSubs.ContainsKey(id)) { command.Reply($"Package {Colors.BLUE}{id}{Colors.NORMAL} ({Steam.GetPackageName(id)}) is already important."); } else { Application.ImportantSubs.Add(id, 1); await using (var db = await Database.GetConnectionAsync()) { await db.ExecuteAsync("INSERT INTO `ImportantSubs` (`SubID`) VALUES (@SubID)", new { SubID = id }); } command.Reply($"Marked package {Colors.BLUE}{id}{Colors.NORMAL} ({Steam.GetPackageName(id)}) as important."); } return; } break; case "remove": if (count < 3) { break; } if (!uint.TryParse(s[2], out id)) { break; } switch (s[1]) { case "app": if (!Application.ImportantApps.TryGetValue(id, out var channels) || !channels.Contains(channel)) { command.Reply($"App {Colors.BLUE}{id}{Colors.NORMAL} ({Steam.GetAppName(id)}) is not important in {Colors.BLUE}{channel}{Colors.NORMAL}."); } else { if (channels.Count > 1) { Application.ImportantApps[id].Remove(channel); } else { Application.ImportantApps.Remove(id); } await using (var db = await Database.GetConnectionAsync()) { await db.ExecuteAsync("DELETE FROM `ImportantApps` WHERE `AppID` = @AppID AND `Channel` = @Channel", new { AppID = id, Channel = channel }); } command.Reply($"Removed app {Colors.BLUE}{id}{Colors.NORMAL} ({Steam.GetAppName(id)}) from the important list in {Colors.BLUE}{channel}{Colors.NORMAL}."); } return; case "sub": if (!Application.ImportantSubs.ContainsKey(id)) { command.Reply($"Package {Colors.BLUE}{id}{Colors.NORMAL} ({Steam.GetPackageName(id)}) is not important."); } else { Application.ImportantSubs.Remove(id); await using (var db = await Database.GetConnectionAsync()) { await db.ExecuteAsync("DELETE FROM `ImportantSubs` WHERE `SubID` = @SubID", new { SubID = id }); } command.Reply($"Removed package {Colors.BLUE}{id}{Colors.NORMAL} ({Steam.GetPackageName(id)}) from the important list."); } return; } break; } } command.Reply($"Usage:{Colors.OLIVE} important reload {Colors.NORMAL}or{Colors.OLIVE} important <add/remove> <app/sub> <id>"); }
public override async Task OnCommand(CommandArguments command) { await Task.Yield(); if (command.CommandType != ECommandType.IRC || !IRC.IsRecipientChannel(command.Recipient)) { command.Reply("This command is only available in channels."); return; } var channel = command.Recipient; var s = command.Message.Split(' '); var count = s.Length; uint id; if (count > 0) { switch (s[0]) { case "reload": Application.ReloadImportant(command); PICSTokens.Reload(command); FileDownloader.ReloadFileList(); return; case "add": if (count < 3) { break; } if (!uint.TryParse(s[2], out id)) { break; } switch (s[1]) { case "app": List <string> channels; var exists = Application.ImportantApps.TryGetValue(id, out channels); if (exists && channels.Contains(channel)) { command.Reply("App {0}{1}{2} ({3}) is already important in {4}{5}{6}.", Colors.BLUE, id, Colors.NORMAL, Steam.GetAppName(id), Colors.BLUE, channel, Colors.NORMAL); } else { if (exists) { Application.ImportantApps[id].Add(channel); } else { Application.ImportantApps.Add(id, new List <string> { channel }); } using (var db = Database.GetConnection()) { db.Execute("INSERT INTO `ImportantApps` (`AppID`, `Channel`) VALUES (@AppID, @Channel)", new { AppID = id, Channel = channel }); } command.Reply("Marked app {0}{1}{2} ({3}) as important in {4}{5}{6}.", Colors.BLUE, id, Colors.NORMAL, Steam.GetAppName(id), Colors.BLUE, channel, Colors.NORMAL); } return; case "sub": if (Application.ImportantSubs.ContainsKey(id)) { command.Reply("Package {0}{1}{2} ({3}) is already important.", Colors.BLUE, id, Colors.NORMAL, Steam.GetPackageName(id)); } else { Application.ImportantSubs.Add(id, 1); using (var db = Database.GetConnection()) { db.Execute("INSERT INTO `ImportantSubs` (`SubID`) VALUES (@SubID)", new { SubID = id }); } command.Reply("Marked package {0}{1}{2} ({3}) as important.", Colors.BLUE, id, Colors.NORMAL, Steam.GetPackageName(id)); } return; } break; case "remove": if (count < 3) { break; } if (!uint.TryParse(s[2], out id)) { break; } switch (s[1]) { case "app": List <string> channels; if (!Application.ImportantApps.TryGetValue(id, out channels) || !channels.Contains(channel)) { command.Reply("App {0}{1}{2} ({3}) is not important in {4}{5}{6}.", Colors.BLUE, id, Colors.NORMAL, Steam.GetAppName(id), Colors.BLUE, channel, Colors.NORMAL); } else { if (channels.Count > 1) { Application.ImportantApps[id].Remove(channel); } else { Application.ImportantApps.Remove(id); } using (var db = Database.GetConnection()) { db.Execute("DELETE FROM `ImportantApps` WHERE `AppID` = @AppID AND `Channel` = @Channel", new { AppID = id, Channel = channel }); } command.Reply("Removed app {0}{1}{2} ({3}) from the important list in {4}{5}{6}.", Colors.BLUE, id, Colors.NORMAL, Steam.GetAppName(id), Colors.BLUE, channel, Colors.NORMAL); } return; case "sub": if (!Application.ImportantSubs.ContainsKey(id)) { command.Reply("Package {0}{1}{2} ({3}) is not important.", Colors.BLUE, id, Colors.NORMAL, Steam.GetPackageName(id)); } else { Application.ImportantSubs.Remove(id); using (var db = Database.GetConnection()) { db.Execute("DELETE FROM `ImportantSubs` WHERE `SubID` = @SubID", new { SubID = id }); } command.Reply("Removed package {0}{1}{2} ({3}) from the important list.", Colors.BLUE, id, Colors.NORMAL, Steam.GetPackageName(id)); } return; } break; } } command.Reply("Usage:{0} important reload {1}or{2} important <add/remove> <app/sub> <id>", Colors.OLIVE, Colors.NORMAL, Colors.OLIVE); }
public void OnMessage(CommandArguments command) { var matches = SteamLinkMatch.Matches(command.Message); foreach (Match match in matches) { var page = match.Groups["page"].Value; // Ignore sub pages, easier to do it here rather than in regex if (!string.IsNullOrEmpty(page)) { continue; } var appType = string.Empty; var id = uint.Parse(match.Groups["id"].Value); var isPackage = match.Groups["type"].Value == "sub"; string name; if (isPackage) { name = Steam.GetPackageName(id); } else { App data; using (var db = Database.Get()) { data = db.Query <App>("SELECT `AppID`, `Apps`.`Name`, `LastKnownName`, `AppsTypes`.`DisplayName` as `AppTypeString` FROM `Apps` JOIN `AppsTypes` ON `Apps`.`AppType` = `AppsTypes`.`AppType` WHERE `AppID` = @AppID", new { AppID = id }).SingleOrDefault(); } if (data.AppID == 0) { continue; } name = string.IsNullOrEmpty(data.LastKnownName) ? data.Name : data.LastKnownName; name = Utils.RemoveControlCharacters(name); appType = data.AppTypeString; } if (command.Message.IndexOf(name, StringComparison.CurrentCultureIgnoreCase) >= 0) { continue; } string priceInfo = isPackage ? string.Empty : GetFormattedPrices(id); IRC.Instance.SendReply(command.Recipient, string.Format("{0}» {1}{2} {3} —{4} {5}{6}{7}", Colors.OLIVE, Colors.NORMAL, isPackage ? "Package" : appType, id, Colors.BLUE, name, Colors.LIGHTGRAY, priceInfo ), false ); } }
private static void OnPICSProductInfo(SteamApps.PICSProductInfoCallback callback) { JobAction job; if (!JobManager.TryRemoveJob(callback.JobID, out job) || !job.IsCommand) { return; } var request = job.CommandRequest; if (request.Type == JobManager.IRCRequestType.TYPE_SUB) { if (!callback.Packages.ContainsKey(request.Target)) { CommandHandler.ReplyToCommand(request.Command, "Unknown SubID: {0}{1}{2}", Colors.BLUE, request.Target, LicenseList.OwnedSubs.ContainsKey(request.Target) ? SteamDB.StringCheckmark : string.Empty); return; } var info = callback.Packages[request.Target]; var kv = info.KeyValues.Children.FirstOrDefault(); string name; if (kv["name"].Value != null) { name = Utils.RemoveControlCharacters(kv["name"].AsString()); } else { name = Steam.GetPackageName(info.ID); } try { kv.SaveToFile(Path.Combine(Application.Path, "sub", string.Format("{0}.vdf", info.ID)), false); } catch (Exception e) { CommandHandler.ReplyToCommand(request.Command, "Unable to save file for {0}: {1}", name, e.Message); return; } CommandHandler.ReplyToCommand(request.Command, "{0}{1}{2} -{3} {4}{5} - Dump:{6} {7}{8}{9}{10}", Colors.BLUE, name, Colors.NORMAL, Colors.DARKBLUE, SteamDB.GetPackageURL(info.ID), Colors.NORMAL, Colors.DARKBLUE, SteamDB.GetRawPackageURL(info.ID), Colors.NORMAL, info.MissingToken ? SteamDB.StringNeedToken : string.Empty, LicenseList.OwnedSubs.ContainsKey(info.ID) ? SteamDB.StringCheckmark : string.Empty ); } else if (request.Type == JobManager.IRCRequestType.TYPE_APP) { if (!callback.Apps.ContainsKey(request.Target)) { CommandHandler.ReplyToCommand(request.Command, "Unknown AppID: {0}{1}{2}", Colors.BLUE, request.Target, LicenseList.OwnedApps.ContainsKey(request.Target) ? SteamDB.StringCheckmark : string.Empty); return; } var info = callback.Apps[request.Target]; string name; if (info.KeyValues["common"]["name"].Value != null) { name = Utils.RemoveControlCharacters(info.KeyValues["common"]["name"].AsString()); } else { name = Steam.GetAppName(info.ID); } try { info.KeyValues.SaveToFile(Path.Combine(Application.Path, "app", string.Format("{0}.vdf", info.ID)), false); } catch (Exception e) { CommandHandler.ReplyToCommand(request.Command, "Unable to save file for {0}: {1}", name, e.Message); return; } CommandHandler.ReplyToCommand(request.Command, "{0}{1}{2} -{3} {4}{5} - Dump:{6} {7}{8}{9}{10}", Colors.BLUE, name, Colors.NORMAL, Colors.DARKBLUE, SteamDB.GetAppURL(info.ID), Colors.NORMAL, Colors.DARKBLUE, SteamDB.GetRawAppURL(info.ID), Colors.NORMAL, info.MissingToken ? SteamDB.StringNeedToken : string.Empty, LicenseList.OwnedApps.ContainsKey(info.ID) ? SteamDB.StringCheckmark : string.Empty ); } else { CommandHandler.ReplyToCommand(request.Command, "I have no idea what happened here!"); } }