Compare commits

...

26 Commits

Author SHA1 Message Date
JustArchi
33df54365a Add !help + code review 2016-03-26 02:47:25 +01:00
JustArchi
4a6ae3064a Put NetHook2 in it's own directory + add small readme 2016-03-25 12:42:34 +01:00
JustArchi
84857e060b Add !pause + misc 2016-03-24 14:18:07 +01:00
JustArchi
3311f2a703 Make number of hours human-readable 2016-03-24 08:14:26 +01:00
JustArchi
5666ebf891 Bump 2016-03-23 19:04:27 +01:00
JustArchi
0ded4f3b80 Bump 2016-03-23 18:53:51 +01:00
JustArchi
4c9354308c Improve UI a little 2016-03-23 18:38:19 +01:00
JustArchi
0bcf2f35b7 Misc 2016-03-23 13:59:54 +01:00
JustArchi
b93d5187d6 Misc 2016-03-23 13:48:59 +01:00
JustArchi
1426922854 Misc 2016-03-23 13:42:16 +01:00
JustArchi
d8925f9409 Sync ConfigGenerator 2016-03-23 13:39:56 +01:00
JustArchi
4302029bee Be consistent 2016-03-23 13:31:11 +01:00
JustArchi
01a7800a44 Final touch on travis + readme 2016-03-23 13:26:03 +01:00
JustArchi
ab3cf5b8d0 Add travis build status 2016-03-23 13:13:04 +01:00
JustArchi
2ab9741fa8 Add travis integration 2016-03-23 13:09:17 +01:00
JustArchi
f1c3339764 Misc 2016-03-23 12:18:16 +01:00
JustArchi
da01d4eab3 Use self-compiled ILRepack 2016-03-23 12:09:26 +01:00
JustArchi
cd9bd5f0dd Misc 2016-03-22 20:20:04 +01:00
JustArchi
2602ac3623 Improve Start/Stop mechanisms 2016-03-22 20:18:47 +01:00
JustArchi
2fe8db712e Enable enhanced logging when Debug is enabled, #176 2016-03-22 18:45:30 +01:00
JustArchi
687b20bcb5 Misc 2016-03-22 17:33:08 +01:00
JustArchi
23d9dcffe7 Enable AccountPlayingDelay of 0, WCFHostname of null and add code for fixing fuckups 2016-03-22 17:26:39 +01:00
JustArchi
42623ffb5a Misc 2016-03-22 16:49:17 +01:00
JustArchi
214003edbd Misc 2016-03-22 16:42:53 +01:00
JustArchi
c21333b6e9 Further code optimizations 2016-03-22 16:41:17 +01:00
JustArchi
630f1c008c Bump 2016-03-22 16:09:33 +01:00
30 changed files with 337 additions and 258 deletions

10
.travis.yml Normal file
View File

@@ -0,0 +1,10 @@
sudo: false
language: csharp
solution: ArchiSteamFarm.sln
git:
depth: 10
mono:
- weekly
- latest

View File

@@ -160,19 +160,19 @@
</PropertyGroup>
<PropertyGroup>
<PostBuildEvent Condition=" '$(OS)' != 'Unix' AND '$(ConfigurationName)' == 'Release' ">
mkdir "$(SolutionDir)out" "$(SolutionDir)out\config"
mkdir "$(SolutionDir)out\config"
copy "$(TargetDir)config\ASF.json" "$(SolutionDir)out\config"
copy "$(TargetDir)config\example.json" "$(SolutionDir)out\config"
copy "$(TargetDir)config\minimal.json" "$(SolutionDir)out\config"
"$(SolutionDir)tools\ILRepack.exe" /ndebug /internalize /parallel /targetplatform:v4 /wildcards /out:"$(SolutionDir)out\ASF.exe" "$(TargetDir)$(TargetName).exe" "$(TargetDir)*.dll"
"$(SolutionDir)tools\ILRepack\ILRepack.exe" /ndebug /internalize /parallel /targetplatform:v4 /wildcards /out:"$(SolutionDir)out\ASF.exe" "$(TargetDir)$(TargetName).exe" "$(TargetDir)*.dll"
del "$(SolutionDir)out\ASF.exe.config"
</PostBuildEvent>
<PostBuildEvent Condition=" '$(OS)' == 'Unix' AND '$(ConfigurationName)' == 'Release' ">
mkdir -p "$(SolutionDir)out" "$(SolutionDir)out/config"
mkdir -p "$(SolutionDir)out/config"
cp "$(TargetDir)config/ASF.json" "$(SolutionDir)out/config"
cp "$(TargetDir)config/example.json" "$(SolutionDir)out/config"
cp "$(TargetDir)config/minimal.json" "$(SolutionDir)out/config"
mono -O=all "$(SolutionDir)tools/ILRepack.exe" /ndebug /internalize /parallel /targetplatform:v4 /wildcards /out:"$(SolutionDir)out/ASF.exe" "$(TargetDir)$(TargetName).exe" "$(TargetDir)*.dll"
mono -O=all "$(SolutionDir)tools/ILRepack/ILRepack.exe" /ndebug /internalize /parallel /targetplatform:v4 /wildcards /out:"$(SolutionDir)out/ASF.exe" "$(TargetDir)$(TargetName).exe" "$(TargetDir)*.dll"
rm "$(SolutionDir)out/ASF.exe.config"
</PostBuildEvent>
</PropertyGroup>

View File

