Compare commits

..

15 Commits

Author SHA1 Message Date
JustArchi
50b5c7b87f Correct STM algorithm when overpaying with cards from the same game
us: X X Y
them: Y Y Z

trade:
Y -> X + Z

New:
toGive: 1
toReceive: 2 + 0 -> 0 + 2

diff: 1 - 0 = 1
1 > 0 ? True

Old:
toGive: 1
toReceive: 2

1 > 2 ? False
2016-05-13 01:35:17 +02:00
JustArchi
b60448ef4c Bump 2016-05-12 19:00:26 +02:00
JustArchi
fad08a1fa9 Fix linking new authenticator with null password 2016-05-12 16:32:04 +02:00
JustArchi
a180c100c6 Make use of CellID, closes #223 2016-05-08 15:52:57 +02:00
JustArchi
9d97ca16e8 Misc WCF code review 2016-05-07 15:24:09 +02:00
JustArchi
e833415718 Closes #221 2016-05-07 15:08:24 +02:00
JustArchi
6bb296a674 Bump 2016-05-06 23:58:50 +02:00
JustArchi
f1e5874868 Misc 2016-05-06 23:54:47 +02:00
JustArchi
38e2088d09 Misc 2016-05-06 23:48:33 +02:00
JustArchi
8447e07aa0 Allow overpaying also in steam cards 2016-05-06 23:38:22 +02:00
JustArchi
fbe4e4bc6d Allow STM overpaying 2016-05-06 23:31:00 +02:00
JustArchi
f1213607ce Don't react in any way to failed commands sent by non-owner 2016-05-06 18:07:03 +02:00
JustArchi
de832c530b Misc 2016-05-04 16:43:16 +02:00
JustArchi
0c872b17e2 Misc 2016-05-04 16:41:00 +02:00
JustArchi
5fcbb85b4c Bump 2016-05-03 15:54:26 +02:00
6 changed files with 146 additions and 94 deletions

View File