@@ -255,14 +255,6 @@ namespace ArchiSteamFarm {
Start().Forget();
}
internal bool IsMaster(ulong steamID) {
if (steamID == 0) {
return false;
}
return steamID == BotConfig.SteamMasterID || IsOwner(steamID);
}
internal async Task AcceptConfirmations(Confirmation.ConfirmationType allowedConfirmationType = Confirmation.ConfirmationType.Unknown) {
if (BotDatabase.SteamGuardAccount == null) {
return;
@@ -308,7 +300,6 @@ namespace ArchiSteamFarm {
return;
}
await Stop().ConfigureAwait(false);
await Start().ConfigureAwait(false);
}
@@ -318,7 +309,7 @@ namespace ArchiSteamFarm {
}
if (BotConfig.ShutdownOnFarmingFinished) {
await Shutdown().ConfigureAwait(false);
Stop();
}
}
@@ -343,8 +334,12 @@ namespace ArchiSteamFarm {
return ResponseExit(steamID);
case "!farm":
return ResponseFarm(steamID);
case "!help":
return ResponseHelp(steamID);
case "!loot":
return await ResponseSendTrade(steamID).ConfigureAwait(false);
case "!pause":
return await ResponsePause(steamID).ConfigureAwait(false);
case "!rejoinchat":
return ResponseRejoinChat(steamID);
case "!restart":
@@ -354,7 +349,7 @@ namespace ArchiSteamFarm {
case "!statusall":
return ResponseStatusAll(steamID);
case "!stop":
return await ResponseStop(steamID).ConfigureAwait(false);
return ResponseStop(steamID);
case "!update":
return await ResponseUpdate(steamID).ConfigureAwait(false);
default:
@@ -377,6 +372,8 @@ 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":
@@ -385,6 +382,8 @@ namespace ArchiSteamFarm {
} else {
return await ResponseOwns(steamID, BotName, args[1]).ConfigureAwait(false);
}
case "!pause":
return await ResponsePause(steamID, args[1]).ConfigureAwait(false);
case "!play":
if (args.Length > 2) {
return await ResponsePlay(steamID, args[1], args[2]).ConfigureAwait(false);
@@ -402,7 +401,7 @@ namespace ArchiSteamFarm {
case "!status":
return ResponseStatus(steamID, args[1]);
case "!stop":
return await ResponseStop(steamID, args[1]).ConfigureAwait(false);
return ResponseStop(steamID, args[1]);
default:
return ResponseUnknown(steamID);
}
@@ -410,48 +409,37 @@ namespace ArchiSteamFarm {
}
private async Task Start() {
if (SteamClient.IsConnected) {
return;
}
if (!KeepRunning) {
KeepRunning = true;
Task.Run(() => HandleCallbacks()).Forget();
}
Logging.LogGenericInfo("Starting...", BotName);
// 2FA tokens are expiring soon, use limiter only when we don't have any pending
if (TwoFactorAuth == null) {
await Program.LimitSteamRequestsAsync().ConfigureAwait(false);
}
Logging.LogGenericInfo("Starting...", BotName);
SteamClient.Connect();
}
private async Task Stop() {
if (!SteamClient.IsConnected) {
return;
}
private void Stop() {
Logging.LogGenericInfo("Stopping...", BotName);
for (byte i = 0; i < WebBrowser.MaxRetries && SteamClient.IsConnected; i++) {
SteamClient.Disconnect();
await Utilities.SleepAsync(1000).ConfigureAwait(false);
}
KeepRunning = false;
if (SteamClient.IsConnected) {
Logging.LogGenericWarning("Could not stop this bot instance!", BotName);
} else {
Logging.LogGenericInfo("Stopped!", BotName);
SteamClient.Disconnect();
}
Program.OnBotShutdown();
}
private async Task Shutdown() {
KeepRunning = false;
await Stop().ConfigureAwait(false);
Program.OnBotShutdown();
private bool IsMaster(ulong steamID) {
if (steamID == 0) {
return false;
}
return steamID == BotConfig.SteamMasterID || IsOwner(steamID);
}
private void ImportAuthenticator(string maFilePath) {
@@ -485,7 +473,7 @@ namespace ArchiSteamFarm {
while ((loginResult = userLogin.DoLogin()) != LoginResult.LoginOkay) {
switch (loginResult) {
case LoginResult.Need2FA:
userLogin.TwoFactorCode = Program.GetUserInput(BotName, Program.EUserInputType.TwoFactorAuthentication);
userLogin.TwoFactorCode = Program.GetUserInput(Program.EUserInputType.TwoFactorAuthentication, BotName);
break;
default:
Logging.LogGenericError("Unhandled situation: " + loginResult, BotName);
@@ -503,19 +491,42 @@ namespace ArchiSteamFarm {
BotDatabase.SteamGuardAccount.Session = userLogin.Session;
if (string.IsNullOrEmpty(BotDatabase.SteamGuardAccount.DeviceID)) {
BotDatabase.SteamGuardAccount.DeviceID = Program.GetUserInput(BotName, Program.EUserInputType.DeviceID);
BotDatabase.SteamGuardAccount.DeviceID = Program.GetUserInput(Program.EUserInputType.DeviceID, BotName);
}
BotDatabase.Save();
Logging.LogGenericInfo("Successfully finished importing mobile authenticator!", BotName);
}
private string ResponseStatus(ulong steamID) {
if (steamID == 0) {
private async Task<string> ResponsePause(ulong steamID) {
if (steamID == 0 || !IsMaster(steamID)) {
return null;
}
if (!IsMaster(steamID)) {
if (CardsFarmer.ManualMode) {
await CardsFarmer.SwitchToManualMode(false).ConfigureAwait(false);
return "Automatic farming is enabled again!";
} else {
await CardsFarmer.SwitchToManualMode(true).ConfigureAwait(false);
return "Automatic farming is now stopped!";
}
}
private static async Task<string> ResponsePause(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 await bot.ResponsePause(steamID).ConfigureAwait(false);
}
private string ResponseStatus(ulong steamID) {
if (steamID == 0 || !IsMaster(steamID)) {
return null;
}
@@ -567,11 +578,7 @@ namespace ArchiSteamFarm {
}
private async Task<string> ResponseSendTrade(ulong steamID) {
if (steamID == 0) {
return null;
}
if (!IsMaster(steamID)) {
if (steamID == 0 || !IsMaster(steamID)) {
return null;
}
@@ -608,11 +615,7 @@ namespace ArchiSteamFarm {
}
private string Response2FA(ulong steamID) {
if (steamID == 0) {
return null;
}
if (!IsMaster(steamID)) {
if (steamID == 0 || !IsMaster(steamID)) {
return null;
}
@@ -638,11 +641,7 @@ namespace ArchiSteamFarm {
}
private string Response2FAOff(ulong steamID) {
if (steamID == 0) {
return null;
}
if (!IsMaster(steamID)) {
if (steamID == 0 || !IsMaster(steamID)) {
return null;
}
@@ -671,11 +670,7 @@ namespace ArchiSteamFarm {
}
private async Task<string> Response2FAOK(ulong steamID) {
if (steamID == 0) {
return null;
}
if (!IsMaster(steamID)) {
if (steamID == 0 || !IsMaster(steamID)) {
return null;
}
@@ -714,11 +709,7 @@ namespace ArchiSteamFarm {
}
private string ResponseFarm(ulong steamID) {
if (steamID == 0) {
return null;
}
if (!IsMaster(steamID)) {
if (steamID == 0 || !IsMaster(steamID)) {
return null;
}
@@ -743,12 +734,29 @@ namespace ArchiSteamFarm {
return bot.ResponseFarm(steamID);
}
private async Task<string> ResponseRedeem(ulong steamID, string message, bool validate) {
if (steamID == 0 || string.IsNullOrEmpty(message)) {
private string ResponseHelp(ulong steamID) {
if (steamID == 0 || !IsMaster(steamID)) {
return null;
}
if (!IsMaster(steamID)) {
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;
}
@@ -931,11 +939,7 @@ namespace ArchiSteamFarm {
}
private async Task<string> ResponseAddLicense(ulong steamID, HashSet<uint> gameIDs) {
if (steamID == 0 || gameIDs == null || gameIDs.Count == 0) {
return null;
}
if (!IsMaster(steamID)) {
if (steamID == 0 || gameIDs == null || gameIDs.Count == 0 || !IsMaster(steamID)) {
return null;
}
@@ -984,11 +988,7 @@ namespace ArchiSteamFarm {
}
private async Task<string> ResponseOwns(ulong steamID, string games) {
if (steamID == 0 || string.IsNullOrEmpty(games)) {
return null;
}
if (!IsMaster(steamID)) {
if (steamID == 0 || string.IsNullOrEmpty(games) || !IsMaster(steamID)) {
return null;
}
@@ -1040,20 +1040,19 @@ namespace ArchiSteamFarm {
}
private async Task<string> ResponsePlay(ulong steamID, HashSet<uint> gameIDs) {
if (steamID == 0 || gameIDs == null || gameIDs.Count == 0) {
return null;
}
if (!IsMaster(steamID)) {
if (steamID == 0 || gameIDs == null || gameIDs.Count == 0 || !IsMaster(steamID)) {
return null;
}
if (gameIDs.Contains(0)) {
if (await CardsFarmer.SwitchToManualMode(false).ConfigureAwait(false)) {
if (CardsFarmer.ManualMode) {
ResetGamesPlayed();
await CardsFarmer.SwitchToManualMode(false).ConfigureAwait(false);
}
} else {
await CardsFarmer.SwitchToManualMode(true).ConfigureAwait(false);
if (!CardsFarmer.ManualMode) {
await CardsFarmer.SwitchToManualMode(true).ConfigureAwait(false);
}
ArchiHandler.PlayGames(gameIDs);
}
@@ -1089,11 +1088,7 @@ namespace ArchiSteamFarm {
}
private async Task<string> ResponseStart(ulong steamID) {
if (steamID == 0) {
return null;
}
if (!IsMaster(steamID)) {
if (steamID == 0 || !IsMaster(steamID)) {
return null;
}
@@ -1118,12 +1113,8 @@ namespace ArchiSteamFarm {
return await bot.ResponseStart(steamID).ConfigureAwait(false);
}
private async Task<string> ResponseStop(ulong steamID) {
if (steamID == 0) {
return null;
}
if (!IsMaster(steamID)) {
private string ResponseStop(ulong steamID) {
if (steamID == 0 || !IsMaster(steamID)) {
return null;
}
@@ -1131,11 +1122,11 @@ namespace ArchiSteamFarm {
return "That bot instance is already inactive!";
}
await Shutdown().ConfigureAwait(false);
Stop();
return "Done!";
}
private static async Task<string> ResponseStop(ulong steamID, string botName) {
private static string ResponseStop(ulong steamID, string botName) {
if (steamID == 0 || string.IsNullOrEmpty(botName)) {
return null;
}
@@ -1145,15 +1136,11 @@ namespace ArchiSteamFarm {
return "Couldn't find any bot named " + botName + "!";
}
return await bot.ResponseStop(steamID).ConfigureAwait(false);
return bot.ResponseStop(steamID);
}
private string ResponseUnknown(ulong steamID) {
if (steamID == 0) {
return null;
}
if (!IsMaster(steamID)) {
if (steamID == 0 || !IsMaster(steamID)) {
return null;
}
@@ -1214,7 +1201,7 @@ namespace ArchiSteamFarm {
while ((loginResult = userLogin.DoLogin()) != LoginResult.LoginOkay) {
switch (loginResult) {
case LoginResult.NeedEmail:
userLogin.EmailCode = Program.GetUserInput(BotName, Program.EUserInputType.SteamGuard);
userLogin.EmailCode = Program.GetUserInput(Program.EUserInputType.SteamGuard, BotName);
break;
default:
Logging.LogGenericError("Unhandled situation: " + loginResult, BotName);
@@ -1228,7 +1215,7 @@ namespace ArchiSteamFarm {
while ((linkResult = authenticatorLinker.AddAuthenticator()) != AuthenticatorLinker.LinkResult.AwaitingFinalization) {
switch (linkResult) {
case AuthenticatorLinker.LinkResult.MustProvidePhoneNumber:
authenticatorLinker.PhoneNumber = Program.GetUserInput(BotName, Program.EUserInputType.PhoneNumber);
authenticatorLinker.PhoneNumber = Program.GetUserInput(Program.EUserInputType.PhoneNumber, BotName);
break;
default:
Logging.LogGenericError("Unhandled situation: " + linkResult, BotName);
@@ -1238,7 +1225,7 @@ namespace ArchiSteamFarm {
BotDatabase.SteamGuardAccount = authenticatorLinker.LinkedAccount;
AuthenticatorLinker.FinalizeResult finalizeResult = authenticatorLinker.FinalizeAddAuthenticator(Program.GetUserInput(BotName, Program.EUserInputType.SMS));
AuthenticatorLinker.FinalizeResult finalizeResult = authenticatorLinker.FinalizeAddAuthenticator(Program.GetUserInput(Program.EUserInputType.SMS, BotName));
if (finalizeResult != AuthenticatorLinker.FinalizeResult.Success) {
Logging.LogGenericError("Unhandled situation: " + finalizeResult, BotName);
DelinkMobileAuthenticator();
@@ -1246,7 +1233,7 @@ namespace ArchiSteamFarm {
}
Logging.LogGenericInfo("Successfully linked ASF as new mobile authenticator for this account!", BotName);
Program.GetUserInput(BotName, Program.EUserInputType.RevocationCode, BotDatabase.SteamGuardAccount.RevocationCode);
Program.GetUserInput(Program.EUserInputType.RevocationCode, BotName, BotDatabase.SteamGuardAccount.RevocationCode);
}
private bool DelinkMobileAuthenticator() {
@@ -1273,11 +1260,11 @@ namespace ArchiSteamFarm {
private void InitializeLoginAndPassword() {
if (string.IsNullOrEmpty(BotConfig.SteamLogin)) {
BotConfig.SteamLogin = Program.GetUserInput(BotName, Program.EUserInputType.Login);
BotConfig.SteamLogin = Program.GetUserInput(Program.EUserInputType.Login, BotName);
}
if (string.IsNullOrEmpty(BotConfig.SteamPassword) && string.IsNullOrEmpty(BotDatabase.LoginKey)) {
BotConfig.SteamPassword = Program.GetUserInput(BotName, Program.EUserInputType.Password);
BotConfig.SteamPassword = Program.GetUserInput(Program.EUserInputType.Password, BotName);
}
}
@@ -1347,17 +1334,17 @@ namespace ArchiSteamFarm {
}
Logging.LogGenericInfo("Disconnected from Steam!", BotName);
await CardsFarmer.StopFarming().ConfigureAwait(false);
if (!KeepRunning) {
return;
}
CardsFarmer.StopFarming().Forget();
// If we initiated disconnect, do not attempt to reconnect
if (callback.UserInitiated) {
return;
}
if (!KeepRunning) {
return;
}
if (InvalidPassword) {
InvalidPassword = false;
if (!string.IsNullOrEmpty(BotDatabase.LoginKey)) { // InvalidPassword means usually that login key has expired, if we used it
@@ -1369,6 +1356,12 @@ namespace ArchiSteamFarm {
}
} else if (LoggedInElsewhere) {
LoggedInElsewhere = false;
if (Program.GlobalConfig.AccountPlayingDelay == 0) {
Stop();
return;
}
Logging.LogGenericInfo("Account is being used elsewhere, ASF will try to resume farming in " + Program.GlobalConfig.AccountPlayingDelay + " minutes...", BotName);
await Utilities.SleepAsync(Program.GlobalConfig.AccountPlayingDelay * 60 * 1000).ConfigureAwait(false);
}
@@ -1390,11 +1383,7 @@ namespace ArchiSteamFarm {
}
private void OnChatInvite(SteamFriends.ChatInviteCallback callback) {
if (callback == null) {
return;
}
if (!IsMaster(callback.PatronID)) {
if (callback == null || !IsMaster(callback.PatronID)) {
return;
}
@@ -1402,20 +1391,16 @@ namespace ArchiSteamFarm {
}
private async void OnChatMsg(SteamFriends.ChatMsgCallback callback) {
if (callback == null) {
return;
}
if (callback.ChatMsgType != EChatEntryType.ChatMsg) {
return;
}
if (!IsMaster(callback.ChatterID)) {
if (callback == null || callback.ChatMsgType != EChatEntryType.ChatMsg) {
return;
}
switch (callback.Message) {
case "!leave":
if (!IsMaster(callback.ChatterID)) {
break;
}
SteamFriends.LeaveChat(callback.ChatRoomID);
break;
default:
@@ -1442,6 +1427,7 @@ namespace ArchiSteamFarm {
if (!IsMaster(friend.SteamID)) {
break;
}
SteamFriends.AddFriend(friend.SteamID);
break;
}
@@ -1449,11 +1435,7 @@ namespace ArchiSteamFarm {
}
private async void OnFriendMsg(SteamFriends.FriendMsgCallback callback) {
if (callback == null) {
return;
}
if (callback.EntryType != EChatEntryType.ChatMsg) {
if (callback == null || callback.EntryType != EChatEntryType.ChatMsg) {
return;
}
@@ -1461,19 +1443,7 @@ namespace ArchiSteamFarm {
}
private async void OnFriendMsgHistory(SteamFriends.FriendMsgHistoryCallback callback) {
if (callback == null) {
return;
}
if (callback.Result != EResult.OK) {
return;
}
if (!IsMaster(callback.SteamID)) {
return;
}
if (callback.Messages.Count == 0) {
if (callback == null || callback.Result != EResult.OK || callback.Messages.Count == 0 || !IsMaster(callback.SteamID)) {
return;
}
@@ -1527,11 +1497,11 @@ namespace ArchiSteamFarm {
switch (callback.Result) {
case EResult.AccountLogonDenied:
AuthCode = Program.GetUserInput(BotConfig.SteamLogin, Program.EUserInputType.SteamGuard);
AuthCode = Program.GetUserInput(Program.EUserInputType.SteamGuard, BotName);
break;
case EResult.AccountLoginDeniedNeedTwoFactor:
if (BotDatabase.SteamGuardAccount == null) {
TwoFactorAuth = Program.GetUserInput(BotConfig.SteamLogin, Program.EUserInputType.TwoFactorAuthentication);
TwoFactorAuth = Program.GetUserInput(Program.EUserInputType.TwoFactorAuthentication, BotName);
} else {
TwoFactorAuth = BotDatabase.SteamGuardAccount.GenerateSteamGuardCode();
}
@@ -1563,7 +1533,7 @@ namespace ArchiSteamFarm {
ResetGamesPlayed();
if (string.IsNullOrEmpty(BotConfig.SteamParentalPIN)) {
BotConfig.SteamParentalPIN = Program.GetUserInput(BotName, Program.EUserInputType.SteamParentalPIN);
BotConfig.SteamParentalPIN = Program.GetUserInput(Program.EUserInputType.SteamParentalPIN, BotName);
}
if (!await ArchiWebHandler.Init(SteamClient, callback.WebAPIUserNonce, BotConfig.SteamParentalPIN).ConfigureAwait(false)) {
@@ -1601,7 +1571,7 @@ namespace ArchiSteamFarm {
break;
default: // Unexpected result, shutdown immediately
Logging.LogGenericWarning("Unable to login to Steam: " + callback.Result, BotName);
await Shutdown().ConfigureAwait(false);
Stop();
break;
}
}
@@ -1671,7 +1641,7 @@ namespace ArchiSteamFarm {
}
if (checkTrades) {
Trading.CheckTrades();
Trading.CheckTrades().Forget();
}
if (markInventory && BotConfig.DismissInventoryNotifications) {

View File

@@ -42,7 +42,9 @@ namespace ArchiSteamFarm {
private readonly Bot Bot;
private readonly Timer Timer;
private volatile bool ManualMode, NowFarming;
internal bool ManualMode { get; private set; }
private bool NowFarming;
internal CardsFarmer(Bot bot) {
if (bot == null) {
@@ -61,9 +63,9 @@ namespace ArchiSteamFarm {
}
}
internal async Task<bool> SwitchToManualMode(bool manualMode) {
internal async Task SwitchToManualMode(bool manualMode) {
if (ManualMode == manualMode) {
return false;
return;
}
ManualMode = manualMode;
@@ -75,8 +77,6 @@ namespace ArchiSteamFarm {
Logging.LogGenericInfo("Now running in Automatic Farming mode", Bot.BotName);
StartFarming().Forget();
}
return true;
}
internal async Task StartFarming() {
@@ -113,7 +113,6 @@ namespace ArchiSteamFarm {
uint appID = gamesToFarmSolo.First();
if (await FarmSolo(appID).ConfigureAwait(false)) {
farmedSomething = true;
Logging.LogGenericInfo("Done farming: " + appID, Bot.BotName);
gamesToFarmSolo.Remove(appID);
gamesToFarmSolo.TrimExcess();
} else {
@@ -122,7 +121,7 @@ namespace ArchiSteamFarm {
}
}
} else {
if (FarmMultiple(GamesToFarm)) {
if (FarmMultiple()) {
Logging.LogGenericInfo("Done farming: " + string.Join(", ", GamesToFarm.Keys), Bot.BotName);
} else {
NowFarming = false;
@@ -133,10 +132,9 @@ namespace ArchiSteamFarm {
} else { // If we have unrestricted card drops, we use simple algorithm
Logging.LogGenericInfo("Chosen farming algorithm: Simple", Bot.BotName);
while (GamesToFarm.Count > 0) {
uint appID = GetAnyGameToFarm(GamesToFarm);
uint appID = GamesToFarm.Keys.FirstOrDefault();
if (await FarmSolo(appID).ConfigureAwait(false)) {
farmedSomething = true;
Logging.LogGenericInfo("Done farming: " + appID, Bot.BotName);
} else {
NowFarming = false;
return;
@@ -208,14 +206,6 @@ namespace ArchiSteamFarm {
return result;
}
private static uint GetAnyGameToFarm(ConcurrentDictionary<uint, float> gamesToFarm) {
if (gamesToFarm == null) {
return 0;
}
return gamesToFarm.Keys.FirstOrDefault();
}
private async Task<bool> IsAnythingToFarm() {
if (NowFarming) {
return true;
@@ -302,13 +292,13 @@ namespace ArchiSteamFarm {
HtmlNode timeNode = htmlNode.SelectSingleNode(".//div[@class='badge_title_stats_playtime']");
if (timeNode == null) {
Logging.LogNullError("timeNode", Bot.BotName);
return;
continue;
}
string hoursString = timeNode.InnerText;
if (string.IsNullOrEmpty(hoursString)) {
Logging.LogNullError("hoursString", Bot.BotName);
return;
continue;
}
hoursString = Regex.Match(hoursString, @"[0-9\.,]+").Value;
@@ -364,24 +354,27 @@ namespace ArchiSteamFarm {
return !htmlNode.InnerText.Contains("No card drops");
}
private bool FarmMultiple(ConcurrentDictionary<uint, float> appIDs) {
if (appIDs.Count == 0) {
private bool FarmMultiple() {
if (GamesToFarm.Count == 0) {
return true;
}
float maxHour = 0;
foreach (float hour in appIDs.Values) {
if (hour > maxHour) {
maxHour = hour;
foreach (KeyValuePair<uint, float> game in GamesToFarm) {
CurrentGamesFarming.Add(game.Key);
if (game.Value > maxHour) {
maxHour = game.Value;
}
}
foreach (uint appID in appIDs.Keys) {
CurrentGamesFarming.Add(appID);
if (maxHour >= 2) {
CurrentGamesFarming.Clear();
CurrentGamesFarming.TrimExcess();
return true;
}
Logging.LogGenericInfo("Now farming: " + string.Join(", ", appIDs.Keys), Bot.BotName);
if (FarmHours(maxHour, appIDs.Keys)) {
Logging.LogGenericInfo("Now farming: " + string.Join(", ", CurrentGamesFarming), Bot.BotName);
if (FarmHours(maxHour, CurrentGamesFarming)) {
CurrentGamesFarming.Clear();
CurrentGamesFarming.TrimExcess();
return true;
@@ -403,8 +396,11 @@ namespace ArchiSteamFarm {
if (await Farm(appID).ConfigureAwait(false)) {
CurrentGamesFarming.Clear();
CurrentGamesFarming.TrimExcess();
float ignored;
GamesToFarm.TryRemove(appID, out ignored);
float hours;
if (GamesToFarm.TryRemove(appID, out hours)) {
TimeSpan timeSpan = TimeSpan.FromHours(hours);
Logging.LogGenericInfo("Done farming: " + appID + " after " + timeSpan.ToString(@"hh\:mm") + " hours of playtime!", Bot.BotName);
}
return true;
} else {
CurrentGamesFarming.Clear();
@@ -428,6 +424,11 @@ namespace ArchiSteamFarm {
success = false;
break;
}
// Don't forget to update our GamesToFarm hours
float timePlayed = Program.GlobalConfig.FarmingDelay / 60.0F;
GamesToFarm[appID] += timePlayed;
keepFarming = await ShouldFarm(appID).ConfigureAwait(false);
Logging.LogGenericInfo("Still farming: " + appID, Bot.BotName);
}
@@ -437,7 +438,7 @@ namespace ArchiSteamFarm {
return success;
}
private bool FarmHours(float maxHour, ICollection<uint> appIDs) {
private bool FarmHours(float maxHour, HashSet<uint> appIDs) {
if (maxHour < 0 || appIDs == null || appIDs.Count == 0) {
return false;
}
@@ -450,7 +451,6 @@ namespace ArchiSteamFarm {
bool success = true;
while (maxHour < 2) {
Logging.LogGenericInfo("Still farming: " + string.Join(", ", appIDs), Bot.BotName);
if (FarmResetEvent.WaitOne(60 * 1000 * Program.GlobalConfig.FarmingDelay)) {
success = false;
break;
@@ -458,15 +458,12 @@ namespace ArchiSteamFarm {
// Don't forget to update our GamesToFarm hours
float timePlayed = Program.GlobalConfig.FarmingDelay / 60.0F;
foreach (KeyValuePair<uint, float> gameToFarm in GamesToFarm) {
if (!appIDs.Contains(gameToFarm.Key)) {
continue;
}
GamesToFarm[gameToFarm.Key] = gameToFarm.Value + timePlayed;
foreach (uint appID in appIDs) {
GamesToFarm[appID] += timePlayed;
}
maxHour += timePlayed;
Logging.LogGenericInfo("Still farming: " + string.Join(", ", appIDs), Bot.BotName);
}
Bot.ResetGamesPlayed();

View File

@@ -36,6 +36,13 @@ namespace ArchiSteamFarm {
Experimental
}
private const byte DefaultMaxFarmingTime = 10;
private const byte DefaultFarmingDelay = 5;
private const byte DefaultHttpTimeout = 60;
private const ushort DefaultWCFPort = 1242;
private static readonly ProtocolType DefaultSteamProtocol = ProtocolType.Tcp;
// This is hardcoded blacklist which should not be possible to change
internal static readonly HashSet<uint> GlobalBlacklist = new HashSet<uint> { 267420, 303700, 335590, 368020, 425280 };
@@ -49,19 +56,19 @@ namespace ArchiSteamFarm {
internal EUpdateChannel UpdateChannel { get; private set; } = EUpdateChannel.Stable;
[JsonProperty(Required = Required.DisallowNull)]
internal ProtocolType SteamProtocol { get; private set; } = ProtocolType.Tcp;
internal ProtocolType SteamProtocol { get; private set; } = DefaultSteamProtocol;
[JsonProperty(Required = Required.DisallowNull)]
internal ulong SteamOwnerID { get; private set; } = 0;
[JsonProperty(Required = Required.DisallowNull)]
internal byte MaxFarmingTime { get; private set; } = 10;
internal byte MaxFarmingTime { get; private set; } = DefaultMaxFarmingTime;
[JsonProperty(Required = Required.DisallowNull)]
internal byte IdleFarmingPeriod { get; private set; } = 3;
[JsonProperty(Required = Required.DisallowNull)]
internal byte FarmingDelay { get; private set; } = 5;
internal byte FarmingDelay { get; private set; } = DefaultFarmingDelay;
[JsonProperty(Required = Required.DisallowNull)]
internal byte AccountPlayingDelay { get; private set; } = 5;
@@ -76,13 +83,13 @@ namespace ArchiSteamFarm {
internal bool ForceHttp { get; private set; } = false;
[JsonProperty(Required = Required.DisallowNull)]
internal byte HttpTimeout { get; private set; } = 60;
internal byte HttpTimeout { get; private set; } = DefaultHttpTimeout;
[JsonProperty]
internal string WCFHostname { get; set; } = "localhost";
[JsonProperty(Required = Required.DisallowNull)]
internal string WCFHostname { get; private set; } = "localhost";
[JsonProperty(Required = Required.DisallowNull)]
internal ushort WCFPort { get; private set; } = 1242;
internal ushort WCFPort { get; private set; } = DefaultWCFPort;
[JsonProperty(Required = Required.DisallowNull)]
internal bool LogToFile { get; private set; } = true;
@@ -112,17 +119,39 @@ namespace ArchiSteamFarm {
}
// SK2 supports only TCP and UDP steam protocols
// Make sure that user can't screw this up
// Ensure that user can't screw this up
switch (globalConfig.SteamProtocol) {
case ProtocolType.Tcp:
case ProtocolType.Udp:
break;
default:
Logging.LogGenericWarning("Configured SteamProtocol is invalid: " + globalConfig.SteamProtocol + ", default TCP protocol will be used instead");
globalConfig.SteamProtocol = ProtocolType.Tcp;
Logging.LogGenericWarning("Configured SteamProtocol is invalid: " + globalConfig.SteamProtocol + ". Value of " + DefaultSteamProtocol + " will be used instead");
globalConfig.SteamProtocol = DefaultSteamProtocol;
break;
}
// User might not know what he's doing
// Ensure that he can't screw core ASF variables
if (globalConfig.MaxFarmingTime == 0) {
Logging.LogGenericWarning("Configured MaxFarmingTime is invalid: " + globalConfig.MaxFarmingTime + ". Value of " + DefaultMaxFarmingTime + " will be used instead");
globalConfig.MaxFarmingTime = DefaultMaxFarmingTime;
}
if (globalConfig.FarmingDelay == 0) {
Logging.LogGenericWarning("Configured FarmingDelay is invalid: " + globalConfig.FarmingDelay + ". Value of " + DefaultFarmingDelay + " will be used instead");
globalConfig.FarmingDelay = DefaultFarmingDelay;
}
if (globalConfig.HttpTimeout == 0) {
Logging.LogGenericWarning("Configured HttpTimeout is invalid: " + globalConfig.HttpTimeout + ". Value of " + DefaultHttpTimeout + " will be used instead");
globalConfig.HttpTimeout = DefaultHttpTimeout;
}
if (globalConfig.WCFPort == 0) {
Logging.LogGenericWarning("Configured WCFPort is invalid: " + globalConfig.WCFPort + ". Value of " + DefaultWCFPort + " will be used instead");
globalConfig.WCFPort = DefaultWCFPort;
}
return globalConfig;
}

View File

@@ -45,6 +45,7 @@ namespace ArchiSteamFarm {
SteamParentalPIN,
RevocationCode,
TwoFactorAuthentication,
WCFHostname
}
internal enum EMode : byte {
@@ -58,10 +59,11 @@ namespace ArchiSteamFarm {
internal const string ConfigDirectory = "config";
internal const string DebugDirectory = "debug";
internal const string LogFile = "log.txt";
internal const string GithubRepo = "JustArchi/ArchiSteamFarm";
internal const string GlobalConfigFile = ASF + ".json";
internal const string GlobalDatabaseFile = ASF + ".db";
private const string GithubReleaseURL = "https://api.github.com/repos/JustArchi/ArchiSteamFarm/releases"; // GitHub API is HTTPS only
private const string GithubReleaseURL = "https://api.github.com/repos/" + GithubRepo + "/releases"; // GitHub API is HTTPS only
private static readonly Assembly Assembly = Assembly.GetExecutingAssembly();
internal static readonly Version Version = Assembly.GetName().Version;
@@ -262,7 +264,7 @@ namespace ArchiSteamFarm {
}).Forget();
}
internal static string GetUserInput(string botLogin, EUserInputType userInputType, string extraInformation = null) {
internal static string GetUserInput(EUserInputType userInputType, string botName = null, string extraInformation = null) {
if (userInputType == EUserInputType.Unknown) {
return null;
}
@@ -272,36 +274,38 @@ namespace ArchiSteamFarm {
ConsoleIsBusy = true;
switch (userInputType) {
case EUserInputType.DeviceID:
Console.Write("<" + botLogin + "> Please enter your Device ID (including \"android:\"): ");
Console.Write((string.IsNullOrEmpty(botName) ? "" : "<" + botName + "> ") + "Please enter your Device ID (including \"android:\"): ");
break;
case EUserInputType.Login:
Console.Write("<" + botLogin + "> Please enter your login: ");
Console.Write((string.IsNullOrEmpty(botName) ? "" : "<" + botName + "> ") + "Please enter your login: ");
break;
case EUserInputType.Password:
Console.Write("<" + botLogin + "> Please enter your password: ");
Console.Write((string.IsNullOrEmpty(botName) ? "" : "<" + botName + "> ") + "Please enter your password: ");
break;
case EUserInputType.PhoneNumber:
Console.Write("<" + botLogin + "> Please enter your full phone number (e.g. +1234567890): ");
Console.Write((string.IsNullOrEmpty(botName) ? "" : "<" + botName + "> ") + "Please enter your full phone number (e.g. +1234567890): ");
break;
case EUserInputType.SMS:
Console.Write("<" + botLogin + "> Please enter SMS code sent on your mobile: ");
Console.Write((string.IsNullOrEmpty(botName) ? "" : "<" + botName + "> ") + "Please enter SMS code sent on your mobile: ");
break;
case EUserInputType.SteamGuard:
Console.Write("<" + botLogin + "> Please enter the auth code sent to your email: ");
Console.Write((string.IsNullOrEmpty(botName) ? "" : "<" + botName + "> ") + "Please enter the auth code sent to your email: ");
break;
case EUserInputType.SteamParentalPIN:
Console.Write("<" + botLogin + "> Please enter steam parental PIN: ");
Console.Write((string.IsNullOrEmpty(botName) ? "" : "<" + botName + "> ") + "Please enter steam parental PIN: ");
break;
case EUserInputType.RevocationCode:
Console.WriteLine("<" + botLogin + "> PLEASE WRITE DOWN YOUR REVOCATION CODE: " + extraInformation);
Console.WriteLine("<" + botLogin + "> THIS IS THE ONLY WAY TO NOT GET LOCKED OUT OF YOUR ACCOUNT!");
Console.Write("<" + botLogin + "> Hit enter once ready...");
Console.Write((string.IsNullOrEmpty(botName) ? "" : "<" + botName + "> ") + "PLEASE WRITE DOWN YOUR REVOCATION CODE: " + extraInformation);
Console.Write("Hit enter once ready...");
break;
case EUserInputType.TwoFactorAuthentication:
Console.Write("<" + botLogin + "> Please enter your 2 factor auth code from your authenticator app: ");
Console.Write((string.IsNullOrEmpty(botName) ? "" : "<" + botName + "> ") + "Please enter your 2 factor auth code from your authenticator app: ");
break;
case EUserInputType.WCFHostname:
Console.Write((string.IsNullOrEmpty(botName) ? "" : "<" + botName + "> ") + "Please enter your WCF hostname: ");
break;
default:
Console.Write("<" + botLogin + "> Please enter not documented yet value of \"" + userInputType + "\": ");
Console.Write((string.IsNullOrEmpty(botName) ? "" : "<" + botName + "> ") + "Please enter not documented yet value of \"" + userInputType + "\": ");
break;
}
result = Console.ReadLine();

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.1.7")]
[assembly: AssemblyFileVersion("2.0.1.7")]
[assembly: AssemblyVersion("2.0.2.0")]
[assembly: AssemblyFileVersion("2.0.2.0")]

View File

@@ -35,9 +35,9 @@ namespace ArchiSteamFarm {
private static readonly SemaphoreSlim InventorySemaphore = new SemaphoreSlim(1);
private readonly Bot Bot;
private readonly SemaphoreSlim Semaphore = new SemaphoreSlim(1);
private readonly SemaphoreSlim TradesSemaphore = new SemaphoreSlim(1);
private volatile byte ParsingTasks = 0;
private byte ParsingTasks = 0;
internal static async Task LimitInventoryRequestsAsync() {
await InventorySemaphore.WaitAsync().ConfigureAwait(false);
@@ -55,18 +55,27 @@ namespace ArchiSteamFarm {
Bot = bot;
}
internal async void CheckTrades() {
if (ParsingTasks >= 2) {
internal async Task CheckTrades() {
bool shouldRun = false;
lock (TradesSemaphore) {
if (ParsingTasks < 2) {
ParsingTasks++;
shouldRun = true;
}
}
if (!shouldRun) {
return;
}
ParsingTasks++;
await TradesSemaphore.WaitAsync().ConfigureAwait(false);
await Semaphore.WaitAsync().ConfigureAwait(false);
await ParseActiveTrades().ConfigureAwait(false);
Semaphore.Release();
lock (TradesSemaphore) {
ParsingTasks--;
}
ParsingTasks--;
TradesSemaphore.Release();
}
private async Task ParseActiveTrades() {

View File

@@ -42,6 +42,10 @@ namespace ArchiSteamFarm {
private Client Client;
internal static void Init() {
if (string.IsNullOrEmpty(Program.GlobalConfig.WCFHostname)) {
Program.GlobalConfig.WCFHostname = Program.GetUserInput(Program.EUserInputType.WCFHostname);
}
URL = "http://" + Program.GlobalConfig.WCFHostname + ":" + Program.GlobalConfig.WCFPort + "/ASF";
}

View File

@@ -214,7 +214,16 @@ namespace ArchiSteamFarm {
}
}
if (responseMessage == null || !responseMessage.IsSuccessStatusCode) {
if (responseMessage == null) {
return null;
}
if (!responseMessage.IsSuccessStatusCode) {
if (Program.GlobalConfig.Debug) {
Logging.LogGenericError("Request: " + request + "failed!");
Logging.LogGenericError("Status code: " + responseMessage.StatusCode);
Logging.LogGenericError("Content: " + await responseMessage.Content.ReadAsStringAsync().ConfigureAwait(false));
}
return null;
}

View File

@@ -29,7 +29,7 @@ using System.IO;
namespace ConfigGenerator {
internal class ASFConfig {
internal static List<ASFConfig> ASFConfigs = new List<ASFConfig>();
internal static HashSet<ASFConfig> ASFConfigs = new HashSet<ASFConfig>();
internal string FilePath { get; set; }
@@ -37,9 +37,8 @@ namespace ConfigGenerator {
ASFConfigs.Add(this);
}
protected ASFConfig(string filePath) {
protected ASFConfig(string filePath) : this() {
FilePath = filePath;
ASFConfigs.Add(this);
}
internal virtual void Save() {

View File

@@ -48,7 +48,6 @@
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Deployment" />
<Reference Include="System.Drawing" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Windows.Forms" />
@@ -111,13 +110,11 @@
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<PropertyGroup>
<PostBuildEvent Condition=" '$(OS)' != 'Unix' AND '$(ConfigurationName)' == 'Release' ">
mkdir "$(SolutionDir)out" "$(SolutionDir)out\config"
"$(SolutionDir)tools\ILRepack.exe" /ndebug /internalize /parallel /targetplatform:v4 /wildcards /out:"$(SolutionDir)out\ASF-GUI.exe" "$(TargetDir)$(TargetName).exe" "$(TargetDir)*.dll"
"$(SolutionDir)tools\ILRepack\ILRepack.exe" /ndebug /internalize /parallel /targetplatform:v4 /wildcards /out:"$(SolutionDir)out\ASF-GUI.exe" "$(TargetDir)$(TargetName).exe" "$(TargetDir)*.dll"
del "$(SolutionDir)out\ASF-GUI.exe.config"
</PostBuildEvent>
<PostBuildEvent Condition=" '$(OS)' == 'Unix' AND '$(ConfigurationName)' == 'Release' ">
mkdir -p "$(SolutionDir)out" "$(SolutionDir)out/config"
mono -O=all "$(SolutionDir)tools/ILRepack.exe" /ndebug /internalize /parallel /targetplatform:v4 /wildcards /out:"$(SolutionDir)out/ASF-GUI.exe" "$(TargetDir)$(TargetName).exe" "$(TargetDir)*.dll"
mono -O=all "$(SolutionDir)tools/ILRepack/ILRepack.exe" /ndebug /internalize /parallel /targetplatform:v4 /wildcards /out:"$(SolutionDir)out/ASF-GUI.exe" "$(TargetDir)$(TargetName).exe" "$(TargetDir)*.dll"
rm "$(SolutionDir)out/ASF-GUI.exe.config"
</PostBuildEvent>
</PropertyGroup>

View File

@@ -22,9 +22,6 @@
*/
using System;
using System.IO;
namespace ConfigGenerator {
internal static class Debugging {
#if DEBUG

View File

@@ -27,6 +27,7 @@ using System.Windows.Forms;
namespace ConfigGenerator {
internal sealed class EnhancedPropertyGrid : PropertyGrid {
private ASFConfig ASFConfig;
internal EnhancedPropertyGrid(ASFConfig config) : base() {
if (config == null) {
return;

View File

@@ -36,6 +36,13 @@ namespace ConfigGenerator {
Experimental
}
private const byte DefaultMaxFarmingTime = 10;
private const byte DefaultFarmingDelay = 5;
private const byte DefaultHttpTimeout = 60;
private const ushort DefaultWCFPort = 1242;
private static readonly ProtocolType DefaultSteamProtocol = ProtocolType.Tcp;
// This is hardcoded blacklist which should not be possible to change
internal static readonly HashSet<uint> GlobalBlacklist = new HashSet<uint> { 267420, 303700, 335590, 368020, 425280 };
@@ -49,19 +56,19 @@ namespace ConfigGenerator {
public EUpdateChannel UpdateChannel { get; set; } = EUpdateChannel.Stable;
[JsonProperty(Required = Required.DisallowNull)]
public ProtocolType SteamProtocol { get; set; } = ProtocolType.Tcp;
public ProtocolType SteamProtocol { get; set; } = DefaultSteamProtocol;
[JsonProperty(Required = Required.DisallowNull)]
public ulong SteamOwnerID { get; set; } = 0;
[JsonProperty(Required = Required.DisallowNull)]
public byte MaxFarmingTime { get; set; } = 10;
public byte MaxFarmingTime { get; set; } = DefaultMaxFarmingTime;
[JsonProperty(Required = Required.DisallowNull)]
public byte IdleFarmingPeriod { get; set; } = 3;
[JsonProperty(Required = Required.DisallowNull)]
public byte FarmingDelay { get; set; } = 5;
public byte FarmingDelay { get; set; } = DefaultFarmingDelay;
[JsonProperty(Required = Required.DisallowNull)]
public byte AccountPlayingDelay { get; set; } = 5;
@@ -76,13 +83,13 @@ namespace ConfigGenerator {
public bool ForceHttp { get; set; } = false;
[JsonProperty(Required = Required.DisallowNull)]
public byte HttpTimeout { get; set; } = 60;
public byte HttpTimeout { get; set; } = DefaultHttpTimeout;
[JsonProperty(Required = Required.DisallowNull)]
[JsonProperty]
public string WCFHostname { get; set; } = "localhost";
[JsonProperty(Required = Required.DisallowNull)]
public ushort WCFPort { get; set; } = 1242;
public ushort WCFPort { get; set; } = DefaultWCFPort;
[JsonProperty(Required = Required.DisallowNull)]
public bool LogToFile { get; set; } = true;
@@ -117,17 +124,39 @@ namespace ConfigGenerator {
globalConfig.FilePath = filePath;
// SK2 supports only TCP and UDP steam protocols
// Make sure that user can't screw this up
// Ensure that user can't screw this up
switch (globalConfig.SteamProtocol) {
case ProtocolType.Tcp:
case ProtocolType.Udp:
break;
default:
Logging.LogGenericWarning("Configured SteamProtocol is invalid: " + globalConfig.SteamProtocol + ", default TCP protocol will be used instead");
globalConfig.SteamProtocol = ProtocolType.Tcp;
Logging.LogGenericWarning("Configured SteamProtocol is invalid: " + globalConfig.SteamProtocol + ". Value of " + DefaultSteamProtocol + " will be used instead");
globalConfig.SteamProtocol = DefaultSteamProtocol;
break;
}
// User might not know what he's doing
// Ensure that he can't screw core ASF variables
if (globalConfig.MaxFarmingTime == 0) {
Logging.LogGenericWarning("Configured MaxFarmingTime is invalid: " + globalConfig.MaxFarmingTime + ". Value of " + DefaultMaxFarmingTime + " will be used instead");
globalConfig.MaxFarmingTime = DefaultMaxFarmingTime;
}
if (globalConfig.FarmingDelay == 0) {
Logging.LogGenericWarning("Configured FarmingDelay is invalid: " + globalConfig.FarmingDelay + ". Value of " + DefaultFarmingDelay + " will be used instead");
globalConfig.FarmingDelay = DefaultFarmingDelay;
}
if (globalConfig.HttpTimeout == 0) {
Logging.LogGenericWarning("Configured HttpTimeout is invalid: " + globalConfig.HttpTimeout + ". Value of " + DefaultHttpTimeout + " will be used instead");
globalConfig.HttpTimeout = DefaultHttpTimeout;
}
if (globalConfig.WCFPort == 0) {
Logging.LogGenericWarning("Configured WCFPort is invalid: " + globalConfig.WCFPort + ". Value of " + DefaultWCFPort + " will be used instead");
globalConfig.WCFPort = DefaultWCFPort;
}
return globalConfig;
}

View File

@@ -32,28 +32,30 @@
this.MainTab.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.MainTab.Appearance = System.Windows.Forms.TabAppearance.Buttons;
this.MainTab.Font = new System.Drawing.Font("Segoe UI", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
this.MainTab.HotTrack = true;
this.MainTab.Location = new System.Drawing.Point(16, 13);
this.MainTab.Location = new System.Drawing.Point(14, 14);
this.MainTab.Margin = new System.Windows.Forms.Padding(4, 4, 4, 4);
this.MainTab.Multiline = true;
this.MainTab.Name = "MainTab";
this.MainTab.SelectedIndex = 0;
this.MainTab.Size = new System.Drawing.Size(748, 529);
this.MainTab.Size = new System.Drawing.Size(854, 745);
this.MainTab.SizeMode = System.Windows.Forms.TabSizeMode.Fixed;
this.MainTab.TabIndex = 1;
this.MainTab.Selected += new System.Windows.Forms.TabControlEventHandler(this.MainTab_Selected);
this.MainTab.Deselecting += new System.Windows.Forms.TabControlCancelEventHandler(this.MainTab_Deselecting);
//
// MainForm
//
this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 16F);
this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 17F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.AutoScroll = true;
this.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;
this.ClientSize = new System.Drawing.Size(780, 557);
this.ClientSize = new System.Drawing.Size(882, 774);
this.Controls.Add(this.MainTab);
this.Cursor = System.Windows.Forms.Cursors.Default;
this.DoubleBuffered = true;
this.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.Fixed3D;
this.Font = new System.Drawing.Font("Segoe UI", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
this.HelpButton = true;
this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
this.Margin = new System.Windows.Forms.Padding(4, 4, 4, 4);

View File

@@ -1,7 +1,12 @@
ArchiSteamFarm
===================
[![Build status](https://ci.appveyor.com/api/projects/status/yi0y25nipcb1j1yj?svg=true)](https://ci.appveyor.com/project/JustArchi/archisteamfarm) [![GitHub release](https://img.shields.io/github/release/JustArchi/ArchiSteamFarm.svg)](https://github.com/JustArchi/ArchiSteamFarm/releases/latest) [![Github All Releases](https://img.shields.io/github/downloads/JustArchi/ArchiSteamFarm/total.svg)](https://github.com/JustArchi/ArchiSteamFarm/releases) [![Paypal donate](https://img.shields.io/badge/paypal-donate-yellow.svg)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=HD2P2P3WGS5Y4) [![Steam donate](https://img.shields.io/badge/steam-donate-yellow.svg)](https://steamcommunity.com/tradeoffer/new/?partner=46697991&token=0ix2Ruv_)
[![Build Status (Windows)](https://img.shields.io/appveyor/ci/JustArchi/ArchiSteamFarm.svg?label=Windows)](https://ci.appveyor.com/project/JustArchi/ArchiSteamFarm)
[![Build Status (Mono)](https://img.shields.io/travis/JustArchi/ArchiSteamFarm.svg?label=Mono)](https://travis-ci.org/JustArchi/ArchiSteamFarm)
[![GitHub Release](https://img.shields.io/github/release/JustArchi/ArchiSteamFarm.svg?label=Latest)](https://github.com/JustArchi/ArchiSteamFarm/releases/latest)
[![Github All Releases](https://img.shields.io/github/downloads/JustArchi/ArchiSteamFarm/total.svg?label=Downloads)](https://github.com/JustArchi/ArchiSteamFarm/releases)
[![Paypal Donate](https://img.shields.io/badge/Paypal-donate-yellow.svg)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=HD2P2P3WGS5Y4)
[![Steam Donate](https://img.shields.io/badge/Steam-donate-yellow.svg)](https://steamcommunity.com/tradeoffer/new/?partner=46697991&token=0ix2Ruv_)
---

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
tools/ILRepack/ILRepack.exe Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

17
tools/NetHook2/README.md Normal file
View File

@@ -0,0 +1,17 @@
NetHook2
===================
This tool is used for reverse-engineering of Steam client. It's capable of hooking and recording network traffic sent/received by the client. If you're not trying to implement missing SK2 functionality in ASF, then please do not proceed.
1. Launch Steam client
2. Execute ```hook.bat```
3. Reproduce the functionality you're trying to add
4. Execute ```unhook.bat```
5. Use ```NetHookAnalyzer2.exe``` for analyzing recorded log (which can be found in your Steam directory)
- Source of the ```NetHook2.dll``` can be found **[here](https://github.com/SteamRE/SteamKit/tree/master/Resources/NetHook2)**
- Source of the ```NetHookAnalyzer2.exe``` can be found **[here](https://github.com/SteamRE/SteamKit/tree/master/Resources/NetHookAnalyzer2)**
===================
There is absolutely no guarantee that this will even work for you, not to mention the consequences from hooking the external DLL into steam client. You're on your own.