@@ -393,8 +393,6 @@ namespace ArchiSteamFarm {
}
case "!farm":
return ResponseFarm(steamID, args[1]);
case "!help":
return ResponseHelp(steamID, args[1]);
case "!loot":
return await ResponseSendTrade(steamID, args[1]).ConfigureAwait(false);
case "!owns":
@@ -487,7 +485,7 @@ namespace ArchiSteamFarm {
// But here we're dealing with WinAuth authenticator
Logging.LogGenericInfo("ASF requires a few more steps to complete authenticator import...", BotName);
if (!InitializeLoginAndPassword()) {
if (!InitializeLoginAndPassword(true)) {
BotDatabase.SteamGuardAccount = null;
return;
}
@@ -548,7 +546,11 @@ namespace ArchiSteamFarm {
Bot bot;
if (!Bots.TryGetValue(botName, out bot)) {
return "Couldn't find any bot named " + botName + "!";
if (IsOwner(steamID)) {
return "Couldn't find any bot named " + botName + "!";
} else {
return null;
}
}
return await bot.ResponsePause(steamID).ConfigureAwait(false);
@@ -579,7 +581,11 @@ namespace ArchiSteamFarm {
Bot bot;
if (!Bots.TryGetValue(botName, out bot)) {
return "Couldn't find any bot named " + botName + "!";
if (IsOwner(steamID)) {
return "Couldn't find any bot named " + botName + "!";
} else {
return null;
}
}
return bot.ResponseStatus(steamID);
@@ -647,7 +653,11 @@ namespace ArchiSteamFarm {
Bot bot;
if (!Bots.TryGetValue(botName, out bot)) {
return "Couldn't find any bot named " + botName + "!";
if (IsOwner(steamID)) {
return "Couldn't find any bot named " + botName + "!";
} else {
return null;
}
}
return await bot.ResponseSendTrade(steamID).ConfigureAwait(false);
@@ -673,7 +683,11 @@ namespace ArchiSteamFarm {
Bot bot;
if (!Bots.TryGetValue(botName, out bot)) {
return "Couldn't find any bot named " + botName + "!";
if (IsOwner(steamID)) {
return "Couldn't find any bot named " + botName + "!";
} else {
return null;
}
}
return bot.Response2FA(steamID);
@@ -702,7 +716,11 @@ namespace ArchiSteamFarm {
Bot bot;
if (!Bots.TryGetValue(botName, out bot)) {
return "Couldn't find any bot named " + botName + "!";
if (IsOwner(steamID)) {
return "Couldn't find any bot named " + botName + "!";
} else {
return null;
}
}
return bot.Response2FAOff(steamID);
@@ -728,7 +746,11 @@ namespace ArchiSteamFarm {
Bot bot;
if (!Bots.TryGetValue(botName, out bot)) {
return "Couldn't find any bot named " + botName + "!";
if (IsOwner(steamID)) {
return "Couldn't find any bot named " + botName + "!";
} else {
return null;
}
}
return await bot.Response2FAConfirm(steamID, confirm).ConfigureAwait(false);
@@ -772,7 +794,11 @@ namespace ArchiSteamFarm {
Bot bot;
if (!Bots.TryGetValue(botName, out bot)) {
return "Couldn't find any bot named " + botName + "!";
if (IsOwner(steamID)) {
return "Couldn't find any bot named " + botName + "!";
} else {
return null;
}
}
return bot.ResponseFarm(steamID);
@@ -786,19 +812,6 @@ namespace ArchiSteamFarm {
return "https://github.com/" + Program.GithubRepo + "/wiki/Commands";
}
private static string ResponseHelp(ulong steamID, string botName) {
if (steamID == 0 || string.IsNullOrEmpty(botName)) {
return null;
}
Bot bot;
if (!Bots.TryGetValue(botName, out bot)) {
return "Couldn't find any bot named " + botName + "!";
}
return bot.ResponseHelp(steamID);
}
private async Task<string> ResponseRedeem(ulong steamID, string message, bool validate) {
if (steamID == 0 || string.IsNullOrEmpty(message) || !IsMaster(steamID)) {
return null;
@@ -908,7 +921,11 @@ namespace ArchiSteamFarm {
Bot bot;
if (!Bots.TryGetValue(botName, out bot)) {
return "Couldn't find any bot named " + botName + "!";
if (IsOwner(steamID)) {
return "Couldn't find any bot named " + botName + "!";
} else {
return null;
}
}
return await bot.ResponseRedeem(steamID, message, validate).ConfigureAwait(false);
@@ -949,7 +966,7 @@ namespace ArchiSteamFarm {
}
private async Task<string> ResponseAddLicense(ulong steamID, HashSet<uint> gameIDs) {
if (steamID == 0 || gameIDs == null || gameIDs.Count == 0 || !IsMaster(steamID)) {
if (steamID == 0 || gameIDs == null || gameIDs.Count == 0 || !SteamClient.IsConnected || !IsMaster(steamID)) {
return null;
}
@@ -973,17 +990,26 @@ namespace ArchiSteamFarm {
Bot bot;
if (!Bots.TryGetValue(botName, out bot)) {
return "Couldn't find any bot named " + botName + "!";
if (IsOwner(steamID)) {
return "Couldn't find any bot named " + botName + "!";
} else {
return null;
}
}
string[] gameIDs = games.Split(',');
string[] gameIDs = games.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
HashSet<uint> gamesToRedeem = new HashSet<uint>();
foreach (string game in gameIDs) {
if (string.IsNullOrEmpty(game)) {
continue;
}
uint gameID;
if (!uint.TryParse(game, out gameID)) {
continue;
}
gamesToRedeem.Add(gameID);
}
@@ -1012,8 +1038,12 @@ namespace ArchiSteamFarm {
StringBuilder response = new StringBuilder();
string[] games = query.Split(',');
string[] games = query.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
foreach (string game in games) {
if (string.IsNullOrEmpty(game)) {
continue;
}
// Check if this is appID
uint appID;
if (uint.TryParse(game, out appID)) {
@@ -1051,7 +1081,11 @@ namespace ArchiSteamFarm {
Bot bot;
if (!Bots.TryGetValue(botName, out bot)) {
return "Couldn't find any bot named " + botName + "!";
if (IsOwner(steamID)) {
return "Couldn't find any bot named " + botName + "!";
} else {
return null;
}
}
return await bot.ResponseOwns(steamID, query).ConfigureAwait(false);
@@ -1084,17 +1118,26 @@ namespace ArchiSteamFarm {
Bot bot;
if (!Bots.TryGetValue(botName, out bot)) {
return "Couldn't find any bot named " + botName + "!";
if (IsOwner(steamID)) {
return "Couldn't find any bot named " + botName + "!";
} else {
return null;
}
}
string[] gameIDs = games.Split(',');
string[] gameIDs = games.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
HashSet<uint> gamesToPlay = new HashSet<uint>();
foreach (string game in gameIDs) {
if (string.IsNullOrEmpty(game)) {
continue;
}
uint gameID;
if (!uint.TryParse(game, out gameID)) {
continue;
}
gamesToPlay.Add(gameID);
}
@@ -1125,7 +1168,11 @@ namespace ArchiSteamFarm {
Bot bot;
if (!Bots.TryGetValue(botName, out bot)) {
return "Couldn't find any bot named " + botName + "!";
if (IsOwner(steamID)) {
return "Couldn't find any bot named " + botName + "!";
} else {
return null;
}
}
return await bot.ResponseStart(steamID).ConfigureAwait(false);
@@ -1151,7 +1198,11 @@ namespace ArchiSteamFarm {
Bot bot;
if (!Bots.TryGetValue(botName, out bot)) {
return "Couldn't find any bot named " + botName + "!";
if (IsOwner(steamID)) {
return "Couldn't find any bot named " + botName + "!";
} else {
return null;
}
}
return bot.ResponseStop(steamID);
@@ -1210,7 +1261,7 @@ namespace ArchiSteamFarm {
}
private void SendMessageToChannel(ulong steamID, string message) {
if (steamID == 0 || string.IsNullOrEmpty(message)) {
if (steamID == 0 || string.IsNullOrEmpty(message) || !SteamClient.IsConnected) {
return;
}
@@ -1221,7 +1272,7 @@ namespace ArchiSteamFarm {
}
private void SendMessageToUser(ulong steamID, string message) {
if (steamID == 0 || string.IsNullOrEmpty(message)) {
if (steamID == 0 || string.IsNullOrEmpty(message) || !SteamClient.IsConnected) {
return;
}
@@ -1238,7 +1289,7 @@ namespace ArchiSteamFarm {
Logging.LogGenericInfo("Linking new ASF MobileAuthenticator...", BotName);
if (!InitializeLoginAndPassword()) {
if (!InitializeLoginAndPassword(true)) {
return;
}
@@ -1324,14 +1375,14 @@ namespace ArchiSteamFarm {
}
private void JoinMasterChat() {
if (BotConfig.SteamMasterClanID == 0) {
if (!SteamClient.IsConnected || BotConfig.SteamMasterClanID == 0) {
return;
}
SteamFriends.JoinChat(BotConfig.SteamMasterClanID);
}
private bool InitializeLoginAndPassword() {
private bool InitializeLoginAndPassword(bool requiresPassword) {
if (string.IsNullOrEmpty(BotConfig.SteamLogin)) {
BotConfig.SteamLogin = Program.GetUserInput(Program.EUserInputType.Login, BotName);
if (string.IsNullOrEmpty(BotConfig.SteamLogin)) {
@@ -1339,7 +1390,7 @@ namespace ArchiSteamFarm {
}
}
if (string.IsNullOrEmpty(BotConfig.SteamPassword) && string.IsNullOrEmpty(BotDatabase.LoginKey)) {
if (string.IsNullOrEmpty(BotConfig.SteamPassword) && (requiresPassword || string.IsNullOrEmpty(BotDatabase.LoginKey))) {
BotConfig.SteamPassword = Program.GetUserInput(Program.EUserInputType.Password, BotName);
if (string.IsNullOrEmpty(BotConfig.SteamPassword)) {
return false;
@@ -1377,7 +1428,7 @@ namespace ArchiSteamFarm {
}
}
if (!InitializeLoginAndPassword()) {
if (!InitializeLoginAndPassword(false)) {
Stop();
return;
}
@@ -1396,6 +1447,7 @@ namespace ArchiSteamFarm {
Username = BotConfig.SteamLogin,
Password = BotConfig.SteamPassword,
AuthCode = AuthCode,
CellID = Program.GlobalDatabase.CellID,
LoginID = LoginID,
LoginKey = BotDatabase.LoginKey,
TwoFactorCode = TwoFactorCode,
@@ -1409,6 +1461,7 @@ namespace ArchiSteamFarm {
Username = BotConfig.SteamLogin,
Password = BotConfig.SteamPassword,
AuthCode = AuthCode,
CellID = Program.GlobalDatabase.CellID,
LoginID = LoginID,
LoginKey = BotDatabase.LoginKey,
TwoFactorCode = TwoFactorCode,

View File

@@ -249,23 +249,17 @@ namespace ArchiSteamFarm {
}
}
internal bool IsSteamCardsOnlyTrade() {
internal bool IsSteamCardsOnlyTradeForUs() {
foreach (Item item in ItemsToGive) {
if (item.AppID != Item.SteamAppID || item.ContextID != Item.SteamContextID || (item.Type != Item.EType.FoilTradingCard && item.Type != Item.EType.TradingCard)) {
return false;
}
}
foreach (Item item in ItemsToReceive) {
if (item.AppID != Item.SteamAppID || item.ContextID != Item.SteamContextID || (item.Type != Item.EType.FoilTradingCard && item.Type != Item.EType.TradingCard)) {
return false;
}
}
return true;
}
internal bool IsPotentiallyDupesTrade() {
internal bool IsPotentiallyDupesTradeForUs() {
Dictionary<uint, Dictionary<Item.EType, uint>> ItemsToGivePerGame = new Dictionary<uint, Dictionary<Item.EType, uint>>();
foreach (Item item in ItemsToGive) {
Dictionary<Item.EType, uint> ItemsPerType;
@@ -300,7 +294,7 @@ namespace ArchiSteamFarm {
}
}
// Ensure that amount per type and per game matches
// Ensure that amount of items to give is at least amount of items to receive (per game and per type)
foreach (KeyValuePair<uint, Dictionary<Item.EType, uint>> ItemsPerGame in ItemsToGivePerGame) {
Dictionary<Item.EType, uint> otherItemsPerType;
if (!ItemsToReceivePerGame.TryGetValue(ItemsPerGame.Key, out otherItemsPerType)) {
@@ -313,7 +307,7 @@ namespace ArchiSteamFarm {
return false;
}
if (ItemsPerType.Value != otherAmount) {
if (ItemsPerType.Value > otherAmount) {
return false;
}
}

View File

@@ -38,16 +38,21 @@ namespace ArchiSteamFarm {
if (LogToFile) {
lock (FileLock) {
if (!LogToFile) {
return;
}
try {
File.Delete(Program.LogFile);
} catch (Exception e) {
LogToFile = false;
LogGenericException(e);
}
}
}
}
internal static void LogGenericWTF(string message, string botName = "Main", [CallerMemberName] string previousMethodName = "") {
internal static void LogGenericWTF(string message, string botName = "Main", [CallerMemberName] string previousMethodName = null) {
if (string.IsNullOrEmpty(message)) {
return;
}
@@ -55,7 +60,7 @@ namespace ArchiSteamFarm {
Log("[!!] WTF: " + previousMethodName + "() <" + botName + "> " + message + ", WTF?");
}
internal static void LogGenericError(string message, string botName = "Main", [CallerMemberName] string previousMethodName = "") {
internal static void LogGenericError(string message, string botName = "Main", [CallerMemberName] string previousMethodName = null) {
if (string.IsNullOrEmpty(message)) {
return;
}
@@ -63,7 +68,7 @@ namespace ArchiSteamFarm {
Log("[!!] ERROR: " + previousMethodName + "() <" + botName + "> " + message);
}
internal static void LogGenericException(Exception exception, string botName = "Main", [CallerMemberName] string previousMethodName = "") {
internal static void LogGenericException(Exception exception, string botName = "Main", [CallerMemberName] string previousMethodName = null) {
if (exception == null) {
return;
}
@@ -76,7 +81,7 @@ namespace ArchiSteamFarm {
}
}
internal static void LogGenericWarning(string message, string botName = "Main", [CallerMemberName] string previousMethodName = "") {
internal static void LogGenericWarning(string message, string botName = "Main", [CallerMemberName] string previousMethodName = null) {
if (string.IsNullOrEmpty(message)) {
return;
}
@@ -84,7 +89,7 @@ namespace ArchiSteamFarm {
Log("[!] WARNING: " + previousMethodName + "() <" + botName + "> " + message);
}
internal static void LogGenericInfo(string message, string botName = "Main", [CallerMemberName] string previousMethodName = "") {
internal static void LogGenericInfo(string message, string botName = "Main", [CallerMemberName] string previousMethodName = null) {
if (string.IsNullOrEmpty(message)) {
return;
}
@@ -92,7 +97,7 @@ namespace ArchiSteamFarm {
Log("[*] INFO: " + previousMethodName + "() <" + botName + "> " + message);
}
internal static void LogNullError(string nullObjectName, string botName = "Main", [CallerMemberName] string previousMethodName = "") {
internal static void LogNullError(string nullObjectName, string botName = "Main", [CallerMemberName] string previousMethodName = null) {
if (string.IsNullOrEmpty(nullObjectName)) {
return;
}
@@ -101,7 +106,7 @@ namespace ArchiSteamFarm {
}
[Conditional("DEBUG")]
internal static void LogGenericDebug(string message, string botName = "Main", [CallerMemberName] string previousMethodName = "") {
internal static void LogGenericDebug(string message, string botName = "Main", [CallerMemberName] string previousMethodName = null) {
if (string.IsNullOrEmpty(message)) {
return;
}
@@ -125,6 +130,10 @@ namespace ArchiSteamFarm {
if (LogToFile) {
lock (FileLock) {
if (!LogToFile) {
return;
}
try {
File.AppendAllText(Program.LogFile, loggedMessage);
} catch (Exception e) {

View File

@@ -32,5 +32,5 @@ using System.Runtime.InteropServices;
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("2.0.4.2")]
[assembly: AssemblyFileVersion("2.0.4.2")]
[assembly: AssemblyVersion("2.0.4.5")]
[assembly: AssemblyFileVersion("2.0.4.5")]

View File

@@ -119,13 +119,13 @@ namespace ArchiSteamFarm {
return false;
}
// Rule 1 - We always trade the same amount of items
if (tradeOffer.ItemsToGive.Count != tradeOffer.ItemsToReceive.Count) {
// Decline trade if we're giving more count-wise
if (tradeOffer.ItemsToGive.Count > tradeOffer.ItemsToReceive.Count) {
return false;
}
// Rule 2 - We always trade steam cards and only for the same set
if (!tradeOffer.IsSteamCardsOnlyTrade() || !tradeOffer.IsPotentiallyDupesTrade()) {
// Decline trade if we're losing anything but steam cards, or if it's non-dupes trade
if (!tradeOffer.IsSteamCardsOnlyTradeForUs() || !tradeOffer.IsPotentiallyDupesTradeForUs()) {
return false;
}
@@ -165,34 +165,47 @@ namespace ArchiSteamFarm {
}
// Calculate our value of items to give
uint itemsToGiveDupesValue = 0;
List<uint> amountsToGive = new List<uint>(tradeOffer.ItemsToGive.Count);
foreach (Steam.Item item in tradeOffer.ItemsToGive) {
Tuple<ulong, ulong> key = new Tuple<ulong, ulong>(item.ClassID, item.InstanceID);
uint amount;
if (!amountMap.TryGetValue(key, out amount)) {
amountsToGive.Add(0);
continue;
}
itemsToGiveDupesValue += amount;
amountsToGive.Add(amount);
}
// Sort it ascending
amountsToGive.Sort();
// Calculate our value of items to receive
uint itemsToReceiveDupesValue = 0;
List<uint> amountsToReceive = new List<uint>(tradeOffer.ItemsToReceive.Count);
foreach (Steam.Item item in tradeOffer.ItemsToReceive) {
Tuple<ulong, ulong> key = new Tuple<ulong, ulong>(item.ClassID, item.InstanceID);
uint amount;
if (!amountMap.TryGetValue(key, out amount)) {
amountsToReceive.Add(0);
continue;
}
itemsToReceiveDupesValue += amount;
amountsToReceive.Add(amount);
}
// Trade is worth for us if we're in total trading more of our dupes for less of our dupes (or at least same amount)
// Which means that itemsToGiveDupesValue should be greater than itemsToReceiveDupesValue
return itemsToGiveDupesValue > itemsToReceiveDupesValue;
// Sort it ascending
amountsToReceive.Sort();
// Check actual difference
int difference = 0;
for (int i = 0; i < amountsToGive.Count; i++) {
difference += (int) (amountsToGive[i] - amountsToReceive[i]);
}
// Trade is worth for us if the difference is greater than 0
return difference > 0;
}
}
}

View File

@@ -101,35 +101,18 @@ namespace ArchiSteamFarm {
return null;
}
string[] args = input.Split(' ');
string botName;
if (args.Length > 1) { // If we have args[1] provided, use given botName
botName = args[1];
} else { // If not, just pick first one
botName = Bot.Bots.Keys.FirstOrDefault();
Bot bot = Bot.Bots.Values.FirstOrDefault();
if (bot == null) {
return "ERROR: No bots are enabled!";
}
if (string.IsNullOrEmpty(botName)) {
return "ERROR: Invalid botName: " + botName;
}
Bot bot;
if (!Bot.Bots.TryGetValue(botName, out bot)) {
return "ERROR: Couldn't find any bot named: " + botName;
}
Logging.LogGenericInfo("Received command: " + input);
string output;
if (Program.GlobalConfig.SteamOwnerID == 0) {
output = "Refusing to handle request because SteamOwnerID is not set!";
} else {
string command = '!' + input;
output = bot.Response(Program.GlobalConfig.SteamOwnerID, command).Result; // TODO: This should be asynchronous
return "Refusing to handle request because SteamOwnerID is not set!";
}
string command = "!" + input;
string output = bot.Response(Program.GlobalConfig.SteamOwnerID, command).Result; // TODO: This should be asynchronous
Logging.LogGenericInfo("Answered to command: " + input + " with: " + output);
return output;
}