mirror of
https://github.com/JustArchiNET/ArchiSteamFarm.git
synced 2025-12-17 15:00:29 +00:00
Compare commits
206 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cd7b65868a | ||
|
|
7575704a01 | ||
|
|
b6ce8f435c | ||
|
|
565acca9fb | ||
|
|
610954ba73 | ||
|
|
74a748b03f | ||
|
|
585a075ec9 | ||
|
|
891d40afe1 | ||
|
|
387f0dd1c7 | ||
|
|
8b4d3c219c | ||
|
|
365877ec89 | ||
|
|
f03a43d573 | ||
|
|
d15a9cbfca | ||
|
|
acfad624fb | ||
|
|
03a7d5f4ac | ||
|
|
0f96d84d36 | ||
|
|
0edc9f4ff6 | ||
|
|
d11e141ece | ||
|
|
9ff3834ed7 | ||
|
|
9806703cfa | ||
|
|
ca0857abd1 | ||
|
|
d32d3bfd36 | ||
|
|
6efb07eada | ||
|
|
2b28f01b1c | ||
|
|
fb350fe792 | ||
|
|
5e73d18cd2 | ||
|
|
3ff95995b9 | ||
|
|
17b2bc2259 | ||
|
|
4a36345635 | ||
|
|
e9d8f271a2 | ||
|
|
6c84f8eb4f | ||
|
|
54ad58a22d | ||
|
|
790e6baf46 | ||
|
|
c8fb715558 | ||
|
|
2ab5e6013d | ||
|
|
3e0c34e62c | ||
|
|
65b31e5537 | ||
|
|
62a6e38e47 | ||
|
|
0b50a45336 | ||
|
|
8d1d162b02 | ||
|
|
dbe13a1965 | ||
|
|
fc13633f5e | ||
|
|
d0cc10f3c6 | ||
|
|
567931a4cc | ||
|
|
396dc17ab2 | ||
|
|
288cc29338 | ||
|
|
844ca7da94 | ||
|
|
b14b9f87c7 | ||
|
|
8aa086cc27 | ||
|
|
cf00989d84 | ||
|
|
8f2f85282c | ||
|
|
fa12ffd9d0 | ||
|
|
ecb27adedd | ||
|
|
6e9be09944 | ||
|
|
6a79a89a10 | ||
|
|
d67be4f092 | ||
|
|
a8e1039e32 | ||
|
|
2ad9d9e197 | ||
|
|
fd6e2c72d7 | ||
|
|
1eed0f7647 | ||
|
|
c018c08260 | ||
|
|
72fa98cb89 | ||
|
|
71215d695e | ||
|
|
75b785d4b6 | ||
|
|
12e32692cb | ||
|
|
6158a9268d | ||
|
|
a48e53585a | ||
|
|
33383633ea | ||
|
|
3f7359c608 | ||
|
|
d8b59c6889 | ||
|
|
0f71b788cb | ||
|
|
d012255a21 | ||
|
|
8fc39a44cd | ||
|
|
c6fe424fcc | ||
|
|
12488dafd3 | ||
|
|
3b53491567 | ||
|
|
e337bd3856 | ||
|
|
cc47c0a764 | ||
|
|
22e4c0cd40 | ||
|
|
20b47e1787 | ||
|
|
941da0658d | ||
|
|
8048d4a7aa | ||
|
|
2554794daa | ||
|
|
4fcee90b99 | ||
|
|
761d73eb90 | ||
|
|
c163e5e2f3 | ||
|
|
8fd41cc587 | ||
|
|
f195563ba5 | ||
|
|
33df54365a | ||
|
|
4a6ae3064a | ||
|
|
84857e060b | ||
|
|
3311f2a703 | ||
|
|
5666ebf891 | ||
|
|
0ded4f3b80 | ||
|
|
4c9354308c | ||
|
|
0bcf2f35b7 | ||
|
|
b93d5187d6 | ||
|
|
1426922854 | ||
|
|
d8925f9409 | ||
|
|
4302029bee | ||
|
|
01a7800a44 | ||
|
|
ab3cf5b8d0 | ||
|
|
2ab9741fa8 | ||
|
|
f1c3339764 | ||
|
|
da01d4eab3 | ||
|
|
cd9bd5f0dd | ||
|
|
2602ac3623 | ||
|
|
2fe8db712e | ||
|
|
687b20bcb5 | ||
|
|
23d9dcffe7 | ||
|
|
42623ffb5a | ||
|
|
214003edbd | ||
|
|
c21333b6e9 | ||
|
|
630f1c008c | ||
|
|
68977b7907 | ||
|
|
6dade5440e | ||
|
|
10fcfae171 | ||
|
|
320055680b | ||
|
|
84a99c3696 | ||
|
|
df415c8db5 | ||
|
|
9bc04640a1 | ||
|
|
d6c1bdb9b5 | ||
|
|
7276350f74 | ||
|
|
7d3c05088a | ||
|
|
41c2bd9131 | ||
|
|
514a9f38c8 | ||
|
|
5cc884639f | ||
|
|
f77cb6d33b | ||
|
|
b642f4b240 | ||
|
|
6de721089c | ||
|
|
4bd48c399a | ||
|
|
2b3a5ff337 | ||
|
|
0387eb3746 | ||
|
|
3ebc6d618a | ||
|
|
92d9e10cb8 | ||
|
|
d0d670f1a5 | ||
|
|
3597c8f138 | ||
|
|
8a8ec29b41 | ||
|
|
a3352d032d | ||
|
|
d5f8647fcc | ||
|
|
79a700d786 | ||
|
|
bc223f0644 | ||
|
|
2b0d82453b | ||
|
|
fa0150e745 | ||
|
|
c95d11ef66 | ||
|
|
63b268f9c4 | ||
|
|
03d38f8a2a | ||
|
|
c88d9bf123 | ||
|
|
053ebe15bb | ||
|
|
b03bfb6bbc | ||
|
|
e48867000e | ||
|
|
e08cdbd74d | ||
|
|
0b4c585a58 | ||
|
|
6213e77fab | ||
|
|
fccca6a4fc | ||
|
|
d4f4ec3401 | ||
|
|
b23dd3612d | ||
|
|
ca4fa4ac27 | ||
|
|
5e53a208d5 | ||
|
|
895c69642d | ||
|
|
765f9d29bb | ||
|
|
99af5c86a5 | ||
|
|
0bb2b3ed5f | ||
|
|
4181f3ba21 | ||
|
|
c189b398c0 | ||
|
|
de4fbf8b04 | ||
|
|
f91a558314 | ||
|
|
7587ff024c | ||
|
|
06778c9bb0 | ||
|
|
7a97045412 | ||
|
|
5d9bedfd28 | ||
|
|
575992c25d | ||
|
|
72db5bc9f3 | ||
|
|
b015720a3e | ||
|
|
84a6d4501b | ||
|
|
07049e71c0 | ||
|
|
4710d9c1eb | ||
|
|
d08462745a | ||
|
|
eb4e9ee077 | ||
|
|
601a486b13 | ||
|
|
14867f470d | ||
|
|
187f0800b2 | ||
|
|
3afa202d0b | ||
|
|
d33e76c8b0 | ||
|
|
3061c55eaf | ||
|
|
621a1dc2cb | ||
|
|
1a832780a2 | ||
|
|
ab531c80df | ||
|
|
f20ea0a87f | ||
|
|
3e7f726afb | ||
|
|
d247515a03 | ||
|
|
f084a3f219 | ||
|
|
4d3673c305 | ||
|
|
0253c3bf7b | ||
|
|
0eae895676 | ||
|
|
045acb362d | ||
|
|
ebd65da3ff | ||
|
|
1de3c5bec0 | ||
|
|
b334c939df | ||
|
|
8e6100e236 | ||
|
|
8cb512b6e5 | ||
|
|
6a28946205 | ||
|
|
c632c025cb | ||
|
|
1403ffe190 | ||
|
|
71ae9a84da | ||
|
|
a823471771 |
3
.gitignore
vendored
3
.gitignore
vendored
@@ -12,6 +12,9 @@ ArchiSteamFarm/config/*
|
|||||||
ArchiSteamFarm/log.txt
|
ArchiSteamFarm/log.txt
|
||||||
ArchiSteamFarm/debug/*
|
ArchiSteamFarm/debug/*
|
||||||
|
|
||||||
|
# Ignore out
|
||||||
|
out/
|
||||||
|
|
||||||
#################
|
#################
|
||||||
## Eclipse
|
## Eclipse
|
||||||
#################
|
#################
|
||||||
|
|||||||
10
.travis.yml
Normal file
10
.travis.yml
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
sudo: false
|
||||||
|
language: csharp
|
||||||
|
solution: ArchiSteamFarm.sln
|
||||||
|
|
||||||
|
git:
|
||||||
|
depth: 10
|
||||||
|
|
||||||
|
mono:
|
||||||
|
- weekly
|
||||||
|
- latest
|
||||||
@@ -1,12 +1,22 @@
|
|||||||
|
|
||||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
# Visual Studio 14
|
# Visual Studio 14
|
||||||
VisualStudioVersion = 14.0.23107.0
|
VisualStudioVersion = 14.0.24720.0
|
||||||
MinimumVisualStudioVersion = 10.0.40219.1
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ArchiSteamFarm", "ArchiSteamFarm\ArchiSteamFarm.csproj", "{35AF7887-08B9-40E8-A5EA-797D8B60B30C}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ArchiSteamFarm", "ArchiSteamFarm\ArchiSteamFarm.csproj", "{35AF7887-08B9-40E8-A5EA-797D8B60B30C}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SteamAuth", "SteamAuth\SteamAuth.csproj", "{5AD0934E-F6C4-4AE5-83AF-C788313B2A87}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SteamAuth", "SteamAuth\SteamAuth.csproj", "{5AD0934E-F6C4-4AE5-83AF-C788313B2A87}"
|
||||||
EndProject
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ConfigGenerator", "ConfigGenerator\ConfigGenerator.csproj", "{C3F6FE68-5E75-415E-BEA1-1E7C16D6A433}"
|
||||||
|
ProjectSection(ProjectDependencies) = postProject
|
||||||
|
{35AF7887-08B9-40E8-A5EA-797D8B60B30C} = {35AF7887-08B9-40E8-A5EA-797D8B60B30C}
|
||||||
|
EndProjectSection
|
||||||
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GUI", "GUI\GUI.csproj", "{599121A9-5887-4522-A3D6-61470B90BAD4}"
|
||||||
|
ProjectSection(ProjectDependencies) = postProject
|
||||||
|
{35AF7887-08B9-40E8-A5EA-797D8B60B30C} = {35AF7887-08B9-40E8-A5EA-797D8B60B30C}
|
||||||
|
EndProjectSection
|
||||||
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Any CPU = Debug|Any CPU
|
Debug|Any CPU = Debug|Any CPU
|
||||||
@@ -21,6 +31,14 @@ Global
|
|||||||
{5AD0934E-F6C4-4AE5-83AF-C788313B2A87}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{5AD0934E-F6C4-4AE5-83AF-C788313B2A87}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{5AD0934E-F6C4-4AE5-83AF-C788313B2A87}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{5AD0934E-F6C4-4AE5-83AF-C788313B2A87}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{5AD0934E-F6C4-4AE5-83AF-C788313B2A87}.Release|Any CPU.Build.0 = Release|Any CPU
|
{5AD0934E-F6C4-4AE5-83AF-C788313B2A87}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{C3F6FE68-5E75-415E-BEA1-1E7C16D6A433}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{C3F6FE68-5E75-415E-BEA1-1E7C16D6A433}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{C3F6FE68-5E75-415E-BEA1-1E7C16D6A433}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{C3F6FE68-5E75-415E-BEA1-1E7C16D6A433}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{599121A9-5887-4522-A3D6-61470B90BAD4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{599121A9-5887-4522-A3D6-61470B90BAD4}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{599121A9-5887-4522-A3D6-61470B90BAD4}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{599121A9-5887-4522-A3D6-61470B90BAD4}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
|
|||||||
@@ -32,6 +32,16 @@ using System.Threading.Tasks;
|
|||||||
|
|
||||||
namespace ArchiSteamFarm {
|
namespace ArchiSteamFarm {
|
||||||
internal sealed class ArchiHandler : ClientMsgHandler {
|
internal sealed class ArchiHandler : ClientMsgHandler {
|
||||||
|
private readonly Bot Bot;
|
||||||
|
|
||||||
|
internal ArchiHandler(Bot bot) {
|
||||||
|
if (bot == null) {
|
||||||
|
throw new ArgumentNullException("bot");
|
||||||
|
}
|
||||||
|
|
||||||
|
Bot = bot;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
____ _ _ _ _
|
____ _ _ _ _
|
||||||
/ ___| __ _ | || || |__ __ _ ___ | | __ ___
|
/ ___| __ _ | || || |__ __ _ ___ | | __ ___
|
||||||
@@ -257,14 +267,45 @@ namespace ArchiSteamFarm {
|
|||||||
request.Body.key = key;
|
request.Body.key = key;
|
||||||
|
|
||||||
Client.Send(request);
|
Client.Send(request);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return await new AsyncJob<PurchaseResponseCallback>(Client, request.SourceJobID);
|
return await new AsyncJob<PurchaseResponseCallback>(Client, request.SourceJobID);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Logging.LogGenericException(e);
|
Logging.LogGenericException(e, Bot.BotName);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: Please remove me immediately after https://github.com/SteamRE/SteamKit/issues/254 gets fixed
|
||||||
|
internal void HackedLogOn(SteamUser.LogOnDetails details) {
|
||||||
|
if (!Client.IsConnected) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
SteamID steamID = new SteamID(details.AccountID, details.AccountInstance, Client.ConnectedUniverse, EAccountType.Individual);
|
||||||
|
|
||||||
|
var logon = new ClientMsgProtobuf<CMsgClientLogon>(EMsg.ClientLogon);
|
||||||
|
logon.Body.obfustucated_private_ip = details.LoginID.Value;
|
||||||
|
logon.ProtoHeader.client_sessionid = 0;
|
||||||
|
logon.ProtoHeader.steamid = steamID.ConvertToUInt64();
|
||||||
|
logon.Body.account_name = details.Username;
|
||||||
|
logon.Body.password = details.Password;
|
||||||
|
logon.Body.should_remember_password = details.ShouldRememberPassword;
|
||||||
|
logon.Body.protocol_version = MsgClientLogon.CurrentProtocol;
|
||||||
|
logon.Body.client_os_type = (uint) details.ClientOSType;
|
||||||
|
logon.Body.client_language = details.ClientLanguage;
|
||||||
|
logon.Body.cell_id = details.CellID;
|
||||||
|
logon.Body.steam2_ticket_request = details.RequestSteam2Ticket;
|
||||||
|
logon.Body.client_package_version = 1771;
|
||||||
|
logon.Body.auth_code = details.AuthCode;
|
||||||
|
logon.Body.two_factor_code = details.TwoFactorCode;
|
||||||
|
logon.Body.login_key = details.LoginKey;
|
||||||
|
logon.Body.sha_sentryfile = details.SentryFileHash;
|
||||||
|
logon.Body.eresult_sentryfile = (int) (details.SentryFileHash != null ? EResult.OK : EResult.FileNotFound);
|
||||||
|
|
||||||
|
Client.Send(logon);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
_ _ _ _
|
_ _ _ _
|
||||||
| | | | __ _ _ __ __| || | ___ _ __ ___
|
| | | | __ _ _ __ __| || | ___ _ __ ___
|
||||||
|
|||||||
@@ -76,7 +76,7 @@
|
|||||||
<Private>True</Private>
|
<Private>True</Private>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="Newtonsoft.Json, Version=8.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
|
<Reference Include="Newtonsoft.Json, Version=8.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
|
||||||
<HintPath>..\packages\Newtonsoft.Json.8.0.2\lib\net45\Newtonsoft.Json.dll</HintPath>
|
<HintPath>..\packages\Newtonsoft.Json.8.0.3\lib\net45\Newtonsoft.Json.dll</HintPath>
|
||||||
<Private>True</Private>
|
<Private>True</Private>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="protobuf-net, Version=2.0.0.668, Culture=neutral, PublicKeyToken=257b51d87d2e4d67, processorArchitecture=MSIL">
|
<Reference Include="protobuf-net, Version=2.0.0.668, Culture=neutral, PublicKeyToken=257b51d87d2e4d67, processorArchitecture=MSIL">
|
||||||
@@ -90,10 +90,7 @@
|
|||||||
<Reference Include="System" />
|
<Reference Include="System" />
|
||||||
<Reference Include="System.Core" />
|
<Reference Include="System.Core" />
|
||||||
<Reference Include="System.ServiceModel" />
|
<Reference Include="System.ServiceModel" />
|
||||||
<Reference Include="System.Xml.Linq" />
|
|
||||||
<Reference Include="System.Data.DataSetExtensions" />
|
|
||||||
<Reference Include="Microsoft.CSharp" />
|
<Reference Include="Microsoft.CSharp" />
|
||||||
<Reference Include="System.Data" />
|
|
||||||
<Reference Include="System.Net.Http" />
|
<Reference Include="System.Net.Http" />
|
||||||
<Reference Include="System.Xml" />
|
<Reference Include="System.Xml" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
@@ -105,17 +102,14 @@
|
|||||||
<Compile Include="GlobalDatabase.cs" />
|
<Compile Include="GlobalDatabase.cs" />
|
||||||
<Compile Include="BotDatabase.cs" />
|
<Compile Include="BotDatabase.cs" />
|
||||||
<Compile Include="CardsFarmer.cs" />
|
<Compile Include="CardsFarmer.cs" />
|
||||||
<Compile Include="CMsgClientClanInviteAction.cs" />
|
<Compile Include="CMsgs\CMsgClientClanInviteAction.cs" />
|
||||||
<Compile Include="Debugging.cs" />
|
<Compile Include="Debugging.cs" />
|
||||||
<Compile Include="GlobalConfig.cs" />
|
<Compile Include="GlobalConfig.cs" />
|
||||||
<Compile Include="JSON\GitHub.cs" />
|
<Compile Include="JSON\GitHub.cs" />
|
||||||
|
<Compile Include="JSON\Steam.cs" />
|
||||||
<Compile Include="Logging.cs" />
|
<Compile Include="Logging.cs" />
|
||||||
<Compile Include="Program.cs" />
|
<Compile Include="Program.cs" />
|
||||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
<Compile Include="SteamItem.cs" />
|
|
||||||
<Compile Include="SteamItemList.cs" />
|
|
||||||
<Compile Include="SteamTradeOffer.cs" />
|
|
||||||
<Compile Include="SteamTradeOfferRequest.cs" />
|
|
||||||
<Compile Include="Trading.cs" />
|
<Compile Include="Trading.cs" />
|
||||||
<Compile Include="Utilities.cs" />
|
<Compile Include="Utilities.cs" />
|
||||||
<Compile Include="WCF.cs" />
|
<Compile Include="WCF.cs" />
|
||||||
@@ -163,20 +157,20 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<PostBuildEvent Condition=" '$(OS)' != 'Unix' AND '$(ConfigurationName)' == 'Release' ">
|
<PostBuildEvent Condition=" '$(OS)' != 'Unix' AND '$(ConfigurationName)' == 'Release' ">
|
||||||
mkdir "$(TargetDir)out" "$(TargetDir)out\config"
|
mkdir "$(SolutionDir)out\config"
|
||||||
copy "$(TargetDir)config\ASF.json" "$(TargetDir)out\config"
|
copy "$(TargetDir)config\ASF.json" "$(SolutionDir)out\config"
|
||||||
copy "$(TargetDir)config\example.json" "$(TargetDir)out\config"
|
copy "$(TargetDir)config\example.json" "$(SolutionDir)out\config"
|
||||||
copy "$(TargetDir)config\minimal.json" "$(TargetDir)out\config"
|
copy "$(TargetDir)config\minimal.json" "$(SolutionDir)out\config"
|
||||||
"$(SolutionDir)tools\ILRepack.exe" /ndebug /internalize /parallel /targetplatform:v4 /wildcards /out:"$(TargetDir)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 "$(TargetDir)out\ASF.exe.config"
|
del "$(SolutionDir)out\ASF.exe.config"
|
||||||
</PostBuildEvent>
|
</PostBuildEvent>
|
||||||
<PostBuildEvent Condition=" '$(OS)' == 'Unix' AND '$(ConfigurationName)' == 'Release' ">
|
<PostBuildEvent Condition=" '$(OS)' == 'Unix' AND '$(ConfigurationName)' == 'Release' ">
|
||||||
mkdir -p "$(TargetDir)out" "$(TargetDir)out/config"
|
mkdir -p "$(SolutionDir)out/config"
|
||||||
cp "$(TargetDir)config/ASF.json" "$(TargetDir)out/config"
|
cp "$(TargetDir)config/ASF.json" "$(SolutionDir)out/config"
|
||||||
cp "$(TargetDir)config/example.json" "$(TargetDir)out/config"
|
cp "$(TargetDir)config/example.json" "$(SolutionDir)out/config"
|
||||||
cp "$(TargetDir)config/minimal.json" "$(TargetDir)out/config"
|
cp "$(TargetDir)config/minimal.json" "$(SolutionDir)out/config"
|
||||||
mono -O=all "$(SolutionDir)tools/ILRepack.exe" /ndebug /internalize /parallel /targetplatform:v4 /wildcards /out:"$(TargetDir)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 "$(TargetDir)out/ASF.exe.config"
|
rm "$(SolutionDir)out/ASF.exe.config"
|
||||||
</PostBuildEvent>
|
</PostBuildEvent>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||||
|
|||||||
@@ -31,38 +31,53 @@ using System.Net;
|
|||||||
using System.Net.Http;
|
using System.Net.Http;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using System.Xml;
|
||||||
|
using System.Threading;
|
||||||
|
|
||||||
namespace ArchiSteamFarm {
|
namespace ArchiSteamFarm {
|
||||||
internal sealed class ArchiWebHandler {
|
internal sealed class ArchiWebHandler {
|
||||||
private static int Timeout = 30 * 1000;
|
private const string SteamCommunity = "steamcommunity.com";
|
||||||
|
private const byte MinSessionTTL = 15; // Assume session is valid for at least that amount of seconds
|
||||||
|
|
||||||
|
private static string SteamCommunityURL = "https://" + SteamCommunity;
|
||||||
|
|
||||||
|
private static int Timeout = GlobalConfig.DefaultHttpTimeout * 1000;
|
||||||
|
|
||||||
private readonly Bot Bot;
|
private readonly Bot Bot;
|
||||||
private readonly Dictionary<string, string> Cookie = new Dictionary<string, string>(4);
|
private readonly SemaphoreSlim SessionSemaphore = new SemaphoreSlim(1);
|
||||||
|
private readonly WebBrowser WebBrowser;
|
||||||
|
|
||||||
private ulong SteamID;
|
private DateTime LastSessionRefreshCheck = DateTime.MinValue;
|
||||||
|
|
||||||
internal static void Init() {
|
internal static void Init() {
|
||||||
Timeout = Program.GlobalConfig.HttpTimeout * 1000;
|
Timeout = Program.GlobalConfig.HttpTimeout * 1000;
|
||||||
|
SteamCommunityURL = (Program.GlobalConfig.ForceHttp ? "http://" : "https://") + SteamCommunity;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal ArchiWebHandler(Bot bot) {
|
internal ArchiWebHandler(Bot bot) {
|
||||||
|
if (bot == null) {
|
||||||
|
throw new ArgumentNullException("bot");
|
||||||
|
}
|
||||||
|
|
||||||
Bot = bot;
|
Bot = bot;
|
||||||
|
|
||||||
|
WebBrowser = new WebBrowser(bot.BotName);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal async Task<bool> Init(SteamClient steamClient, string webAPIUserNonce, string parentalPin) {
|
internal bool Init(SteamClient steamClient, string webAPIUserNonce, string parentalPin) {
|
||||||
if (steamClient == null || steamClient.SteamID == null || string.IsNullOrEmpty(webAPIUserNonce)) {
|
if (steamClient == null || steamClient.SteamID == null || string.IsNullOrEmpty(webAPIUserNonce)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
SteamID = steamClient.SteamID;
|
ulong steamID = steamClient.SteamID;
|
||||||
|
|
||||||
string sessionID = Convert.ToBase64String(Encoding.UTF8.GetBytes(SteamID.ToString()));
|
string sessionID = Convert.ToBase64String(Encoding.UTF8.GetBytes(steamID.ToString()));
|
||||||
|
|
||||||
// Generate an AES session key
|
// Generate an AES session key
|
||||||
byte[] sessionKey = CryptoHelper.GenerateRandomBlock(32);
|
byte[] sessionKey = CryptoHelper.GenerateRandomBlock(32);
|
||||||
|
|
||||||
// RSA encrypt it with the public key for the universe we're on
|
// RSA encrypt it with the public key for the universe we're on
|
||||||
byte[] cryptedSessionKey = null;
|
byte[] cryptedSessionKey;
|
||||||
using (RSACrypto rsa = new RSACrypto(KeyDictionary.GetPublicKey(steamClient.ConnectedUniverse))) {
|
using (RSACrypto rsa = new RSACrypto(KeyDictionary.GetPublicKey(steamClient.ConnectedUniverse))) {
|
||||||
cryptedSessionKey = rsa.Encrypt(sessionKey);
|
cryptedSessionKey = rsa.Encrypt(sessionKey);
|
||||||
}
|
}
|
||||||
@@ -83,11 +98,11 @@ namespace ArchiSteamFarm {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
authResult = iSteamUserAuth.AuthenticateUser(
|
authResult = iSteamUserAuth.AuthenticateUser(
|
||||||
steamid: SteamID,
|
steamid: steamID,
|
||||||
sessionkey: Encoding.ASCII.GetString(WebUtility.UrlEncodeToBytes(cryptedSessionKey, 0, cryptedSessionKey.Length)),
|
sessionkey: Encoding.ASCII.GetString(WebUtility.UrlEncodeToBytes(cryptedSessionKey, 0, cryptedSessionKey.Length)),
|
||||||
encrypted_loginkey: Encoding.ASCII.GetString(WebUtility.UrlEncodeToBytes(cryptedLoginKey, 0, cryptedLoginKey.Length)),
|
encrypted_loginkey: Encoding.ASCII.GetString(WebUtility.UrlEncodeToBytes(cryptedLoginKey, 0, cryptedLoginKey.Length)),
|
||||||
method: WebRequestMethods.Http.Post,
|
method: WebRequestMethods.Http.Post,
|
||||||
secure: true
|
secure: !Program.GlobalConfig.ForceHttp
|
||||||
);
|
);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Logging.LogGenericException(e, Bot.BotName);
|
Logging.LogGenericException(e, Bot.BotName);
|
||||||
@@ -101,28 +116,26 @@ namespace ArchiSteamFarm {
|
|||||||
|
|
||||||
Logging.LogGenericInfo("Success!", Bot.BotName);
|
Logging.LogGenericInfo("Success!", Bot.BotName);
|
||||||
|
|
||||||
string steamLogin = authResult["token"].AsString();
|
WebBrowser.CookieContainer.Add(new Cookie("sessionid", sessionID, "/", "." + SteamCommunity));
|
||||||
string steamLoginSecure = authResult["tokensecure"].AsString();
|
|
||||||
|
|
||||||
Cookie["sessionid"] = sessionID;
|
string steamLogin = authResult["token"].Value;
|
||||||
Cookie["steamLogin"] = steamLogin;
|
WebBrowser.CookieContainer.Add(new Cookie("steamLogin", steamLogin, "/", "." + SteamCommunity));
|
||||||
Cookie["steamLoginSecure"] = steamLoginSecure;
|
|
||||||
|
|
||||||
// The below is used for display purposes only
|
string steamLoginSecure = authResult["tokensecure"].Value;
|
||||||
Cookie["webTradeEligibility"] = "{\"allowed\":0,\"reason\":0,\"allowed_at_time\":0,\"steamguard_required_days\":0,\"sales_this_year\":0,\"max_sales_per_year\":0,\"forms_requested\":0}";
|
WebBrowser.CookieContainer.Add(new Cookie("steamLoginSecure", steamLoginSecure, "/", "." + SteamCommunity));
|
||||||
|
|
||||||
await UnlockParentalAccount(parentalPin).ConfigureAwait(false);
|
if (!UnlockParentalAccount(parentalPin).Result) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
LastSessionRefreshCheck = DateTime.Now;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal async Task<bool?> IsLoggedIn() {
|
internal async Task<bool?> IsLoggedIn() {
|
||||||
if (SteamID == 0) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
HtmlDocument htmlDocument = null;
|
HtmlDocument htmlDocument = null;
|
||||||
for (byte i = 0; i < WebBrowser.MaxRetries && htmlDocument == null; i++) {
|
for (byte i = 0; i < WebBrowser.MaxRetries && htmlDocument == null; i++) {
|
||||||
htmlDocument = await WebBrowser.UrlGetToHtmlDocument("https://steamcommunity.com/my/profile", Cookie).ConfigureAwait(false);
|
htmlDocument = await WebBrowser.UrlGetToHtmlDocument(SteamCommunityURL + "/my/profile").ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (htmlDocument == null) {
|
if (htmlDocument == null) {
|
||||||
@@ -134,18 +147,82 @@ namespace ArchiSteamFarm {
|
|||||||
return htmlNode != null;
|
return htmlNode != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal async Task<bool> ReconnectIfNeeded() {
|
internal async Task<bool> RefreshSessionIfNeeded() {
|
||||||
bool? isLoggedIn = await IsLoggedIn().ConfigureAwait(false);
|
DateTime now = DateTime.Now;
|
||||||
if (isLoggedIn.HasValue && !isLoggedIn.Value) {
|
if (now.Subtract(LastSessionRefreshCheck).TotalSeconds < MinSessionTTL) {
|
||||||
Logging.LogGenericInfo("Reconnecting because our sessionID expired!", Bot.BotName);
|
|
||||||
Task.Run(async () => await Bot.Restart().ConfigureAwait(false)).Forget();
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
await SessionSemaphore.WaitAsync().ConfigureAwait(false);
|
||||||
|
|
||||||
|
now = DateTime.Now;
|
||||||
|
if (now.Subtract(LastSessionRefreshCheck).TotalSeconds < MinSessionTTL) {
|
||||||
|
SessionSemaphore.Release();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool result;
|
||||||
|
|
||||||
|
bool? isLoggedIn = await IsLoggedIn().ConfigureAwait(false);
|
||||||
|
if (isLoggedIn.GetValueOrDefault(true)) {
|
||||||
|
result = true;
|
||||||
|
now = DateTime.Now;
|
||||||
|
LastSessionRefreshCheck = now;
|
||||||
|
} else {
|
||||||
|
Logging.LogGenericInfo("Refreshing our session!", Bot.BotName);
|
||||||
|
result = await Bot.RefreshSession().ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
SessionSemaphore.Release();
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal List<SteamTradeOffer> GetTradeOffers() {
|
internal async Task<Dictionary<uint, string>> GetOwnedGames() {
|
||||||
|
if (!await RefreshSessionIfNeeded().ConfigureAwait(false)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
string request = SteamCommunityURL + "/my/games/?xml=1";
|
||||||
|
|
||||||
|
XmlDocument response = null;
|
||||||
|
for (byte i = 0; i < WebBrowser.MaxRetries && response == null; i++) {
|
||||||
|
response = await WebBrowser.UrlGetToXML(request).ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (response == null) {
|
||||||
|
Logging.LogGenericWTF("Request failed even after " + WebBrowser.MaxRetries + " tries", Bot.BotName);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
XmlNodeList xmlNodeList = response.SelectNodes("gamesList/games/game");
|
||||||
|
if (xmlNodeList == null || xmlNodeList.Count == 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
Dictionary<uint, string> result = new Dictionary<uint, string>(xmlNodeList.Count);
|
||||||
|
foreach (XmlNode xmlNode in xmlNodeList) {
|
||||||
|
XmlNode appNode = xmlNode.SelectSingleNode("appID");
|
||||||
|
if (appNode == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint appID;
|
||||||
|
if (!uint.TryParse(appNode.InnerText, out appID)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
XmlNode nameNode = xmlNode.SelectSingleNode("name");
|
||||||
|
if (nameNode == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
result[appID] = nameNode.InnerText;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal List<Steam.TradeOffer> GetTradeOffers() {
|
||||||
if (string.IsNullOrEmpty(Bot.BotConfig.SteamApiKey)) {
|
if (string.IsNullOrEmpty(Bot.BotConfig.SteamApiKey)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -159,7 +236,7 @@ namespace ArchiSteamFarm {
|
|||||||
response = iEconService.GetTradeOffers(
|
response = iEconService.GetTradeOffers(
|
||||||
get_received_offers: 1,
|
get_received_offers: 1,
|
||||||
active_only: 1,
|
active_only: 1,
|
||||||
secure: true
|
secure: !Program.GlobalConfig.ForceHttp
|
||||||
);
|
);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Logging.LogGenericException(e, Bot.BotName);
|
Logging.LogGenericException(e, Bot.BotName);
|
||||||
@@ -172,15 +249,15 @@ namespace ArchiSteamFarm {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
List<SteamTradeOffer> result = new List<SteamTradeOffer>();
|
List<Steam.TradeOffer> result = new List<Steam.TradeOffer>();
|
||||||
foreach (KeyValue trade in response["trade_offers_received"].Children) {
|
foreach (KeyValue trade in response["trade_offers_received"].Children) {
|
||||||
SteamTradeOffer tradeOffer = new SteamTradeOffer {
|
Steam.TradeOffer tradeOffer = new Steam.TradeOffer {
|
||||||
tradeofferid = trade["tradeofferid"].AsString(),
|
tradeofferid = trade["tradeofferid"].AsString(),
|
||||||
accountid_other = trade["accountid_other"].AsInteger(),
|
accountid_other = (uint) trade["accountid_other"].AsUnsignedLong(), // TODO: Correct this when SK2 with https://github.com/SteamRE/SteamKit/pull/255 gets released
|
||||||
trade_offer_state = trade["trade_offer_state"].AsEnum<SteamTradeOffer.ETradeOfferState>()
|
trade_offer_state = trade["trade_offer_state"].AsEnum<Steam.TradeOffer.ETradeOfferState>()
|
||||||
};
|
};
|
||||||
foreach (KeyValue item in trade["items_to_give"].Children) {
|
foreach (KeyValue item in trade["items_to_give"].Children) {
|
||||||
tradeOffer.items_to_give.Add(new SteamItem {
|
tradeOffer.items_to_give.Add(new Steam.Item {
|
||||||
appid = item["appid"].AsString(),
|
appid = item["appid"].AsString(),
|
||||||
contextid = item["contextid"].AsString(),
|
contextid = item["contextid"].AsString(),
|
||||||
assetid = item["assetid"].AsString(),
|
assetid = item["assetid"].AsString(),
|
||||||
@@ -190,7 +267,7 @@ namespace ArchiSteamFarm {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
foreach (KeyValue item in trade["items_to_receive"].Children) {
|
foreach (KeyValue item in trade["items_to_receive"].Children) {
|
||||||
tradeOffer.items_to_receive.Add(new SteamItem {
|
tradeOffer.items_to_receive.Add(new Steam.Item {
|
||||||
appid = item["appid"].AsString(),
|
appid = item["appid"].AsString(),
|
||||||
contextid = item["contextid"].AsString(),
|
contextid = item["contextid"].AsString(),
|
||||||
assetid = item["assetid"].AsString(),
|
assetid = item["assetid"].AsString(),
|
||||||
@@ -210,24 +287,29 @@ namespace ArchiSteamFarm {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
string sessionID;
|
if (!await RefreshSessionIfNeeded().ConfigureAwait(false)) {
|
||||||
if (!Cookie.TryGetValue("sessionid", out sessionID)) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
string request = "https://steamcommunity.com/gid/" + clanID;
|
string sessionID = WebBrowser.CookieContainer.GetCookieValue(SteamCommunityURL, "sessionid");
|
||||||
|
if (string.IsNullOrEmpty(sessionID)) {
|
||||||
|
Logging.LogNullError("sessionID");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
string request = SteamCommunityURL + "/gid/" + clanID;
|
||||||
|
|
||||||
Dictionary<string, string> data = new Dictionary<string, string>(2) {
|
Dictionary<string, string> data = new Dictionary<string, string>(2) {
|
||||||
{"sessionID", sessionID},
|
{"sessionID", sessionID},
|
||||||
{"action", "join"}
|
{"action", "join"}
|
||||||
};
|
};
|
||||||
|
|
||||||
HttpResponseMessage response = null;
|
bool result = false;
|
||||||
for (byte i = 0; i < WebBrowser.MaxRetries && response == null; i++) {
|
for (byte i = 0; i < WebBrowser.MaxRetries && !result; i++) {
|
||||||
response = await WebBrowser.UrlPost(request, data, Cookie).ConfigureAwait(false);
|
result = await WebBrowser.UrlPost(request, data).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (response == null) {
|
if (!result) {
|
||||||
Logging.LogGenericWTF("Request failed even after " + WebBrowser.MaxRetries + " tries", Bot.BotName);
|
Logging.LogGenericWTF("Request failed even after " + WebBrowser.MaxRetries + " tries", Bot.BotName);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -240,12 +322,17 @@ namespace ArchiSteamFarm {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
string sessionID;
|
if (!await RefreshSessionIfNeeded().ConfigureAwait(false)) {
|
||||||
if (!Cookie.TryGetValue("sessionid", out sessionID)) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
string referer = "https://steamcommunity.com/tradeoffer/" + tradeID;
|
string sessionID = WebBrowser.CookieContainer.GetCookieValue(SteamCommunityURL, "sessionid");
|
||||||
|
if (string.IsNullOrEmpty(sessionID)) {
|
||||||
|
Logging.LogNullError("sessionID");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
string referer = SteamCommunityURL + "/tradeoffer/" + tradeID;
|
||||||
string request = referer + "/accept";
|
string request = referer + "/accept";
|
||||||
|
|
||||||
Dictionary<string, string> data = new Dictionary<string, string>(3) {
|
Dictionary<string, string> data = new Dictionary<string, string>(3) {
|
||||||
@@ -254,12 +341,12 @@ namespace ArchiSteamFarm {
|
|||||||
{"tradeofferid", tradeID.ToString()}
|
{"tradeofferid", tradeID.ToString()}
|
||||||
};
|
};
|
||||||
|
|
||||||
HttpResponseMessage response = null;
|
bool result = false;
|
||||||
for (byte i = 0; i < WebBrowser.MaxRetries && response == null; i++) {
|
for (byte i = 0; i < WebBrowser.MaxRetries && !result; i++) {
|
||||||
response = await WebBrowser.UrlPost(request, data, Cookie, referer).ConfigureAwait(false);
|
result = await WebBrowser.UrlPost(request, data, referer).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (response == null) {
|
if (!result) {
|
||||||
Logging.LogGenericWTF("Request failed even after " + WebBrowser.MaxRetries + " tries", Bot.BotName);
|
Logging.LogGenericWTF("Request failed even after " + WebBrowser.MaxRetries + " tries", Bot.BotName);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -267,40 +354,14 @@ namespace ArchiSteamFarm {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal bool DeclineTradeOffer(ulong tradeID) {
|
internal async Task<List<Steam.Item>> GetMyTradableInventory() {
|
||||||
if (tradeID == 0 || string.IsNullOrEmpty(Bot.BotConfig.SteamApiKey)) {
|
if (!await RefreshSessionIfNeeded().ConfigureAwait(false)) {
|
||||||
return false;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
KeyValue response = null;
|
|
||||||
using (dynamic iEconService = WebAPI.GetInterface("IEconService", Bot.BotConfig.SteamApiKey)) {
|
|
||||||
iEconService.Timeout = Timeout;
|
|
||||||
|
|
||||||
for (byte i = 0; i < WebBrowser.MaxRetries && response == null; i++) {
|
|
||||||
try {
|
|
||||||
response = iEconService.DeclineTradeOffer(
|
|
||||||
tradeofferid: tradeID.ToString(),
|
|
||||||
method: WebRequestMethods.Http.Post,
|
|
||||||
secure: true
|
|
||||||
);
|
|
||||||
} catch (Exception e) {
|
|
||||||
Logging.LogGenericException(e, Bot.BotName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (response == null) {
|
|
||||||
Logging.LogGenericWTF("Request failed even after " + WebBrowser.MaxRetries + " tries", Bot.BotName);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
internal async Task<List<SteamItem>> GetMyTradableInventory() {
|
|
||||||
JObject jObject = null;
|
JObject jObject = null;
|
||||||
for (byte i = 0; i < WebBrowser.MaxRetries && jObject == null; i++) {
|
for (byte i = 0; i < WebBrowser.MaxRetries && jObject == null; i++) {
|
||||||
jObject = await WebBrowser.UrlGetToJObject("https://steamcommunity.com/my/inventory/json/753/6?trading=1", Cookie).ConfigureAwait(false);
|
jObject = await WebBrowser.UrlGetToJObject(SteamCommunityURL + "/my/inventory/json/753/6?trading=1").ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (jObject == null) {
|
if (jObject == null) {
|
||||||
@@ -314,10 +375,10 @@ namespace ArchiSteamFarm {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
List<SteamItem> result = new List<SteamItem>();
|
List<Steam.Item> result = new List<Steam.Item>();
|
||||||
foreach (JToken jToken in jTokens) {
|
foreach (JToken jToken in jTokens) {
|
||||||
try {
|
try {
|
||||||
result.Add(JsonConvert.DeserializeObject<SteamItem>(jToken.ToString()));
|
result.Add(JsonConvert.DeserializeObject<Steam.Item>(jToken.ToString()));
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Logging.LogGenericException(e, Bot.BotName);
|
Logging.LogGenericException(e, Bot.BotName);
|
||||||
}
|
}
|
||||||
@@ -326,31 +387,36 @@ namespace ArchiSteamFarm {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal async Task<bool> SendTradeOffer(List<SteamItem> inventory, ulong partnerID, string token = null) {
|
internal async Task<bool> SendTradeOffer(List<Steam.Item> inventory, ulong partnerID, string token = null) {
|
||||||
if (inventory == null || inventory.Count == 0 || partnerID == 0) {
|
if (inventory == null || inventory.Count == 0 || partnerID == 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
string sessionID;
|
if (!await RefreshSessionIfNeeded().ConfigureAwait(false)) {
|
||||||
if (!Cookie.TryGetValue("sessionid", out sessionID)) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
List<SteamTradeOfferRequest> trades = new List<SteamTradeOfferRequest>(1 + inventory.Count / Trading.MaxItemsPerTrade);
|
string sessionID = WebBrowser.CookieContainer.GetCookieValue(SteamCommunityURL, "sessionid");
|
||||||
|
if (string.IsNullOrEmpty(sessionID)) {
|
||||||
|
Logging.LogNullError("sessionID");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
SteamTradeOfferRequest singleTrade = null;
|
List<Steam.TradeOfferRequest> trades = new List<Steam.TradeOfferRequest>(1 + inventory.Count / Trading.MaxItemsPerTrade);
|
||||||
|
|
||||||
|
Steam.TradeOfferRequest singleTrade = null;
|
||||||
for (ushort i = 0; i < inventory.Count; i++) {
|
for (ushort i = 0; i < inventory.Count; i++) {
|
||||||
if (i % Trading.MaxItemsPerTrade == 0) {
|
if (i % Trading.MaxItemsPerTrade == 0) {
|
||||||
if (trades.Count >= Trading.MaxTradesPerAccount) {
|
if (trades.Count >= Trading.MaxTradesPerAccount) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
singleTrade = new SteamTradeOfferRequest();
|
singleTrade = new Steam.TradeOfferRequest();
|
||||||
trades.Add(singleTrade);
|
trades.Add(singleTrade);
|
||||||
}
|
}
|
||||||
|
|
||||||
SteamItem item = inventory[i];
|
Steam.Item item = inventory[i];
|
||||||
singleTrade.me.assets.Add(new SteamItem() {
|
singleTrade.me.assets.Add(new Steam.Item() {
|
||||||
appid = "753",
|
appid = "753",
|
||||||
contextid = "6",
|
contextid = "6",
|
||||||
amount = item.amount,
|
amount = item.amount,
|
||||||
@@ -358,25 +424,25 @@ namespace ArchiSteamFarm {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
string referer = "https://steamcommunity.com/tradeoffer/new";
|
string referer = SteamCommunityURL + "/tradeoffer/new";
|
||||||
string request = referer + "/send";
|
string request = referer + "/send";
|
||||||
|
|
||||||
foreach (SteamTradeOfferRequest trade in trades) {
|
foreach (Steam.TradeOfferRequest trade in trades) {
|
||||||
Dictionary<string, string> data = new Dictionary<string, string>(6) {
|
Dictionary<string, string> data = new Dictionary<string, string>(6) {
|
||||||
{"sessionid", sessionID},
|
{"sessionid", sessionID},
|
||||||
{"serverid", "1"},
|
{"serverid", "1"},
|
||||||
{"partner", partnerID.ToString()},
|
{"partner", partnerID.ToString()},
|
||||||
{"tradeoffermessage", "Sent by ASF"},
|
{"tradeoffermessage", "Sent by ASF"},
|
||||||
{"json_tradeoffer", JsonConvert.SerializeObject(trade)},
|
{"json_tradeoffer", JsonConvert.SerializeObject(trade)},
|
||||||
{"trade_offer_create_params", string.IsNullOrEmpty(token) ? "" : string.Format("{{ \"trade_offer_access_token\":\"{0}\" }}", token)} // TODO: This should be rewrote
|
{"trade_offer_create_params", string.IsNullOrEmpty(token) ? "" : $"{{\"trade_offer_access_token\":\"{token}\"}}"}
|
||||||
};
|
};
|
||||||
|
|
||||||
HttpResponseMessage response = null;
|
bool result = false;
|
||||||
for (byte i = 0; i < WebBrowser.MaxRetries && response == null; i++) {
|
for (byte i = 0; i < WebBrowser.MaxRetries && !result; i++) {
|
||||||
response = await WebBrowser.UrlPost(request, data, Cookie, referer).ConfigureAwait(false);
|
result = await WebBrowser.UrlPost(request, data, referer).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (response == null) {
|
if (!result) {
|
||||||
Logging.LogGenericWTF("Request failed even after " + WebBrowser.MaxRetries + " tries", Bot.BotName);
|
Logging.LogGenericWTF("Request failed even after " + WebBrowser.MaxRetries + " tries", Bot.BotName);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -386,13 +452,17 @@ namespace ArchiSteamFarm {
|
|||||||
}
|
}
|
||||||
|
|
||||||
internal async Task<HtmlDocument> GetBadgePage(byte page) {
|
internal async Task<HtmlDocument> GetBadgePage(byte page) {
|
||||||
if (page == 0 || SteamID == 0) {
|
if (page == 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!await RefreshSessionIfNeeded().ConfigureAwait(false)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
HtmlDocument htmlDocument = null;
|
HtmlDocument htmlDocument = null;
|
||||||
for (byte i = 0; i < WebBrowser.MaxRetries && htmlDocument == null; i++) {
|
for (byte i = 0; i < WebBrowser.MaxRetries && htmlDocument == null; i++) {
|
||||||
htmlDocument = await WebBrowser.UrlGetToHtmlDocument("https://steamcommunity.com/profiles/" + SteamID + "/badges?l=english&p=" + page, Cookie).ConfigureAwait(false);
|
htmlDocument = await WebBrowser.UrlGetToHtmlDocument(SteamCommunityURL + "/my/badges?p=" + page).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (htmlDocument == null) {
|
if (htmlDocument == null) {
|
||||||
@@ -404,13 +474,17 @@ namespace ArchiSteamFarm {
|
|||||||
}
|
}
|
||||||
|
|
||||||
internal async Task<HtmlDocument> GetGameCardsPage(ulong appID) {
|
internal async Task<HtmlDocument> GetGameCardsPage(ulong appID) {
|
||||||
if (appID == 0 || SteamID == 0) {
|
if (appID == 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!await RefreshSessionIfNeeded().ConfigureAwait(false)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
HtmlDocument htmlDocument = null;
|
HtmlDocument htmlDocument = null;
|
||||||
for (byte i = 0; i < WebBrowser.MaxRetries && htmlDocument == null; i++) {
|
for (byte i = 0; i < WebBrowser.MaxRetries && htmlDocument == null; i++) {
|
||||||
htmlDocument = await WebBrowser.UrlGetToHtmlDocument("https://steamcommunity.com/profiles/" + SteamID + "/gamecards/" + appID + "?l=english", Cookie).ConfigureAwait(false);
|
htmlDocument = await WebBrowser.UrlGetToHtmlDocument(SteamCommunityURL + "/my/gamecards/" + appID).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (htmlDocument == null) {
|
if (htmlDocument == null) {
|
||||||
@@ -422,16 +496,16 @@ namespace ArchiSteamFarm {
|
|||||||
}
|
}
|
||||||
|
|
||||||
internal async Task<bool> MarkInventory() {
|
internal async Task<bool> MarkInventory() {
|
||||||
if (SteamID == 0) {
|
if (!await RefreshSessionIfNeeded().ConfigureAwait(false)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
HttpResponseMessage response = null;
|
bool result = false;
|
||||||
for (byte i = 0; i < WebBrowser.MaxRetries && response == null; i++) {
|
for (byte i = 0; i < WebBrowser.MaxRetries && !result; i++) {
|
||||||
response = await WebBrowser.UrlGet("https://steamcommunity.com/profiles/" + SteamID + "/inventory", Cookie).ConfigureAwait(false);
|
result = await WebBrowser.UrlGet(SteamCommunityURL + "/my/inventory").ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (response == null) {
|
if (!result) {
|
||||||
Logging.LogGenericWTF("Request failed even after " + WebBrowser.MaxRetries + " tries", Bot.BotName);
|
Logging.LogGenericWTF("Request failed even after " + WebBrowser.MaxRetries + " tries", Bot.BotName);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -439,9 +513,42 @@ namespace ArchiSteamFarm {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task UnlockParentalAccount(string parentalPin) {
|
internal async Task<bool> AcceptGift(ulong gid) {
|
||||||
|
if (gid == 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!await RefreshSessionIfNeeded().ConfigureAwait(false)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
string sessionID = WebBrowser.CookieContainer.GetCookieValue(SteamCommunityURL, "sessionid");
|
||||||
|
if (string.IsNullOrEmpty(sessionID)) {
|
||||||
|
Logging.LogNullError("sessionID");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
string request = SteamCommunityURL + "/gifts/" + gid + "/acceptunpack";
|
||||||
|
Dictionary<string, string> data = new Dictionary<string, string>(1) {
|
||||||
|
{ "sessionid", sessionID }
|
||||||
|
};
|
||||||
|
|
||||||
|
bool result = false;
|
||||||
|
for (byte i = 0; i < WebBrowser.MaxRetries && !result; i++) {
|
||||||
|
result = await WebBrowser.UrlPost(request, data).ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!result) {
|
||||||
|
Logging.LogGenericWTF("Request failed even after " + WebBrowser.MaxRetries + " tries", Bot.BotName);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task<bool> UnlockParentalAccount(string parentalPin) {
|
||||||
if (string.IsNullOrEmpty(parentalPin) || parentalPin.Equals("0")) {
|
if (string.IsNullOrEmpty(parentalPin) || parentalPin.Equals("0")) {
|
||||||
return;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
Logging.LogGenericInfo("Unlocking parental account...", Bot.BotName);
|
Logging.LogGenericInfo("Unlocking parental account...", Bot.BotName);
|
||||||
@@ -449,33 +556,21 @@ namespace ArchiSteamFarm {
|
|||||||
{ "pin", parentalPin }
|
{ "pin", parentalPin }
|
||||||
};
|
};
|
||||||
|
|
||||||
HttpResponseMessage response = null;
|
string referer = SteamCommunityURL;
|
||||||
for (byte i = 0; i < WebBrowser.MaxRetries && response == null; i++) {
|
string request = referer + "/parental/ajaxunlock";
|
||||||
response = await WebBrowser.UrlPost("https://steamcommunity.com/parental/ajaxunlock", data, Cookie, "https://steamcommunity.com/").ConfigureAwait(false);
|
|
||||||
|
bool result = false;
|
||||||
|
for (byte i = 0; i < WebBrowser.MaxRetries && !result; i++) {
|
||||||
|
result = await WebBrowser.UrlPost(request, data, referer).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (response == null) {
|
if (!result) {
|
||||||
Logging.LogGenericWTF("Request failed even after " + WebBrowser.MaxRetries + " tries", Bot.BotName);
|
Logging.LogGenericWTF("Request failed even after " + WebBrowser.MaxRetries + " tries", Bot.BotName);
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
IEnumerable<string> setCookieValues;
|
Logging.LogGenericInfo("Success!", Bot.BotName);
|
||||||
if (!response.Headers.TryGetValues("Set-Cookie", out setCookieValues)) {
|
return true;
|
||||||
Logging.LogNullError("setCookieValues", Bot.BotName);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (string setCookieValue in setCookieValues) {
|
|
||||||
if (setCookieValue.Contains("steamparental=")) {
|
|
||||||
string setCookie = setCookieValue.Substring(setCookieValue.IndexOf("steamparental=") + 14);
|
|
||||||
setCookie = setCookie.Substring(0, setCookie.IndexOf(';'));
|
|
||||||
Cookie["steamparental"] = setCookie;
|
|
||||||
Logging.LogGenericInfo("Success!", Bot.BotName);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Logging.LogGenericWarning("Failed to unlock parental account!", Bot.BotName);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -26,7 +26,6 @@ using Newtonsoft.Json;
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Xml;
|
|
||||||
|
|
||||||
namespace ArchiSteamFarm {
|
namespace ArchiSteamFarm {
|
||||||
internal sealed class BotConfig {
|
internal sealed class BotConfig {
|
||||||
@@ -66,6 +65,9 @@ namespace ArchiSteamFarm {
|
|||||||
[JsonProperty(Required = Required.DisallowNull)]
|
[JsonProperty(Required = Required.DisallowNull)]
|
||||||
internal bool HandleOfflineMessages { get; private set; } = false;
|
internal bool HandleOfflineMessages { get; private set; } = false;
|
||||||
|
|
||||||
|
[JsonProperty(Required = Required.DisallowNull)]
|
||||||
|
internal bool AcceptGifts { get; private set; } = false;
|
||||||
|
|
||||||
[JsonProperty(Required = Required.DisallowNull)]
|
[JsonProperty(Required = Required.DisallowNull)]
|
||||||
internal bool ForwardKeysToOtherBots { get; private set; } = false;
|
internal bool ForwardKeysToOtherBots { get; private set; } = false;
|
||||||
|
|
||||||
@@ -87,24 +89,24 @@ namespace ArchiSteamFarm {
|
|||||||
[JsonProperty(Required = Required.DisallowNull)]
|
[JsonProperty(Required = Required.DisallowNull)]
|
||||||
internal byte SendTradePeriod { get; private set; } = 0;
|
internal byte SendTradePeriod { get; private set; } = 0;
|
||||||
|
|
||||||
|
[JsonProperty(Required = Required.DisallowNull)]
|
||||||
|
internal byte AcceptConfirmationsPeriod { get; private set; } = 0;
|
||||||
|
|
||||||
[JsonProperty]
|
[JsonProperty]
|
||||||
internal string CustomGamePlayedWhileIdle { get; private set; } = null;
|
internal string CustomGamePlayedWhileIdle { get; private set; } = null;
|
||||||
|
|
||||||
[JsonProperty(Required = Required.DisallowNull)]
|
[JsonProperty(Required = Required.DisallowNull)]
|
||||||
internal HashSet<uint> GamesPlayedWhileIdle { get; private set; } = new HashSet<uint>() { 0 };
|
internal HashSet<uint> GamesPlayedWhileIdle { get; private set; } = new HashSet<uint>() { 0 };
|
||||||
|
|
||||||
[JsonProperty(Required = Required.DisallowNull)]
|
|
||||||
internal bool Statistics { get; private set; } = true;
|
|
||||||
|
|
||||||
|
internal static BotConfig Load(string filePath) {
|
||||||
internal static BotConfig Load(string path) {
|
if (string.IsNullOrEmpty(filePath) || !File.Exists(filePath)) {
|
||||||
if (!File.Exists(path)) {
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
BotConfig botConfig;
|
BotConfig botConfig;
|
||||||
try {
|
try {
|
||||||
botConfig = JsonConvert.DeserializeObject<BotConfig>(File.ReadAllText(path));
|
botConfig = JsonConvert.DeserializeObject<BotConfig>(File.ReadAllText(filePath));
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Logging.LogGenericException(e);
|
Logging.LogGenericException(e);
|
||||||
return null;
|
return null;
|
||||||
@@ -113,148 +115,7 @@ namespace ArchiSteamFarm {
|
|||||||
return botConfig;
|
return botConfig;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: This should be removed soon
|
|
||||||
internal static BotConfig LoadOldFormat(string path) {
|
|
||||||
if (!File.Exists(path)) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
BotConfig botConfig = new BotConfig();
|
|
||||||
|
|
||||||
try {
|
|
||||||
using (XmlReader reader = XmlReader.Create(path)) {
|
|
||||||
while (reader.Read()) {
|
|
||||||
if (reader.NodeType != XmlNodeType.Element) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
string key = reader.Name;
|
|
||||||
if (string.IsNullOrEmpty(key)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
string value = reader.GetAttribute("value");
|
|
||||||
if (string.IsNullOrEmpty(value)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (key) {
|
|
||||||
case "Enabled":
|
|
||||||
botConfig.Enabled = bool.Parse(value);
|
|
||||||
break;
|
|
||||||
case "SteamLogin":
|
|
||||||
botConfig.SteamLogin = value;
|
|
||||||
break;
|
|
||||||
case "SteamPassword":
|
|
||||||
botConfig.SteamPassword = value;
|
|
||||||
break;
|
|
||||||
case "SteamApiKey":
|
|
||||||
botConfig.SteamApiKey = value;
|
|
||||||
break;
|
|
||||||
case "SteamTradeToken":
|
|
||||||
botConfig.SteamTradeToken = value;
|
|
||||||
break;
|
|
||||||
case "SteamParentalPIN":
|
|
||||||
botConfig.SteamParentalPIN = value;
|
|
||||||
break;
|
|
||||||
case "SteamMasterID":
|
|
||||||
botConfig.SteamMasterID = ulong.Parse(value);
|
|
||||||
break;
|
|
||||||
case "SteamMasterClanID":
|
|
||||||
botConfig.SteamMasterClanID = ulong.Parse(value);
|
|
||||||
break;
|
|
||||||
case "StartOnLaunch":
|
|
||||||
botConfig.StartOnLaunch = bool.Parse(value);
|
|
||||||
break;
|
|
||||||
case "UseAsfAsMobileAuthenticator":
|
|
||||||
botConfig.UseAsfAsMobileAuthenticator = bool.Parse(value);
|
|
||||||
break;
|
|
||||||
case "CardDropsRestricted":
|
|
||||||
botConfig.CardDropsRestricted = bool.Parse(value);
|
|
||||||
break;
|
|
||||||
case "FarmOffline":
|
|
||||||
botConfig.FarmOffline = bool.Parse(value);
|
|
||||||
break;
|
|
||||||
case "HandleOfflineMessages":
|
|
||||||
botConfig.HandleOfflineMessages = bool.Parse(value);
|
|
||||||
break;
|
|
||||||
case "ForwardKeysToOtherBots":
|
|
||||||
botConfig.ForwardKeysToOtherBots = bool.Parse(value);
|
|
||||||
break;
|
|
||||||
case "DistributeKeys":
|
|
||||||
botConfig.DistributeKeys = bool.Parse(value);
|
|
||||||
break;
|
|
||||||
case "ShutdownOnFarmingFinished":
|
|
||||||
botConfig.ShutdownOnFarmingFinished = bool.Parse(value);
|
|
||||||
break;
|
|
||||||
case "SendOnFarmingFinished":
|
|
||||||
botConfig.SendOnFarmingFinished = bool.Parse(value);
|
|
||||||
break;
|
|
||||||
case "SendTradePeriod":
|
|
||||||
botConfig.SendTradePeriod = byte.Parse(value);
|
|
||||||
break;
|
|
||||||
case "GamesPlayedWhileIdle":
|
|
||||||
botConfig.GamesPlayedWhileIdle.Clear();
|
|
||||||
foreach (string appID in value.Split(',')) {
|
|
||||||
botConfig.GamesPlayedWhileIdle.Add(uint.Parse(appID));
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case "Statistics":
|
|
||||||
botConfig.Statistics = bool.Parse(value);
|
|
||||||
break;
|
|
||||||
case "Blacklist":
|
|
||||||
case "SteamNickname":
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
Logging.LogGenericWarning("Unrecognized config value: " + key + "=" + value);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
Logging.LogGenericException(e);
|
|
||||||
Logging.LogGenericError("Your config for this bot instance is invalid, it won't run!");
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fixups for new format
|
|
||||||
if (botConfig.SteamLogin != null && botConfig.SteamLogin.Equals("null")) {
|
|
||||||
botConfig.SteamLogin = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (botConfig.SteamPassword != null && botConfig.SteamPassword.Equals("null")) {
|
|
||||||
botConfig.SteamPassword = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (botConfig.SteamApiKey != null && botConfig.SteamApiKey.Equals("null")) {
|
|
||||||
botConfig.SteamApiKey = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (botConfig.SteamParentalPIN != null && botConfig.SteamParentalPIN.Equals("null")) {
|
|
||||||
botConfig.SteamParentalPIN = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (botConfig.SteamTradeToken != null && botConfig.SteamTradeToken.Equals("null")) {
|
|
||||||
botConfig.SteamTradeToken = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return botConfig;
|
|
||||||
}
|
|
||||||
|
|
||||||
// This constructor is used only by deserializer
|
// This constructor is used only by deserializer
|
||||||
private BotConfig() { }
|
private BotConfig() { }
|
||||||
|
|
||||||
// TODO: This should be removed soon
|
|
||||||
internal bool Convert(string path) {
|
|
||||||
try {
|
|
||||||
File.WriteAllText(path, JsonConvert.SerializeObject(this, Newtonsoft.Json.Formatting.Indented));
|
|
||||||
} catch (Exception e) {
|
|
||||||
Logging.LogGenericException(e);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
Logging.LogGenericWarning("Your config was converted to new ASF V2.0 format");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -57,15 +57,19 @@ namespace ArchiSteamFarm {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[JsonProperty(Required = Required.AllowNull)]
|
[JsonProperty]
|
||||||
private string _LoginKey;
|
private string _LoginKey;
|
||||||
|
|
||||||
[JsonProperty(Required = Required.AllowNull)]
|
[JsonProperty]
|
||||||
private SteamGuardAccount _SteamGuardAccount;
|
private SteamGuardAccount _SteamGuardAccount;
|
||||||
|
|
||||||
private string FilePath;
|
private string FilePath;
|
||||||
|
|
||||||
internal static BotDatabase Load(string filePath) {
|
internal static BotDatabase Load(string filePath) {
|
||||||
|
if (string.IsNullOrEmpty(filePath)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
if (!File.Exists(filePath)) {
|
if (!File.Exists(filePath)) {
|
||||||
return new BotDatabase(filePath);
|
return new BotDatabase(filePath);
|
||||||
}
|
}
|
||||||
@@ -78,12 +82,20 @@ namespace ArchiSteamFarm {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (botDatabase == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
botDatabase.FilePath = filePath;
|
botDatabase.FilePath = filePath;
|
||||||
return botDatabase;
|
return botDatabase;
|
||||||
}
|
}
|
||||||
|
|
||||||
// This constructor is used when creating new database
|
// This constructor is used when creating new database
|
||||||
private BotDatabase(string filePath) {
|
private BotDatabase(string filePath) {
|
||||||
|
if (string.IsNullOrEmpty(filePath)) {
|
||||||
|
throw new ArgumentNullException("filePath");
|
||||||
|
}
|
||||||
|
|
||||||
FilePath = filePath;
|
FilePath = filePath;
|
||||||
Save();
|
Save();
|
||||||
}
|
}
|
||||||
@@ -91,7 +103,7 @@ namespace ArchiSteamFarm {
|
|||||||
// This constructor is used only by deserializer
|
// This constructor is used only by deserializer
|
||||||
private BotDatabase() { }
|
private BotDatabase() { }
|
||||||
|
|
||||||
private void Save() {
|
internal void Save() {
|
||||||
lock (FilePath) {
|
lock (FilePath) {
|
||||||
try {
|
try {
|
||||||
File.WriteAllText(FilePath, JsonConvert.SerializeObject(this));
|
File.WriteAllText(FilePath, JsonConvert.SerializeObject(this));
|
||||||
|
|||||||
@@ -27,70 +27,45 @@ using System;
|
|||||||
using System.Collections.Concurrent;
|
using System.Collections.Concurrent;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
|
using System.Linq;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace ArchiSteamFarm {
|
namespace ArchiSteamFarm {
|
||||||
internal sealed class CardsFarmer {
|
internal sealed class CardsFarmer {
|
||||||
private const byte StatusCheckSleep = 5; // In minutes, how long to wait before checking the appID again
|
|
||||||
private const ushort MaxFarmingTime = 600; // In minutes, how long ASF is allowed to farm one game in solo mode
|
|
||||||
|
|
||||||
internal readonly ConcurrentDictionary<uint, float> GamesToFarm = new ConcurrentDictionary<uint, float>();
|
internal readonly ConcurrentDictionary<uint, float> GamesToFarm = new ConcurrentDictionary<uint, float>();
|
||||||
internal readonly List<uint> CurrentGamesFarming = new List<uint>();
|
internal readonly HashSet<uint> CurrentGamesFarming = new HashSet<uint>();
|
||||||
|
|
||||||
private readonly ManualResetEvent FarmResetEvent = new ManualResetEvent(false);
|
private readonly ManualResetEventSlim FarmResetEvent = new ManualResetEventSlim(false);
|
||||||
private readonly SemaphoreSlim Semaphore = new SemaphoreSlim(1);
|
private readonly SemaphoreSlim Semaphore = new SemaphoreSlim(1);
|
||||||
|
|
||||||
private readonly Bot Bot;
|
private readonly Bot Bot;
|
||||||
private readonly Timer Timer;
|
private readonly Timer Timer;
|
||||||
|
|
||||||
private bool ManualMode = false;
|
internal bool ManualMode { get; private set; }
|
||||||
private bool NowFarming = false;
|
|
||||||
|
private bool NowFarming;
|
||||||
|
|
||||||
internal CardsFarmer(Bot bot) {
|
internal CardsFarmer(Bot bot) {
|
||||||
|
if (bot == null) {
|
||||||
|
throw new ArgumentNullException("bot");
|
||||||
|
}
|
||||||
|
|
||||||
Bot = bot;
|
Bot = bot;
|
||||||
|
|
||||||
if (Timer == null) {
|
if (Timer == null && Program.GlobalConfig.IdleFarmingPeriod > 0) {
|
||||||
Timer = new Timer(
|
Timer = new Timer(
|
||||||
async e => await CheckGamesForFarming().ConfigureAwait(false),
|
async e => await CheckGamesForFarming().ConfigureAwait(false),
|
||||||
null,
|
null,
|
||||||
TimeSpan.FromMinutes(15), // Delay
|
TimeSpan.FromHours(Program.GlobalConfig.IdleFarmingPeriod), // Delay
|
||||||
TimeSpan.FromMinutes(60) // Period
|
TimeSpan.FromHours(Program.GlobalConfig.IdleFarmingPeriod) // Period
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static List<uint> GetGamesToFarmSolo(ConcurrentDictionary<uint, float> gamesToFarm) {
|
internal async Task SwitchToManualMode(bool manualMode) {
|
||||||
if (gamesToFarm == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
List<uint> result = new List<uint>();
|
|
||||||
foreach (KeyValuePair<uint, float> keyValue in gamesToFarm) {
|
|
||||||
if (keyValue.Value >= 2) {
|
|
||||||
result.Add(keyValue.Key);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
internal static uint GetAnyGameToFarm(ConcurrentDictionary<uint, float> gamesToFarm) {
|
|
||||||
if (gamesToFarm == null) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (uint appID in gamesToFarm.Keys) {
|
|
||||||
return appID;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
internal async Task<bool> SwitchToManualMode(bool manualMode) {
|
|
||||||
if (ManualMode == manualMode) {
|
if (ManualMode == manualMode) {
|
||||||
return false;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ManualMode = manualMode;
|
ManualMode = manualMode;
|
||||||
@@ -100,76 +75,26 @@ namespace ArchiSteamFarm {
|
|||||||
await StopFarming().ConfigureAwait(false);
|
await StopFarming().ConfigureAwait(false);
|
||||||
} else {
|
} else {
|
||||||
Logging.LogGenericInfo("Now running in Automatic Farming mode", Bot.BotName);
|
Logging.LogGenericInfo("Now running in Automatic Farming mode", Bot.BotName);
|
||||||
Task.Run(async () => await StartFarming().ConfigureAwait(false)).Forget();
|
StartFarming().Forget();
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
internal bool FarmMultiple(ConcurrentDictionary<uint, float> appIDs) {
|
|
||||||
if (appIDs.Count == 0) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
float maxHour = 0;
|
|
||||||
|
|
||||||
foreach (float hour in appIDs.Values) {
|
|
||||||
if (hour > maxHour) {
|
|
||||||
maxHour = hour;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
CurrentGamesFarming.Clear();
|
|
||||||
CurrentGamesFarming.TrimExcess();
|
|
||||||
foreach (uint appID in appIDs.Keys) {
|
|
||||||
CurrentGamesFarming.Add(appID);
|
|
||||||
}
|
|
||||||
|
|
||||||
Logging.LogGenericInfo("Now farming: " + string.Join(", ", appIDs.Keys), Bot.BotName);
|
|
||||||
if (Farm(maxHour, appIDs.Keys)) {
|
|
||||||
CurrentGamesFarming.Clear();
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
CurrentGamesFarming.Clear();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
internal async Task<bool> FarmSolo(uint appID) {
|
|
||||||
if (appID == 0) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
CurrentGamesFarming.Clear();
|
|
||||||
CurrentGamesFarming.TrimExcess();
|
|
||||||
CurrentGamesFarming.Add(appID);
|
|
||||||
|
|
||||||
Logging.LogGenericInfo("Now farming: " + appID, Bot.BotName);
|
|
||||||
if (await Farm(appID).ConfigureAwait(false)) {
|
|
||||||
float hours;
|
|
||||||
GamesToFarm.TryRemove(appID, out hours);
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
CurrentGamesFarming.Clear();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
internal async Task RestartFarming() {
|
|
||||||
await StopFarming().ConfigureAwait(false);
|
|
||||||
await StartFarming().ConfigureAwait(false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal async Task StartFarming() {
|
internal async Task StartFarming() {
|
||||||
|
if (NowFarming || ManualMode) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
await Semaphore.WaitAsync().ConfigureAwait(false);
|
await Semaphore.WaitAsync().ConfigureAwait(false);
|
||||||
|
|
||||||
if (ManualMode) {
|
if (NowFarming || ManualMode) {
|
||||||
Semaphore.Release(); // We have nothing to do, don't forget to release semaphore
|
Semaphore.Release(); // We have nothing to do, don't forget to release semaphore
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!await IsAnythingToFarm().ConfigureAwait(false)) {
|
if (!await IsAnythingToFarm().ConfigureAwait(false)) {
|
||||||
Semaphore.Release(); // We have nothing to do, don't forget to release semaphore
|
Semaphore.Release(); // We have nothing to do, don't forget to release semaphore
|
||||||
|
Logging.LogGenericInfo("We don't have anything to farm on this account!", Bot.BotName);
|
||||||
|
await Bot.OnFarmingFinished(false).ConfigureAwait(false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -179,56 +104,60 @@ namespace ArchiSteamFarm {
|
|||||||
|
|
||||||
bool farmedSomething = false;
|
bool farmedSomething = false;
|
||||||
|
|
||||||
// Now the algorithm used for farming depends on whether account is restricted or not
|
do {
|
||||||
if (Bot.BotConfig.CardDropsRestricted) { // If we have restricted card drops, we use complex algorithm
|
// Now the algorithm used for farming depends on whether account is restricted or not
|
||||||
Logging.LogGenericInfo("Chosen farming algorithm: Complex", Bot.BotName);
|
if (Bot.BotConfig.CardDropsRestricted) { // If we have restricted card drops, we use complex algorithm
|
||||||
while (GamesToFarm.Count > 0) {
|
Logging.LogGenericInfo("Chosen farming algorithm: Complex", Bot.BotName);
|
||||||
List<uint> gamesToFarmSolo = GetGamesToFarmSolo(GamesToFarm);
|
while (GamesToFarm.Count > 0) {
|
||||||
if (gamesToFarmSolo.Count > 0) {
|
HashSet<uint> gamesToFarmSolo = GetGamesToFarmSolo(GamesToFarm);
|
||||||
while (gamesToFarmSolo.Count > 0) {
|
if (gamesToFarmSolo.Count > 0) {
|
||||||
uint appID = gamesToFarmSolo[0];
|
while (gamesToFarmSolo.Count > 0) {
|
||||||
if (await FarmSolo(appID).ConfigureAwait(false)) {
|
uint appID = gamesToFarmSolo.First();
|
||||||
farmedSomething = true;
|
if (await FarmSolo(appID).ConfigureAwait(false)) {
|
||||||
Logging.LogGenericInfo("Done farming: " + appID, Bot.BotName);
|
farmedSomething = true;
|
||||||
gamesToFarmSolo.Remove(appID);
|
gamesToFarmSolo.Remove(appID);
|
||||||
gamesToFarmSolo.TrimExcess();
|
gamesToFarmSolo.TrimExcess();
|
||||||
|
} else {
|
||||||
|
NowFarming = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (FarmMultiple()) {
|
||||||
|
Logging.LogGenericInfo("Done farming: " + string.Join(", ", GamesToFarm.Keys), Bot.BotName);
|
||||||
} else {
|
} else {
|
||||||
NowFarming = false;
|
NowFarming = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
if (FarmMultiple(GamesToFarm)) {
|
} 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 = GamesToFarm.Keys.FirstOrDefault();
|
||||||
|
if (await FarmSolo(appID).ConfigureAwait(false)) {
|
||||||
farmedSomething = true;
|
farmedSomething = true;
|
||||||
Logging.LogGenericInfo("Done farming: " + string.Join(", ", GamesToFarm.Keys), Bot.BotName);
|
|
||||||
} else {
|
} else {
|
||||||
NowFarming = false;
|
NowFarming = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else { // If we have unrestricted card drops, we use simple algorithm
|
} while (await IsAnythingToFarm().ConfigureAwait(false));
|
||||||
Logging.LogGenericInfo("Chosen farming algorithm: Simple", Bot.BotName);
|
|
||||||
while (GamesToFarm.Count > 0) {
|
|
||||||
uint appID = GetAnyGameToFarm(GamesToFarm);
|
|
||||||
if (await FarmSolo(appID).ConfigureAwait(false)) {
|
|
||||||
farmedSomething = true;
|
|
||||||
Logging.LogGenericInfo("Done farming: " + appID, Bot.BotName);
|
|
||||||
} else {
|
|
||||||
NowFarming = false;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
CurrentGamesFarming.Clear();
|
CurrentGamesFarming.Clear();
|
||||||
CurrentGamesFarming.TrimExcess();
|
CurrentGamesFarming.TrimExcess();
|
||||||
NowFarming = false;
|
NowFarming = false;
|
||||||
|
|
||||||
Logging.LogGenericInfo("Farming finished!", Bot.BotName);
|
Logging.LogGenericInfo("Farming finished!", Bot.BotName);
|
||||||
await Bot.OnFarmingFinished(farmedSomething).ConfigureAwait(false);
|
await Bot.OnFarmingFinished(farmedSomething).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal async Task StopFarming() {
|
internal async Task StopFarming() {
|
||||||
|
if (!NowFarming) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
await Semaphore.WaitAsync().ConfigureAwait(false);
|
await Semaphore.WaitAsync().ConfigureAwait(false);
|
||||||
|
|
||||||
if (!NowFarming) {
|
if (!NowFarming) {
|
||||||
@@ -238,24 +167,42 @@ namespace ArchiSteamFarm {
|
|||||||
|
|
||||||
Logging.LogGenericInfo("Sending signal to stop farming", Bot.BotName);
|
Logging.LogGenericInfo("Sending signal to stop farming", Bot.BotName);
|
||||||
FarmResetEvent.Set();
|
FarmResetEvent.Set();
|
||||||
for (byte i = 0; i < 5 && NowFarming; i++) {
|
|
||||||
Logging.LogGenericInfo("Waiting for reaction...", Bot.BotName);
|
Logging.LogGenericInfo("Waiting for reaction...", Bot.BotName);
|
||||||
|
for (byte i = 0; i < Program.GlobalConfig.HttpTimeout && NowFarming; i++) {
|
||||||
await Utilities.SleepAsync(1000).ConfigureAwait(false);
|
await Utilities.SleepAsync(1000).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (NowFarming) {
|
||||||
|
Logging.LogGenericWarning("Timed out!", Bot.BotName);
|
||||||
|
}
|
||||||
|
|
||||||
FarmResetEvent.Reset();
|
FarmResetEvent.Reset();
|
||||||
Logging.LogGenericInfo("Farming stopped!", Bot.BotName);
|
Logging.LogGenericInfo("Farming stopped!", Bot.BotName);
|
||||||
Semaphore.Release();
|
Semaphore.Release();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal async Task RestartFarming() {
|
||||||
|
await StopFarming().ConfigureAwait(false);
|
||||||
|
await StartFarming().ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static HashSet<uint> GetGamesToFarmSolo(ConcurrentDictionary<uint, float> gamesToFarm) {
|
||||||
|
if (gamesToFarm == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
HashSet<uint> result = new HashSet<uint>();
|
||||||
|
foreach (KeyValuePair<uint, float> keyValue in gamesToFarm) {
|
||||||
|
if (keyValue.Value >= 2) {
|
||||||
|
result.Add(keyValue.Key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
private async Task<bool> IsAnythingToFarm() {
|
private async Task<bool> IsAnythingToFarm() {
|
||||||
if (NowFarming) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (await Bot.ArchiWebHandler.ReconnectIfNeeded().ConfigureAwait(false)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
Logging.LogGenericInfo("Checking badges...", Bot.BotName);
|
Logging.LogGenericInfo("Checking badges...", Bot.BotName);
|
||||||
|
|
||||||
// Find the number of badge pages
|
// Find the number of badge pages
|
||||||
@@ -270,42 +217,29 @@ namespace ArchiSteamFarm {
|
|||||||
HtmlNodeCollection htmlNodeCollection = htmlDocument.DocumentNode.SelectNodes("//a[@class='pagelink']");
|
HtmlNodeCollection htmlNodeCollection = htmlDocument.DocumentNode.SelectNodes("//a[@class='pagelink']");
|
||||||
if (htmlNodeCollection != null && htmlNodeCollection.Count > 0) {
|
if (htmlNodeCollection != null && htmlNodeCollection.Count > 0) {
|
||||||
HtmlNode htmlNode = htmlNodeCollection[htmlNodeCollection.Count - 1];
|
HtmlNode htmlNode = htmlNodeCollection[htmlNodeCollection.Count - 1];
|
||||||
if (!byte.TryParse(htmlNode.InnerText, out maxPages)) {
|
string lastPage = htmlNode.InnerText;
|
||||||
maxPages = 1; // Should never happen
|
if (!string.IsNullOrEmpty(lastPage)) {
|
||||||
|
if (!byte.TryParse(lastPage, out maxPages)) {
|
||||||
|
maxPages = 1; // Should never happen
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
GamesToFarm.Clear();
|
GamesToFarm.Clear();
|
||||||
|
|
||||||
// Find APPIDs we need to farm
|
CheckPage(htmlDocument);
|
||||||
Logging.LogGenericInfo("Checking other pages...", Bot.BotName);
|
|
||||||
|
|
||||||
List<Task> tasks = new List<Task>(maxPages - 1);
|
if (maxPages > 1) {
|
||||||
for (byte page = 1; page <= maxPages; page++) {
|
Logging.LogGenericInfo("Checking other pages...", Bot.BotName);
|
||||||
if (page == 1) {
|
List<Task> tasks = new List<Task>(maxPages - 1);
|
||||||
CheckPage(htmlDocument); // Because we fetched page number 1 already
|
for (byte page = 2; page <= maxPages; page++) {
|
||||||
} else {
|
byte currentPage = page; // We need a copy of variable being passed when in for loops, as loop will proceed before task is launched
|
||||||
byte currentPage = page; // We need a copy of variable being passed when in for loops
|
tasks.Add(CheckPage(currentPage));
|
||||||
tasks.Add(Task.Run(async () => await CheckPage(currentPage).ConfigureAwait(false)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
await Task.WhenAll(tasks).ConfigureAwait(false);
|
|
||||||
|
|
||||||
if (GamesToFarm.Count == 0) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If we have restricted card drops, actually do check hours of all games that are left to farm
|
|
||||||
if (Bot.BotConfig.CardDropsRestricted) {
|
|
||||||
tasks = new List<Task>(GamesToFarm.Keys.Count);
|
|
||||||
Logging.LogGenericInfo("Checking hours...", Bot.BotName);
|
|
||||||
foreach (uint appID in GamesToFarm.Keys) {
|
|
||||||
tasks.Add(Task.Run(async () => await CheckHours(appID).ConfigureAwait(false)));
|
|
||||||
}
|
}
|
||||||
await Task.WhenAll(tasks).ConfigureAwait(false);
|
await Task.WhenAll(tasks).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return GamesToFarm.Count > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void CheckPage(HtmlDocument htmlDocument) {
|
private void CheckPage(HtmlDocument htmlDocument) {
|
||||||
@@ -313,19 +247,45 @@ namespace ArchiSteamFarm {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
HtmlNodeCollection htmlNodeCollection = htmlDocument.DocumentNode.SelectNodes("//a[@class='btn_green_white_innerfade btn_small_thin']");
|
HtmlNodeCollection htmlNodes = htmlDocument.DocumentNode.SelectNodes("//div[@class='badge_title_stats']");
|
||||||
if (htmlNodeCollection == null) {
|
if (htmlNodes == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (HtmlNode htmlNode in htmlNodeCollection) {
|
foreach (HtmlNode htmlNode in htmlNodes) {
|
||||||
string steamLink = htmlNode.GetAttributeValue("href", null);
|
HtmlNode farmingNode = htmlNode.SelectSingleNode(".//a[@class='btn_green_white_innerfade btn_small_thin']");
|
||||||
if (steamLink == null) {
|
if (farmingNode == null) {
|
||||||
|
continue; // This game is not needed for farming
|
||||||
|
}
|
||||||
|
|
||||||
|
string steamLink = farmingNode.GetAttributeValue("href", null);
|
||||||
|
if (string.IsNullOrEmpty(steamLink)) {
|
||||||
|
Logging.LogNullError("steamLink", Bot.BotName);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
int index = steamLink.LastIndexOf('/');
|
||||||
|
if (index < 0) {
|
||||||
|
Logging.LogNullError("index", Bot.BotName);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
index++;
|
||||||
|
if (steamLink.Length <= index) {
|
||||||
|
Logging.LogNullError("length", Bot.BotName);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
steamLink = steamLink.Substring(index);
|
||||||
|
|
||||||
|
uint appID;
|
||||||
|
if (!uint.TryParse(steamLink, out appID)) {
|
||||||
|
Logging.LogNullError("appID", Bot.BotName);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint appID = (uint) Utilities.OnlyNumbers(steamLink);
|
|
||||||
if (appID == 0) {
|
if (appID == 0) {
|
||||||
|
Logging.LogNullError("appID", Bot.BotName);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -333,8 +293,26 @@ namespace ArchiSteamFarm {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// We assume that every game has at least 2 hours played, until we actually check them
|
HtmlNode timeNode = htmlNode.SelectSingleNode(".//div[@class='badge_title_stats_playtime']");
|
||||||
GamesToFarm[appID] = 2;
|
if (timeNode == null) {
|
||||||
|
Logging.LogNullError("timeNode", Bot.BotName);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
string hoursString = timeNode.InnerText;
|
||||||
|
if (string.IsNullOrEmpty(hoursString)) {
|
||||||
|
Logging.LogNullError("hoursString", Bot.BotName);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
float hours = 0;
|
||||||
|
|
||||||
|
Match match = Regex.Match(hoursString, @"[0-9\.,]+");
|
||||||
|
if (match.Success) {
|
||||||
|
float.TryParse(match.Value, NumberStyles.Number, CultureInfo.InvariantCulture, out hours);
|
||||||
|
}
|
||||||
|
|
||||||
|
GamesToFarm[appID] = hours;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -351,50 +329,15 @@ namespace ArchiSteamFarm {
|
|||||||
CheckPage(htmlDocument);
|
CheckPage(htmlDocument);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task CheckHours(uint appID) {
|
|
||||||
if (appID == 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
HtmlDocument htmlDocument = await Bot.ArchiWebHandler.GetGameCardsPage(appID).ConfigureAwait(false);
|
|
||||||
if (htmlDocument == null) {
|
|
||||||
Logging.LogNullError("htmlDocument", Bot.BotName);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
HtmlNode htmlNode = htmlDocument.DocumentNode.SelectSingleNode("//div[@class='badge_title_stats_playtime']");
|
|
||||||
if (htmlNode == null) {
|
|
||||||
Logging.LogNullError("htmlNode", Bot.BotName);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
string hoursString = htmlNode.InnerText;
|
|
||||||
if (string.IsNullOrEmpty(hoursString)) {
|
|
||||||
Logging.LogNullError("hoursString", Bot.BotName);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
hoursString = Regex.Match(hoursString, @"[0-9\.,]+").Value;
|
|
||||||
float hours;
|
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(hoursString)) {
|
|
||||||
hours = 0;
|
|
||||||
} else {
|
|
||||||
hours = float.Parse(hoursString, CultureInfo.InvariantCulture);
|
|
||||||
}
|
|
||||||
|
|
||||||
GamesToFarm[appID] = hours;
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task CheckGamesForFarming() {
|
private async Task CheckGamesForFarming() {
|
||||||
if (NowFarming || ManualMode || GamesToFarm.Count > 0 || !Bot.SteamClient.IsConnected) {
|
if (NowFarming || ManualMode || !Bot.SteamClient.IsConnected) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
await StartFarming().ConfigureAwait(false);
|
await StartFarming().ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<bool?> ShouldFarm(ulong appID) {
|
private async Task<bool?> ShouldFarm(uint appID) {
|
||||||
if (appID == 0) {
|
if (appID == 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -406,26 +349,89 @@ namespace ArchiSteamFarm {
|
|||||||
|
|
||||||
HtmlNode htmlNode = htmlDocument.DocumentNode.SelectSingleNode("//span[@class='progress_info_bold']");
|
HtmlNode htmlNode = htmlDocument.DocumentNode.SelectSingleNode("//span[@class='progress_info_bold']");
|
||||||
if (htmlNode == null) {
|
if (htmlNode == null) {
|
||||||
await Bot.ArchiWebHandler.ReconnectIfNeeded().ConfigureAwait(false);
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return !htmlNode.InnerText.Contains("No card drops");
|
return !htmlNode.InnerText.Contains("No card drops");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private bool FarmMultiple() {
|
||||||
|
if (GamesToFarm.Count == 0) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
float maxHour = 0;
|
||||||
|
foreach (KeyValuePair<uint, float> game in GamesToFarm) {
|
||||||
|
CurrentGamesFarming.Add(game.Key);
|
||||||
|
if (game.Value > maxHour) {
|
||||||
|
maxHour = game.Value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (maxHour >= 2) {
|
||||||
|
CurrentGamesFarming.Clear();
|
||||||
|
CurrentGamesFarming.TrimExcess();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Logging.LogGenericInfo("Now farming: " + string.Join(", ", CurrentGamesFarming), Bot.BotName);
|
||||||
|
if (FarmHours(maxHour, CurrentGamesFarming)) {
|
||||||
|
CurrentGamesFarming.Clear();
|
||||||
|
CurrentGamesFarming.TrimExcess();
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
CurrentGamesFarming.Clear();
|
||||||
|
CurrentGamesFarming.TrimExcess();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task<bool> FarmSolo(uint appID) {
|
||||||
|
if (appID == 0) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
CurrentGamesFarming.Add(appID);
|
||||||
|
|
||||||
|
Logging.LogGenericInfo("Now farming: " + appID, Bot.BotName);
|
||||||
|
if (await Farm(appID).ConfigureAwait(false)) {
|
||||||
|
CurrentGamesFarming.Clear();
|
||||||
|
CurrentGamesFarming.TrimExcess();
|
||||||
|
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();
|
||||||
|
CurrentGamesFarming.TrimExcess();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private async Task<bool> Farm(uint appID) {
|
private async Task<bool> Farm(uint appID) {
|
||||||
|
if (appID == 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
Bot.ArchiHandler.PlayGames(appID);
|
Bot.ArchiHandler.PlayGames(appID);
|
||||||
|
|
||||||
bool success = true;
|
bool success = true;
|
||||||
|
|
||||||
bool? keepFarming = await ShouldFarm(appID).ConfigureAwait(false);
|
bool? keepFarming = await ShouldFarm(appID).ConfigureAwait(false);
|
||||||
for (ushort farmingTime = 0; farmingTime <= MaxFarmingTime && (!keepFarming.HasValue || keepFarming.Value); farmingTime += StatusCheckSleep) {
|
for (ushort farmingTime = 0; farmingTime <= 60 * Program.GlobalConfig.MaxFarmingTime && keepFarming.GetValueOrDefault(true); farmingTime += Program.GlobalConfig.FarmingDelay) {
|
||||||
Logging.LogGenericInfo("Still farming: " + appID, Bot.BotName);
|
if (FarmResetEvent.Wait(60 * 1000 * Program.GlobalConfig.FarmingDelay)) {
|
||||||
if (FarmResetEvent.WaitOne(1000 * 60 * StatusCheckSleep)) {
|
|
||||||
success = false;
|
success = false;
|
||||||
break;
|
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);
|
keepFarming = await ShouldFarm(appID).ConfigureAwait(false);
|
||||||
|
Logging.LogGenericInfo("Still farming: " + appID, Bot.BotName);
|
||||||
}
|
}
|
||||||
|
|
||||||
Bot.ResetGamesPlayed();
|
Bot.ResetGamesPlayed();
|
||||||
@@ -433,7 +439,11 @@ namespace ArchiSteamFarm {
|
|||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool Farm(float maxHour, ICollection<uint> appIDs) {
|
private bool FarmHours(float maxHour, HashSet<uint> appIDs) {
|
||||||
|
if (maxHour < 0 || appIDs == null || appIDs.Count == 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (maxHour >= 2) {
|
if (maxHour >= 2) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -442,23 +452,19 @@ namespace ArchiSteamFarm {
|
|||||||
|
|
||||||
bool success = true;
|
bool success = true;
|
||||||
while (maxHour < 2) {
|
while (maxHour < 2) {
|
||||||
Logging.LogGenericInfo("Still farming: " + string.Join(", ", appIDs), Bot.BotName);
|
if (FarmResetEvent.Wait(60 * 1000 * Program.GlobalConfig.FarmingDelay)) {
|
||||||
if (FarmResetEvent.WaitOne(1000 * 60 * StatusCheckSleep)) {
|
|
||||||
success = false;
|
success = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Don't forget to update our GamesToFarm hours
|
// Don't forget to update our GamesToFarm hours
|
||||||
float timePlayed = StatusCheckSleep / 60.0F;
|
float timePlayed = Program.GlobalConfig.FarmingDelay / 60.0F;
|
||||||
foreach (KeyValuePair<uint, float> gameToFarm in GamesToFarm) {
|
foreach (uint appID in appIDs) {
|
||||||
if (!appIDs.Contains(gameToFarm.Key)) {
|
GamesToFarm[appID] += timePlayed;
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
GamesToFarm[gameToFarm.Key] = gameToFarm.Value + timePlayed;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
maxHour += timePlayed;
|
maxHour += timePlayed;
|
||||||
|
Logging.LogGenericInfo("Still farming: " + string.Join(", ", appIDs), Bot.BotName);
|
||||||
}
|
}
|
||||||
|
|
||||||
Bot.ResetGamesPlayed();
|
Bot.ResetGamesPlayed();
|
||||||
|
|||||||
@@ -22,6 +22,10 @@
|
|||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
using SteamKit2;
|
||||||
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
|
||||||
namespace ArchiSteamFarm {
|
namespace ArchiSteamFarm {
|
||||||
internal static class Debugging {
|
internal static class Debugging {
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
@@ -33,5 +37,27 @@ namespace ArchiSteamFarm {
|
|||||||
internal static bool IsReleaseBuild => !IsDebugBuild;
|
internal static bool IsReleaseBuild => !IsDebugBuild;
|
||||||
|
|
||||||
internal static bool NetHookAlreadyInitialized { get; set; } = false;
|
internal static bool NetHookAlreadyInitialized { get; set; } = false;
|
||||||
|
|
||||||
|
internal sealed class DebugListener : IDebugListener {
|
||||||
|
private readonly string FilePath;
|
||||||
|
|
||||||
|
internal DebugListener(string filePath) {
|
||||||
|
if (string.IsNullOrEmpty(filePath)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
FilePath = filePath;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void WriteLine(string category, string msg) {
|
||||||
|
lock (FilePath) {
|
||||||
|
try {
|
||||||
|
File.AppendAllText(FilePath, category + " | " + msg + Environment.NewLine);
|
||||||
|
} catch (Exception e) {
|
||||||
|
Logging.LogGenericException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ using Newtonsoft.Json;
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System.Net.Sockets;
|
||||||
|
|
||||||
namespace ArchiSteamFarm {
|
namespace ArchiSteamFarm {
|
||||||
internal sealed class GlobalConfig {
|
internal sealed class GlobalConfig {
|
||||||
@@ -35,38 +36,85 @@ namespace ArchiSteamFarm {
|
|||||||
Experimental
|
Experimental
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal const byte DefaultHttpTimeout = 60;
|
||||||
|
|
||||||
|
private const byte DefaultMaxFarmingTime = 10;
|
||||||
|
private const byte DefaultFarmingDelay = 5;
|
||||||
|
private const ushort DefaultWCFPort = 1242;
|
||||||
|
private const ProtocolType DefaultSteamProtocol = ProtocolType.Tcp;
|
||||||
|
|
||||||
// This is hardcoded blacklist which should not be possible to change
|
// 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 };
|
internal static readonly HashSet<uint> GlobalBlacklist = new HashSet<uint> { 267420, 303700, 335590, 368020, 425280 };
|
||||||
|
|
||||||
[JsonProperty(Required = Required.DisallowNull)]
|
[JsonProperty(Required = Required.DisallowNull)]
|
||||||
internal bool Debug { get; private set; } = false;
|
internal bool Debug { get; private set; } = false;
|
||||||
|
|
||||||
|
[JsonProperty(Required = Required.DisallowNull)]
|
||||||
|
internal bool Headless { get; private set; } = false;
|
||||||
|
|
||||||
[JsonProperty(Required = Required.DisallowNull)]
|
[JsonProperty(Required = Required.DisallowNull)]
|
||||||
internal bool AutoUpdates { get; private set; } = true;
|
internal bool AutoUpdates { get; private set; } = true;
|
||||||
|
|
||||||
[JsonProperty(Required = Required.DisallowNull)]
|
[JsonProperty(Required = Required.DisallowNull)]
|
||||||
internal EUpdateChannel UpdateChannel { get; private set; } = GlobalConfig.EUpdateChannel.Stable;
|
internal bool AutoRestart { get; private set; } = true;
|
||||||
|
|
||||||
[JsonProperty(Required = Required.DisallowNull)]
|
[JsonProperty(Required = Required.DisallowNull)]
|
||||||
internal byte HttpTimeout { get; private set; } = 30;
|
internal EUpdateChannel UpdateChannel { get; private set; } = EUpdateChannel.Stable;
|
||||||
|
|
||||||
|
[JsonProperty(Required = Required.DisallowNull)]
|
||||||
|
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; } = DefaultMaxFarmingTime;
|
||||||
|
|
||||||
|
[JsonProperty(Required = Required.DisallowNull)]
|
||||||
|
internal byte IdleFarmingPeriod { get; private set; } = 3;
|
||||||
|
|
||||||
|
[JsonProperty(Required = Required.DisallowNull)]
|
||||||
|
internal byte FarmingDelay { get; private set; } = DefaultFarmingDelay;
|
||||||
|
|
||||||
[JsonProperty(Required = Required.DisallowNull)]
|
[JsonProperty(Required = Required.DisallowNull)]
|
||||||
internal byte AccountPlayingDelay { get; private set; } = 5;
|
internal byte AccountPlayingDelay { get; private set; } = 5;
|
||||||
|
|
||||||
[JsonProperty(Required = Required.DisallowNull)]
|
[JsonProperty(Required = Required.DisallowNull)]
|
||||||
internal byte RequestLimiterDelay { get; private set; } = 7;
|
internal byte LoginLimiterDelay { get; private set; } = 7;
|
||||||
|
|
||||||
[JsonProperty(Required = Required.DisallowNull)]
|
[JsonProperty(Required = Required.DisallowNull)]
|
||||||
internal string WCFHostname { get; private set; } = "localhost";
|
internal byte InventoryLimiterDelay { get; private set; } = 3;
|
||||||
|
|
||||||
[JsonProperty(Required = Required.DisallowNull)]
|
[JsonProperty(Required = Required.DisallowNull)]
|
||||||
internal ushort WCFPort { get; private set; } = 1242;
|
internal bool ForceHttp { get; private set; } = false;
|
||||||
|
|
||||||
|
[JsonProperty(Required = Required.DisallowNull)]
|
||||||
|
internal byte HttpTimeout { get; private set; } = DefaultHttpTimeout;
|
||||||
|
|
||||||
|
[JsonProperty]
|
||||||
|
internal string WCFHostname { get; set; } = "localhost";
|
||||||
|
|
||||||
|
[JsonProperty(Required = Required.DisallowNull)]
|
||||||
|
internal ushort WCFPort { get; private set; } = DefaultWCFPort;
|
||||||
|
|
||||||
|
[JsonProperty(Required = Required.DisallowNull)]
|
||||||
|
internal bool LogToFile { get; private set; } = true;
|
||||||
|
|
||||||
|
[JsonProperty(Required = Required.DisallowNull)]
|
||||||
|
internal bool Statistics { get; private set; } = true;
|
||||||
|
|
||||||
|
// TODO: Please remove me immediately after https://github.com/SteamRE/SteamKit/issues/254 gets fixed
|
||||||
|
[JsonProperty(Required = Required.DisallowNull)]
|
||||||
|
internal bool HackIgnoreMachineID { get; private set; } = false;
|
||||||
|
|
||||||
[JsonProperty(Required = Required.DisallowNull)]
|
[JsonProperty(Required = Required.DisallowNull)]
|
||||||
internal HashSet<uint> Blacklist { get; private set; } = new HashSet<uint>(GlobalBlacklist);
|
internal HashSet<uint> Blacklist { get; private set; } = new HashSet<uint>(GlobalBlacklist);
|
||||||
|
|
||||||
internal static GlobalConfig Load() {
|
internal static GlobalConfig Load(string filePath) {
|
||||||
string filePath = Path.Combine(Program.ConfigDirectory, Program.GlobalConfigFile);
|
if (string.IsNullOrEmpty(filePath)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
if (!File.Exists(filePath)) {
|
if (!File.Exists(filePath)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -79,6 +127,44 @@ namespace ArchiSteamFarm {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (globalConfig == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// SK2 supports only TCP and UDP steam protocols
|
||||||
|
// 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 + ". 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;
|
return globalConfig;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -23,14 +23,11 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using SteamAuth;
|
|
||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
|
||||||
namespace ArchiSteamFarm {
|
namespace ArchiSteamFarm {
|
||||||
internal sealed class GlobalDatabase {
|
internal sealed class GlobalDatabase {
|
||||||
private static readonly string FilePath = Path.Combine(Program.ConfigDirectory, Program.GlobalDatabaseFile);
|
|
||||||
|
|
||||||
internal uint CellID {
|
internal uint CellID {
|
||||||
get {
|
get {
|
||||||
return _CellID;
|
return _CellID;
|
||||||
@@ -46,24 +43,45 @@ namespace ArchiSteamFarm {
|
|||||||
}
|
}
|
||||||
|
|
||||||
[JsonProperty(Required = Required.DisallowNull)]
|
[JsonProperty(Required = Required.DisallowNull)]
|
||||||
private uint _CellID = 0;
|
private uint _CellID;
|
||||||
|
|
||||||
internal static GlobalDatabase Load() {
|
private string FilePath;
|
||||||
if (!File.Exists(FilePath)) {
|
|
||||||
return new GlobalDatabase();
|
internal static GlobalDatabase Load(string filePath) {
|
||||||
|
if (string.IsNullOrEmpty(filePath)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!File.Exists(filePath)) {
|
||||||
|
return new GlobalDatabase(filePath);
|
||||||
}
|
}
|
||||||
|
|
||||||
GlobalDatabase globalDatabase;
|
GlobalDatabase globalDatabase;
|
||||||
try {
|
try {
|
||||||
globalDatabase = JsonConvert.DeserializeObject<GlobalDatabase>(File.ReadAllText(FilePath));
|
globalDatabase = JsonConvert.DeserializeObject<GlobalDatabase>(File.ReadAllText(filePath));
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Logging.LogGenericException(e);
|
Logging.LogGenericException(e);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (globalDatabase == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
globalDatabase.FilePath = filePath;
|
||||||
return globalDatabase;
|
return globalDatabase;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This constructor is used when creating new database
|
||||||
|
private GlobalDatabase(string filePath) {
|
||||||
|
if (string.IsNullOrEmpty(filePath)) {
|
||||||
|
throw new ArgumentNullException("filePath");
|
||||||
|
}
|
||||||
|
|
||||||
|
FilePath = filePath;
|
||||||
|
Save();
|
||||||
|
}
|
||||||
|
|
||||||
// This constructor is used only by deserializer
|
// This constructor is used only by deserializer
|
||||||
private GlobalDatabase() { }
|
private GlobalDatabase() { }
|
||||||
|
|
||||||
|
|||||||
122
ArchiSteamFarm/JSON/Steam.cs
Normal file
122
ArchiSteamFarm/JSON/Steam.cs
Normal file
@@ -0,0 +1,122 @@
|
|||||||
|
/*
|
||||||
|
_ _ _ ____ _ _____
|
||||||
|
/ \ _ __ ___ | |__ (_)/ ___| | |_ ___ __ _ _ __ ___ | ___|__ _ _ __ _ __ ___
|
||||||
|
/ _ \ | '__|/ __|| '_ \ | |\___ \ | __|/ _ \ / _` || '_ ` _ \ | |_ / _` || '__|| '_ ` _ \
|
||||||
|
/ ___ \ | | | (__ | | | || | ___) || |_| __/| (_| || | | | | || _|| (_| || | | | | | | |
|
||||||
|
/_/ \_\|_| \___||_| |_||_||____/ \__|\___| \__,_||_| |_| |_||_| \__,_||_| |_| |_| |_|
|
||||||
|
|
||||||
|
Copyright 2015-2016 Łukasz "JustArchi" Domeradzki
|
||||||
|
Contact: JustArchi@JustArchi.net
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using SteamKit2;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace ArchiSteamFarm {
|
||||||
|
internal static class Steam {
|
||||||
|
internal sealed class Item {
|
||||||
|
// REF: https://developer.valvesoftware.com/wiki/Steam_Web_API/IEconService#CEcon_Asset
|
||||||
|
[JsonProperty(Required = Required.DisallowNull)]
|
||||||
|
internal string appid { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty(Required = Required.DisallowNull)]
|
||||||
|
internal string contextid { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty(Required = Required.DisallowNull)]
|
||||||
|
internal string assetid { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty(Required = Required.DisallowNull)]
|
||||||
|
internal string id {
|
||||||
|
get { return assetid; }
|
||||||
|
set { assetid = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
[JsonProperty(Required = Required.AllowNull)]
|
||||||
|
internal string classid { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty(Required = Required.AllowNull)]
|
||||||
|
internal string instanceid { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty(Required = Required.Always)]
|
||||||
|
internal string amount { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
internal sealed class ItemList {
|
||||||
|
[JsonProperty(Required = Required.Always)]
|
||||||
|
internal List<Steam.Item> assets { get; } = new List<Steam.Item>();
|
||||||
|
}
|
||||||
|
|
||||||
|
internal sealed class TradeOffer {
|
||||||
|
// REF: https://developer.valvesoftware.com/wiki/Steam_Web_API/IEconService#CEcon_TradeOffer
|
||||||
|
internal enum ETradeOfferState : byte {
|
||||||
|
Unknown,
|
||||||
|
Invalid,
|
||||||
|
Active,
|
||||||
|
Accepted,
|
||||||
|
Countered,
|
||||||
|
Expired,
|
||||||
|
Canceled,
|
||||||
|
Declined,
|
||||||
|
InvalidItems,
|
||||||
|
EmailPending,
|
||||||
|
EmailCanceled,
|
||||||
|
OnHold
|
||||||
|
}
|
||||||
|
|
||||||
|
[JsonProperty(Required = Required.Always)]
|
||||||
|
internal string tradeofferid { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty(Required = Required.Always)]
|
||||||
|
internal uint accountid_other { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty(Required = Required.Always)]
|
||||||
|
internal ETradeOfferState trade_offer_state { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty(Required = Required.Always)]
|
||||||
|
internal List<Steam.Item> items_to_give { get; } = new List<Steam.Item>();
|
||||||
|
|
||||||
|
[JsonProperty(Required = Required.Always)]
|
||||||
|
internal List<Steam.Item> items_to_receive { get; } = new List<Steam.Item>();
|
||||||
|
|
||||||
|
// Extra
|
||||||
|
private ulong _OtherSteamID64 = 0;
|
||||||
|
internal ulong OtherSteamID64 {
|
||||||
|
get {
|
||||||
|
if (_OtherSteamID64 == 0 && accountid_other != 0) {
|
||||||
|
_OtherSteamID64 = new SteamID(accountid_other, EUniverse.Public, EAccountType.Individual).ConvertToUInt64();
|
||||||
|
}
|
||||||
|
|
||||||
|
return _OtherSteamID64;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal sealed class TradeOfferRequest {
|
||||||
|
[JsonProperty(Required = Required.Always)]
|
||||||
|
internal bool newversion { get; } = true;
|
||||||
|
|
||||||
|
[JsonProperty(Required = Required.Always)]
|
||||||
|
internal int version { get; } = 2;
|
||||||
|
|
||||||
|
[JsonProperty(Required = Required.Always)]
|
||||||
|
internal Steam.ItemList me { get; } = new Steam.ItemList();
|
||||||
|
|
||||||
|
[JsonProperty(Required = Required.Always)]
|
||||||
|
internal Steam.ItemList them { get; } = new Steam.ItemList();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -31,18 +31,18 @@ namespace ArchiSteamFarm {
|
|||||||
internal static class Logging {
|
internal static class Logging {
|
||||||
private static readonly object FileLock = new object();
|
private static readonly object FileLock = new object();
|
||||||
|
|
||||||
internal static bool? LogToFile { get; set; } = null;
|
private static bool LogToFile;
|
||||||
|
|
||||||
internal static void Init() {
|
internal static void Init() {
|
||||||
if (!LogToFile.HasValue) {
|
LogToFile = Program.GlobalConfig.LogToFile;
|
||||||
LogToFile = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
lock (FileLock) {
|
if (LogToFile) {
|
||||||
try {
|
lock (FileLock) {
|
||||||
File.Delete(Program.LogFile);
|
try {
|
||||||
} catch (Exception e) {
|
File.Delete(Program.LogFile);
|
||||||
LogGenericException(e);
|
} catch (Exception e) {
|
||||||
|
LogGenericException(e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -69,11 +69,10 @@ namespace ArchiSteamFarm {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Log("[!] EXCEPTION: " + previousMethodName + "() <" + botName + "> " + exception.Message);
|
Log("[!] EXCEPTION: " + previousMethodName + "() <" + botName + "> " + exception.Message);
|
||||||
Log("[!] StackTrace: " + exception.StackTrace);
|
Log("[!] StackTrace:" + Environment.NewLine + exception.StackTrace);
|
||||||
|
|
||||||
Exception innerException = exception.InnerException;
|
if (exception.InnerException != null) {
|
||||||
if (innerException != null) {
|
LogGenericException(exception.InnerException, botName, previousMethodName);
|
||||||
LogGenericException(innerException, botName, previousMethodName);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -119,17 +118,18 @@ namespace ArchiSteamFarm {
|
|||||||
|
|
||||||
// Write on console only when not awaiting response from user
|
// Write on console only when not awaiting response from user
|
||||||
if (!Program.ConsoleIsBusy) {
|
if (!Program.ConsoleIsBusy) {
|
||||||
Console.Write(loggedMessage);
|
try {
|
||||||
|
Console.Write(loggedMessage);
|
||||||
|
} catch { }
|
||||||
}
|
}
|
||||||
|
|
||||||
if (LogToFile.GetValueOrDefault()) {
|
if (LogToFile) {
|
||||||
lock (FileLock) {
|
lock (FileLock) {
|
||||||
try {
|
try {
|
||||||
File.AppendAllText(Program.LogFile, loggedMessage);
|
File.AppendAllText(Program.LogFile, loggedMessage);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
LogToFile = false;
|
LogToFile = false;
|
||||||
LogGenericException(e);
|
LogGenericException(e);
|
||||||
LogToFile = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ using System;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
@@ -34,6 +35,8 @@ using System.Threading.Tasks;
|
|||||||
namespace ArchiSteamFarm {
|
namespace ArchiSteamFarm {
|
||||||
internal static class Program {
|
internal static class Program {
|
||||||
internal enum EUserInputType : byte {
|
internal enum EUserInputType : byte {
|
||||||
|
Unknown,
|
||||||
|
DeviceID,
|
||||||
Login,
|
Login,
|
||||||
Password,
|
Password,
|
||||||
PhoneNumber,
|
PhoneNumber,
|
||||||
@@ -42,51 +45,57 @@ namespace ArchiSteamFarm {
|
|||||||
SteamParentalPIN,
|
SteamParentalPIN,
|
||||||
RevocationCode,
|
RevocationCode,
|
||||||
TwoFactorAuthentication,
|
TwoFactorAuthentication,
|
||||||
|
WCFHostname
|
||||||
}
|
}
|
||||||
|
|
||||||
internal enum EMode : byte {
|
internal enum EMode : byte {
|
||||||
|
Unknown,
|
||||||
Normal, // Standard most common usage
|
Normal, // Standard most common usage
|
||||||
Client, // WCF client only
|
Client, // WCF client only
|
||||||
Server // Normal + WCF server
|
Server // Normal + WCF server
|
||||||
}
|
}
|
||||||
|
|
||||||
private const string GithubReleaseURL = "https://api.github.com/repos/JustArchi/ArchiSteamFarm/releases";
|
|
||||||
|
|
||||||
internal const string ASF = "ASF";
|
internal const string ASF = "ASF";
|
||||||
internal const string ConfigDirectory = "config";
|
internal const string ConfigDirectory = "config";
|
||||||
internal const string DebugDirectory = "debug";
|
internal const string DebugDirectory = "debug";
|
||||||
internal const string LogFile = "log.txt";
|
internal const string LogFile = "log.txt";
|
||||||
|
internal const string GithubRepo = "JustArchi/ArchiSteamFarm";
|
||||||
internal const string GlobalConfigFile = ASF + ".json";
|
internal const string GlobalConfigFile = ASF + ".json";
|
||||||
internal const string GlobalDatabaseFile = ASF + ".db";
|
internal const string GlobalDatabaseFile = ASF + ".db";
|
||||||
|
|
||||||
|
private const string GithubReleaseURL = "https://api.github.com/repos/" + GithubRepo + "/releases"; // GitHub API is HTTPS only
|
||||||
|
|
||||||
|
internal static readonly Version Version = Assembly.GetEntryAssembly().GetName().Version;
|
||||||
|
|
||||||
private static readonly object ConsoleLock = new object();
|
private static readonly object ConsoleLock = new object();
|
||||||
private static readonly SemaphoreSlim SteamSemaphore = new SemaphoreSlim(1);
|
private static readonly SemaphoreSlim SteamSemaphore = new SemaphoreSlim(1);
|
||||||
private static readonly ManualResetEvent ShutdownResetEvent = new ManualResetEvent(false);
|
private static readonly ManualResetEventSlim ShutdownResetEvent = new ManualResetEventSlim(false);
|
||||||
private static readonly Assembly Assembly = Assembly.GetExecutingAssembly();
|
private static readonly string ExecutableFile = Assembly.GetEntryAssembly().Location;
|
||||||
private static readonly string ExecutableFile = Assembly.Location;
|
|
||||||
private static readonly string ExecutableName = Path.GetFileName(ExecutableFile);
|
private static readonly string ExecutableName = Path.GetFileName(ExecutableFile);
|
||||||
private static readonly string ExecutableDirectory = Path.GetDirectoryName(ExecutableFile);
|
private static readonly string ExecutableDirectory = Path.GetDirectoryName(ExecutableFile);
|
||||||
private static readonly WCF WCF = new WCF();
|
private static readonly WCF WCF = new WCF();
|
||||||
|
|
||||||
internal static readonly string Version = Assembly.GetName().Version.ToString();
|
|
||||||
|
|
||||||
internal static GlobalConfig GlobalConfig { get; private set; }
|
internal static GlobalConfig GlobalConfig { get; private set; }
|
||||||
internal static GlobalDatabase GlobalDatabase { get; private set; }
|
internal static GlobalDatabase GlobalDatabase { get; private set; }
|
||||||
internal static bool ConsoleIsBusy { get; private set; } = false;
|
internal static bool ConsoleIsBusy { get; private set; } = false;
|
||||||
|
|
||||||
private static Timer AutoUpdatesTimer;
|
private static Timer AutoUpdatesTimer;
|
||||||
private static EMode Mode = EMode.Normal;
|
private static EMode Mode = EMode.Normal;
|
||||||
|
private static WebBrowser WebBrowser;
|
||||||
|
|
||||||
private static async Task CheckForUpdate() {
|
internal static async Task CheckForUpdate() {
|
||||||
string oldExeFile = ExecutableFile + ".old";
|
string oldExeFile = ExecutableFile + ".old";
|
||||||
|
|
||||||
// We booted successfully so we can now remove old exe file
|
// We booted successfully so we can now remove old exe file
|
||||||
if (File.Exists(oldExeFile)) {
|
if (File.Exists(oldExeFile)) {
|
||||||
|
// It's entirely possible that old process is still running, allow at least a second before trying to remove the file
|
||||||
|
await Utilities.SleepAsync(1000).ConfigureAwait(false);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
File.Delete(oldExeFile);
|
File.Delete(oldExeFile);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Logging.LogGenericException(e);
|
Logging.LogGenericException(e);
|
||||||
return;
|
Logging.LogGenericError("Could not remove old ASF binary, please remove " + oldExeFile + " manually in order for update function to work!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -110,7 +119,7 @@ namespace ArchiSteamFarm {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
GitHub.ReleaseResponse releaseResponse = null;
|
GitHub.ReleaseResponse releaseResponse;
|
||||||
if (GlobalConfig.UpdateChannel == GlobalConfig.EUpdateChannel.Stable) {
|
if (GlobalConfig.UpdateChannel == GlobalConfig.EUpdateChannel.Stable) {
|
||||||
try {
|
try {
|
||||||
releaseResponse = JsonConvert.DeserializeObject<GitHub.ReleaseResponse>(response);
|
releaseResponse = JsonConvert.DeserializeObject<GitHub.ReleaseResponse>(response);
|
||||||
@@ -140,11 +149,12 @@ namespace ArchiSteamFarm {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Logging.LogGenericInfo("Local version: " + Version + " | Remote version: " + releaseResponse.Tag);
|
Version newVersion = new Version(releaseResponse.Tag);
|
||||||
|
|
||||||
if (Version.CompareTo(releaseResponse.Tag) >= 0) { // If local version is the same or newer than remote version
|
Logging.LogGenericInfo("Local version: " + Version + " | Remote version: " + newVersion);
|
||||||
// Set up a timer that will automatically update ASF on as-needed basis
|
|
||||||
if (GlobalConfig.AutoUpdates && AutoUpdatesTimer == null) {
|
if (Version.CompareTo(newVersion) >= 0) { // If local version is the same or newer than remote version
|
||||||
|
if (AutoUpdatesTimer == null && GlobalConfig.AutoUpdates) {
|
||||||
Logging.LogGenericInfo("ASF will automatically check for new versions every 24 hours");
|
Logging.LogGenericInfo("ASF will automatically check for new versions every 24 hours");
|
||||||
AutoUpdatesTimer = new Timer(
|
AutoUpdatesTimer = new Timer(
|
||||||
async e => await CheckForUpdate().ConfigureAwait(false),
|
async e => await CheckForUpdate().ConfigureAwait(false),
|
||||||
@@ -163,6 +173,11 @@ namespace ArchiSteamFarm {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (File.Exists(oldExeFile)) {
|
||||||
|
Logging.LogGenericWarning("Refusing to proceed with auto update as old " + oldExeFile + " binary could not be removed, please remove it manually");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Auto update logic starts here
|
// Auto update logic starts here
|
||||||
if (releaseResponse.Assets == null) {
|
if (releaseResponse.Assets == null) {
|
||||||
Logging.LogGenericWarning("Could not proceed with update because that version doesn't include assets!");
|
Logging.LogGenericWarning("Could not proceed with update because that version doesn't include assets!");
|
||||||
@@ -171,7 +186,7 @@ namespace ArchiSteamFarm {
|
|||||||
|
|
||||||
GitHub.Asset binaryAsset = null;
|
GitHub.Asset binaryAsset = null;
|
||||||
foreach (var asset in releaseResponse.Assets) {
|
foreach (var asset in releaseResponse.Assets) {
|
||||||
if (string.IsNullOrEmpty(asset.Name) || !asset.Name.Equals(ExecutableName)) {
|
if (string.IsNullOrEmpty(asset.Name) || !asset.Name.Equals(ExecutableName, StringComparison.OrdinalIgnoreCase)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -189,21 +204,22 @@ namespace ArchiSteamFarm {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Logging.LogGenericInfo("Downloading new version...");
|
byte[] result = null;
|
||||||
Stream newExe = await WebBrowser.UrlGetToStream(binaryAsset.DownloadURL).ConfigureAwait(false);
|
for (byte i = 0; i < WebBrowser.MaxRetries && result == null; i++) {
|
||||||
if (newExe == null) {
|
Logging.LogGenericInfo("Downloading new version...");
|
||||||
Logging.LogGenericWarning("Could not download new version!");
|
result = await WebBrowser.UrlGetToBytes(binaryAsset.DownloadURL).ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result == null) {
|
||||||
|
Logging.LogGenericWTF("Request failed even after " + WebBrowser.MaxRetries + " tries");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// We start deep update logic here
|
|
||||||
string newExeFile = ExecutableFile + ".new";
|
string newExeFile = ExecutableFile + ".new";
|
||||||
|
|
||||||
// Firstly we create new exec
|
// Firstly we create new exec
|
||||||
try {
|
try {
|
||||||
using (FileStream fileStream = File.Open(newExeFile, FileMode.Create)) {
|
File.WriteAllBytes(newExeFile, result);
|
||||||
await newExe.CopyToAsync(fileStream).ConfigureAwait(false);
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Logging.LogGenericException(e);
|
Logging.LogGenericException(e);
|
||||||
return;
|
return;
|
||||||
@@ -234,87 +250,99 @@ namespace ArchiSteamFarm {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Logging.LogGenericInfo("Update process is finished! ASF will now restart itself...");
|
Logging.LogGenericInfo("Update process finished!");
|
||||||
await Utilities.SleepAsync(5000);
|
|
||||||
|
|
||||||
if (!Restart()) {
|
if (GlobalConfig.AutoRestart) {
|
||||||
// Make sure that we won't try updating again in this case
|
Logging.LogGenericInfo("Restarting...");
|
||||||
if (AutoUpdatesTimer != null) {
|
await Utilities.SleepAsync(5000).ConfigureAwait(false);
|
||||||
AutoUpdatesTimer.Dispose();
|
Restart();
|
||||||
AutoUpdatesTimer = null;
|
} else {
|
||||||
}
|
Logging.LogGenericInfo("Exiting...");
|
||||||
|
await Utilities.SleepAsync(5000).ConfigureAwait(false);
|
||||||
// Inform user about failure
|
Exit();
|
||||||
Logging.LogGenericWarning("ASF could not restart itself, you may need to restart it manually!");
|
|
||||||
await Utilities.SleepAsync(5000);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static void Exit(int exitCode = 0) {
|
internal static void Exit(int exitCode = 0) {
|
||||||
|
WCF.StopServer();
|
||||||
Environment.Exit(exitCode);
|
Environment.Exit(exitCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static bool Restart() {
|
internal static void Restart() {
|
||||||
try {
|
try {
|
||||||
// TODO: This probably won't work on Mono, I wonder if I can make it work at some point
|
Process.Start(ExecutableFile, string.Join(" ", Environment.GetCommandLineArgs().Skip(1)));
|
||||||
if (Process.Start(ExecutableFile, string.Join(" ", Environment.GetCommandLineArgs())) != null) {
|
|
||||||
Exit();
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Logging.LogGenericException(e);
|
Logging.LogGenericException(e);
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static async Task LimitSteamRequestsAsync() {
|
internal static async Task LimitSteamRequestsAsync() {
|
||||||
await SteamSemaphore.WaitAsync().ConfigureAwait(false);
|
await SteamSemaphore.WaitAsync().ConfigureAwait(false);
|
||||||
Task.Run(async () => {
|
Task.Run(async () => {
|
||||||
await Utilities.SleepAsync(GlobalConfig.RequestLimiterDelay * 1000).ConfigureAwait(false);
|
await Utilities.SleepAsync(GlobalConfig.LoginLimiterDelay * 1000).ConfigureAwait(false);
|
||||||
SteamSemaphore.Release();
|
SteamSemaphore.Release();
|
||||||
}).Forget();
|
}).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;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (GlobalConfig.Headless) {
|
||||||
|
Logging.LogGenericWarning("Received a request for user input, but process is running in headless mode!");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
string result;
|
string result;
|
||||||
lock (ConsoleLock) {
|
lock (ConsoleLock) {
|
||||||
ConsoleIsBusy = true;
|
ConsoleIsBusy = true;
|
||||||
switch (userInputType) {
|
switch (userInputType) {
|
||||||
|
case EUserInputType.DeviceID:
|
||||||
|
Console.Write((string.IsNullOrEmpty(botName) ? "" : "<" + botName + "> ") + "Please enter your Device ID (including \"android:\"): ");
|
||||||
|
break;
|
||||||
case EUserInputType.Login:
|
case EUserInputType.Login:
|
||||||
Console.Write("<" + botLogin + "> Please enter your login: ");
|
Console.Write((string.IsNullOrEmpty(botName) ? "" : "<" + botName + "> ") + "Please enter your login: ");
|
||||||
break;
|
break;
|
||||||
case EUserInputType.Password:
|
case EUserInputType.Password:
|
||||||
Console.Write("<" + botLogin + "> Please enter your password: ");
|
Console.Write((string.IsNullOrEmpty(botName) ? "" : "<" + botName + "> ") + "Please enter your password: ");
|
||||||
break;
|
break;
|
||||||
case EUserInputType.PhoneNumber:
|
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;
|
break;
|
||||||
case EUserInputType.SMS:
|
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;
|
break;
|
||||||
case EUserInputType.SteamGuard:
|
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;
|
break;
|
||||||
case EUserInputType.SteamParentalPIN:
|
case EUserInputType.SteamParentalPIN:
|
||||||
Console.Write("<" + botLogin + "> Please enter steam parental PIN: ");
|
Console.Write((string.IsNullOrEmpty(botName) ? "" : "<" + botName + "> ") + "Please enter steam parental PIN: ");
|
||||||
break;
|
break;
|
||||||
case EUserInputType.RevocationCode:
|
case EUserInputType.RevocationCode:
|
||||||
Console.WriteLine("<" + botLogin + "> PLEASE WRITE DOWN YOUR REVOCATION CODE: " + extraInformation);
|
Console.WriteLine((string.IsNullOrEmpty(botName) ? "" : "<" + botName + "> ") + "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("Hit enter once ready...");
|
||||||
Console.Write("<" + botLogin + "> Hit enter once ready...");
|
|
||||||
break;
|
break;
|
||||||
case EUserInputType.TwoFactorAuthentication:
|
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((string.IsNullOrEmpty(botName) ? "" : "<" + botName + "> ") + "Please enter not documented yet value of \"" + userInputType + "\": ");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
result = Console.ReadLine();
|
result = Console.ReadLine();
|
||||||
Console.Clear(); // For security purposes
|
if (!Console.IsOutputRedirected) {
|
||||||
|
Console.Clear(); // For security purposes
|
||||||
|
}
|
||||||
ConsoleIsBusy = false;
|
ConsoleIsBusy = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return result.Trim(); // Get rid of all whitespace characters
|
return string.IsNullOrEmpty(result) ? null : result.Trim();
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static void OnBotShutdown() {
|
internal static void OnBotShutdown() {
|
||||||
@@ -329,18 +357,19 @@ namespace ArchiSteamFarm {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Logging.LogGenericInfo("No bots are running, exiting");
|
Logging.LogGenericInfo("No bots are running, exiting");
|
||||||
|
Thread.Sleep(5000);
|
||||||
ShutdownResetEvent.Set();
|
ShutdownResetEvent.Set();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void InitServices() {
|
private static void InitServices() {
|
||||||
GlobalConfig = GlobalConfig.Load();
|
GlobalConfig = GlobalConfig.Load(Path.Combine(ConfigDirectory, GlobalConfigFile));
|
||||||
if (GlobalConfig == null) {
|
if (GlobalConfig == null) {
|
||||||
Logging.LogGenericError("Global config could not be loaded, please make sure that ASF.db exists and is valid!");
|
Logging.LogGenericError("Global config could not be loaded, please make sure that ASF.json exists and is valid!");
|
||||||
Thread.Sleep(5000);
|
Thread.Sleep(5000);
|
||||||
Exit(1);
|
Exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
GlobalDatabase = GlobalDatabase.Load();
|
GlobalDatabase = GlobalDatabase.Load(Path.Combine(ConfigDirectory, GlobalDatabaseFile));
|
||||||
if (GlobalDatabase == null) {
|
if (GlobalDatabase == null) {
|
||||||
Logging.LogGenericError("Global database could not be loaded!");
|
Logging.LogGenericError("Global database could not be loaded!");
|
||||||
Thread.Sleep(5000);
|
Thread.Sleep(5000);
|
||||||
@@ -350,6 +379,8 @@ namespace ArchiSteamFarm {
|
|||||||
ArchiWebHandler.Init();
|
ArchiWebHandler.Init();
|
||||||
WebBrowser.Init();
|
WebBrowser.Init();
|
||||||
WCF.Init();
|
WCF.Init();
|
||||||
|
|
||||||
|
WebBrowser = new WebBrowser("Main");
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void ParseArgs(string[] args) {
|
private static void ParseArgs(string[] args) {
|
||||||
@@ -357,13 +388,6 @@ namespace ArchiSteamFarm {
|
|||||||
switch (arg) {
|
switch (arg) {
|
||||||
case "--client":
|
case "--client":
|
||||||
Mode = EMode.Client;
|
Mode = EMode.Client;
|
||||||
Logging.LogToFile = false;
|
|
||||||
break;
|
|
||||||
case "--log":
|
|
||||||
Logging.LogToFile = true;
|
|
||||||
break;
|
|
||||||
case "--no-log":
|
|
||||||
Logging.LogToFile = false;
|
|
||||||
break;
|
break;
|
||||||
case "--server":
|
case "--server":
|
||||||
Mode = EMode.Server;
|
Mode = EMode.Server;
|
||||||
@@ -380,10 +404,10 @@ namespace ArchiSteamFarm {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
Logging.LogGenericInfo("Command sent: \"" + arg + "\"");
|
Logging.LogGenericInfo("Command sent: " + arg);
|
||||||
|
|
||||||
// We intentionally execute this async block synchronously
|
// We intentionally execute this async block synchronously
|
||||||
Logging.LogGenericInfo("Response received: \"" + WCF.SendCommand(arg) + "\"");
|
Logging.LogGenericInfo("Response received: " + WCF.SendCommand(arg));
|
||||||
/*
|
/*
|
||||||
Task.Run(async () => {
|
Task.Run(async () => {
|
||||||
Logging.LogGenericNotice("WCF", "Response received: " + await WCF.SendCommand(arg).ConfigureAwait(false));
|
Logging.LogGenericNotice("WCF", "Response received: " + await WCF.SendCommand(arg).ConfigureAwait(false));
|
||||||
@@ -402,8 +426,17 @@ namespace ArchiSteamFarm {
|
|||||||
Logging.LogGenericException((Exception) args.ExceptionObject);
|
Logging.LogGenericException((Exception) args.ExceptionObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void Main(string[] args) {
|
private static void UnobservedTaskExceptionHandler(object sender, UnobservedTaskExceptionEventArgs args) {
|
||||||
|
if (sender == null || args == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Logging.LogGenericException(args.Exception);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void Init(string[] args) {
|
||||||
AppDomain.CurrentDomain.UnhandledException += UnhandledExceptionHandler;
|
AppDomain.CurrentDomain.UnhandledException += UnhandledExceptionHandler;
|
||||||
|
TaskScheduler.UnobservedTaskException += UnobservedTaskExceptionHandler;
|
||||||
|
|
||||||
Logging.LogGenericInfo("Archi's Steam Farm, version " + Version);
|
Logging.LogGenericInfo("Archi's Steam Farm, version " + Version);
|
||||||
Directory.SetCurrentDirectory(ExecutableDirectory);
|
Directory.SetCurrentDirectory(ExecutableDirectory);
|
||||||
@@ -426,12 +459,24 @@ namespace ArchiSteamFarm {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If debugging is on, we prepare debug directory prior to running
|
||||||
|
if (GlobalConfig.Debug) {
|
||||||
|
if (Directory.Exists(DebugDirectory)) {
|
||||||
|
Directory.Delete(DebugDirectory, true);
|
||||||
|
Thread.Sleep(1000); // Dirty workaround giving Windows some time to sync
|
||||||
|
}
|
||||||
|
Directory.CreateDirectory(DebugDirectory);
|
||||||
|
|
||||||
|
SteamKit2.DebugLog.AddListener(new Debugging.DebugListener(Path.Combine(Program.DebugDirectory, "debug.txt")));
|
||||||
|
SteamKit2.DebugLog.Enabled = true;
|
||||||
|
}
|
||||||
|
|
||||||
// Parse args
|
// Parse args
|
||||||
ParseArgs(args);
|
ParseArgs(args);
|
||||||
|
|
||||||
// If we ran ASF as a client, we're done by now
|
// If we ran ASF as a client, we're done by now
|
||||||
if (Mode == EMode.Client) {
|
if (Mode == EMode.Client) {
|
||||||
return;
|
Exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
// From now on it's server mode
|
// From now on it's server mode
|
||||||
@@ -448,40 +493,39 @@ namespace ArchiSteamFarm {
|
|||||||
// Before attempting to connect, initialize our list of CMs
|
// Before attempting to connect, initialize our list of CMs
|
||||||
Bot.RefreshCMs(GlobalDatabase.CellID).Wait();
|
Bot.RefreshCMs(GlobalDatabase.CellID).Wait();
|
||||||
|
|
||||||
|
bool isRunning = false;
|
||||||
|
|
||||||
foreach (var configFile in Directory.EnumerateFiles(ConfigDirectory, "*.json")) {
|
foreach (var configFile in Directory.EnumerateFiles(ConfigDirectory, "*.json")) {
|
||||||
string botName = Path.GetFileNameWithoutExtension(configFile);
|
string botName = Path.GetFileNameWithoutExtension(configFile);
|
||||||
if (botName.Equals(ASF)) {
|
switch (botName) {
|
||||||
continue;
|
case ASF:
|
||||||
|
case "example":
|
||||||
|
case "minimal":
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
Bot bot = new Bot(botName);
|
Bot bot = new Bot(botName);
|
||||||
if (!bot.BotConfig.Enabled) {
|
if (bot.BotConfig != null && bot.BotConfig.Enabled) {
|
||||||
|
isRunning = true;
|
||||||
|
} else {
|
||||||
Logging.LogGenericInfo("Not starting this instance because it's disabled in config file", botName);
|
Logging.LogGenericInfo("Not starting this instance because it's disabled in config file", botName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// CONVERSION START
|
|
||||||
foreach (var configFile in Directory.EnumerateFiles(ConfigDirectory, "*.xml")) {
|
|
||||||
string botName = Path.GetFileNameWithoutExtension(configFile);
|
|
||||||
Logging.LogGenericWarning("Found legacy " + botName + ".xml config file, it will now be converted to new ASF V2.0 format!");
|
|
||||||
Bot bot = new Bot(botName);
|
|
||||||
if (!bot.BotConfig.Enabled) {
|
|
||||||
Logging.LogGenericInfo("Not starting this instance because it's disabled in config file", botName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// CONVERSION END
|
|
||||||
|
|
||||||
// Check if we got any bots running
|
// Check if we got any bots running
|
||||||
OnBotShutdown();
|
if (!isRunning) {
|
||||||
|
OnBotShutdown();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void Main(string[] args) {
|
||||||
|
Init(args);
|
||||||
|
|
||||||
// Wait for signal to shutdown
|
// Wait for signal to shutdown
|
||||||
ShutdownResetEvent.WaitOne();
|
ShutdownResetEvent.Wait();
|
||||||
|
|
||||||
// We got a signal to shutdown, consider giving user some time to read the message
|
// We got a signal to shutdown
|
||||||
Thread.Sleep(5000);
|
Exit();
|
||||||
|
|
||||||
// This is over, cleanup only now
|
|
||||||
WCF.StopServer();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ using System.Runtime.InteropServices;
|
|||||||
[assembly: AssemblyConfiguration("")]
|
[assembly: AssemblyConfiguration("")]
|
||||||
[assembly: AssemblyCompany("")]
|
[assembly: AssemblyCompany("")]
|
||||||
[assembly: AssemblyProduct("ArchiSteamFarm")]
|
[assembly: AssemblyProduct("ArchiSteamFarm")]
|
||||||
[assembly: AssemblyCopyright("Copyright © Łukasz Domeradzki 2015-2016")]
|
[assembly: AssemblyCopyright("Copyright © ArchiSteamFarm 2015-2016")]
|
||||||
[assembly: AssemblyTrademark("")]
|
[assembly: AssemblyTrademark("")]
|
||||||
[assembly: AssemblyCulture("")]
|
[assembly: AssemblyCulture("")]
|
||||||
|
|
||||||
@@ -32,5 +32,5 @@ using System.Runtime.InteropServices;
|
|||||||
// You can specify all the values or you can default the Build and Revision Numbers
|
// You can specify all the values or you can default the Build and Revision Numbers
|
||||||
// by using the '*' as shown below:
|
// by using the '*' as shown below:
|
||||||
// [assembly: AssemblyVersion("1.0.*")]
|
// [assembly: AssemblyVersion("1.0.*")]
|
||||||
[assembly: AssemblyVersion("2.0.0.1")]
|
[assembly: AssemblyVersion("2.0.3.4")]
|
||||||
[assembly: AssemblyFileVersion("2.0.0.1")]
|
[assembly: AssemblyFileVersion("2.0.3.4")]
|
||||||
|
|||||||
@@ -1,74 +0,0 @@
|
|||||||
/*
|
|
||||||
_ _ _ ____ _ _____
|
|
||||||
/ \ _ __ ___ | |__ (_)/ ___| | |_ ___ __ _ _ __ ___ | ___|__ _ _ __ _ __ ___
|
|
||||||
/ _ \ | '__|/ __|| '_ \ | |\___ \ | __|/ _ \ / _` || '_ ` _ \ | |_ / _` || '__|| '_ ` _ \
|
|
||||||
/ ___ \ | | | (__ | | | || | ___) || |_| __/| (_| || | | | | || _|| (_| || | | | | | | |
|
|
||||||
/_/ \_\|_| \___||_| |_||_||____/ \__|\___| \__,_||_| |_| |_||_| \__,_||_| |_| |_| |_|
|
|
||||||
|
|
||||||
Copyright 2015-2016 Łukasz "JustArchi" Domeradzki
|
|
||||||
Contact: JustArchi@JustArchi.net
|
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
See the License for the specific language governing permissions and
|
|
||||||
limitations under the License.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
using Newtonsoft.Json;
|
|
||||||
using SteamKit2;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
|
|
||||||
namespace ArchiSteamFarm {
|
|
||||||
internal sealed class SteamTradeOffer {
|
|
||||||
// REF: https://developer.valvesoftware.com/wiki/Steam_Web_API/IEconService#CEcon_TradeOffer
|
|
||||||
internal enum ETradeOfferState : byte {
|
|
||||||
Unknown,
|
|
||||||
Invalid,
|
|
||||||
Active,
|
|
||||||
Accepted,
|
|
||||||
Countered,
|
|
||||||
Expired,
|
|
||||||
Canceled,
|
|
||||||
Declined,
|
|
||||||
InvalidItems,
|
|
||||||
EmailPending,
|
|
||||||
EmailCanceled,
|
|
||||||
OnHold
|
|
||||||
}
|
|
||||||
|
|
||||||
[JsonProperty(Required = Required.Always)]
|
|
||||||
internal string tradeofferid { get; set; }
|
|
||||||
|
|
||||||
[JsonProperty(Required = Required.Always)]
|
|
||||||
internal int accountid_other { get; set; }
|
|
||||||
|
|
||||||
[JsonProperty(Required = Required.Always)]
|
|
||||||
internal ETradeOfferState trade_offer_state { get; set; }
|
|
||||||
|
|
||||||
[JsonProperty(Required = Required.Always)]
|
|
||||||
internal List<SteamItem> items_to_give { get; } = new List<SteamItem>();
|
|
||||||
|
|
||||||
[JsonProperty(Required = Required.Always)]
|
|
||||||
internal List<SteamItem> items_to_receive { get; } = new List<SteamItem>();
|
|
||||||
|
|
||||||
// Extra
|
|
||||||
private ulong _OtherSteamID64 = 0;
|
|
||||||
internal ulong OtherSteamID64 {
|
|
||||||
get {
|
|
||||||
if (_OtherSteamID64 == 0 && accountid_other != 0) {
|
|
||||||
_OtherSteamID64 = new SteamID((uint) accountid_other, EUniverse.Public, EAccountType.Individual).ConvertToUInt64();
|
|
||||||
}
|
|
||||||
|
|
||||||
return _OtherSteamID64;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -22,6 +22,8 @@
|
|||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
using SteamAuth;
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
@@ -34,52 +36,61 @@ namespace ArchiSteamFarm {
|
|||||||
private static readonly SemaphoreSlim InventorySemaphore = new SemaphoreSlim(1);
|
private static readonly SemaphoreSlim InventorySemaphore = new SemaphoreSlim(1);
|
||||||
|
|
||||||
private readonly Bot Bot;
|
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;
|
||||||
|
|
||||||
internal static async Task LimitInventoryRequestsAsync() {
|
internal static async Task LimitInventoryRequestsAsync() {
|
||||||
await InventorySemaphore.WaitAsync().ConfigureAwait(false);
|
await InventorySemaphore.WaitAsync().ConfigureAwait(false);
|
||||||
Task.Run(async () => {
|
Task.Run(async () => {
|
||||||
await Utilities.SleepAsync(Program.GlobalConfig.RequestLimiterDelay * 1000).ConfigureAwait(false);
|
await Utilities.SleepAsync(Program.GlobalConfig.InventoryLimiterDelay * 1000).ConfigureAwait(false);
|
||||||
InventorySemaphore.Release();
|
InventorySemaphore.Release();
|
||||||
}).Forget();
|
}).Forget();
|
||||||
}
|
}
|
||||||
|
|
||||||
internal Trading(Bot bot) {
|
internal Trading(Bot bot) {
|
||||||
|
if (bot == null) {
|
||||||
|
throw new ArgumentNullException("bot");
|
||||||
|
}
|
||||||
|
|
||||||
Bot = bot;
|
Bot = bot;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal async void CheckTrades() {
|
internal async Task CheckTrades() {
|
||||||
if (ParsingTasks < 2) {
|
bool shouldRun = false;
|
||||||
ParsingTasks++;
|
lock (TradesSemaphore) {
|
||||||
|
if (ParsingTasks < 2) {
|
||||||
|
ParsingTasks++;
|
||||||
|
shouldRun = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
await Semaphore.WaitAsync().ConfigureAwait(false);
|
if (!shouldRun) {
|
||||||
await ParseActiveTrades().ConfigureAwait(false);
|
return;
|
||||||
Semaphore.Release();
|
}
|
||||||
|
|
||||||
|
await TradesSemaphore.WaitAsync().ConfigureAwait(false);
|
||||||
|
|
||||||
|
await ParseActiveTrades().ConfigureAwait(false);
|
||||||
|
lock (TradesSemaphore) {
|
||||||
ParsingTasks--;
|
ParsingTasks--;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TradesSemaphore.Release();
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task ParseActiveTrades() {
|
private async Task ParseActiveTrades() {
|
||||||
List<SteamTradeOffer> tradeOffers = Bot.ArchiWebHandler.GetTradeOffers();
|
List<Steam.TradeOffer> tradeOffers = Bot.ArchiWebHandler.GetTradeOffers();
|
||||||
if (tradeOffers == null) {
|
if (tradeOffers == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
List<Task> tasks = new List<Task>();
|
await tradeOffers.ForEachAsync(ParseTrade).ConfigureAwait(false);
|
||||||
foreach (SteamTradeOffer tradeOffer in tradeOffers) {
|
await Bot.AcceptConfirmations(true, Confirmation.ConfirmationType.Trade).ConfigureAwait(false);
|
||||||
if (tradeOffer.trade_offer_state == SteamTradeOffer.ETradeOfferState.Active) {
|
|
||||||
tasks.Add(Task.Run(async () => await ParseTrade(tradeOffer).ConfigureAwait(false)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
await Task.WhenAll(tasks).ConfigureAwait(false);
|
|
||||||
await Bot.AcceptAllConfirmations().ConfigureAwait(false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task ParseTrade(SteamTradeOffer tradeOffer) {
|
private async Task ParseTrade(Steam.TradeOffer tradeOffer) {
|
||||||
if (tradeOffer == null) {
|
if (tradeOffer == null || tradeOffer.trade_offer_state != Steam.TradeOffer.ETradeOfferState.Active) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -88,12 +99,34 @@ namespace ArchiSteamFarm {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tradeOffer.items_to_give.Count == 0 || tradeOffer.OtherSteamID64 == Bot.BotConfig.SteamMasterID) {
|
if (ShouldAcceptTrade(tradeOffer)) {
|
||||||
Logging.LogGenericInfo("Accepting trade: " + tradeID, Bot.BotName);
|
Logging.LogGenericInfo("Accepting trade: " + tradeID, Bot.BotName);
|
||||||
await Bot.ArchiWebHandler.AcceptTradeOffer(tradeID).ConfigureAwait(false);
|
await Bot.ArchiWebHandler.AcceptTradeOffer(tradeID).ConfigureAwait(false);
|
||||||
} else {
|
} else {
|
||||||
Logging.LogGenericInfo("Ignoring trade: " + tradeID, Bot.BotName);
|
Logging.LogGenericInfo("Ignoring trade: " + tradeID, Bot.BotName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private bool ShouldAcceptTrade(Steam.TradeOffer tradeOffer) {
|
||||||
|
if (tradeOffer == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Always accept trades when we're not losing anything
|
||||||
|
if (tradeOffer.items_to_give.Count == 0) {
|
||||||
|
// Unless it's steam fuckup and we're dealing with broken trade
|
||||||
|
return tradeOffer.items_to_receive.Count > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Always accept trades from SteamMasterID
|
||||||
|
if (tradeOffer.OtherSteamID64 != 0 && tradeOffer.OtherSteamID64 == Bot.BotConfig.SteamMasterID) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Add optional SteamTradeMatcher integration here
|
||||||
|
|
||||||
|
// If no rule above matched this trade, reject it
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,41 +22,47 @@
|
|||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
using System.Text.RegularExpressions;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Net;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace ArchiSteamFarm {
|
namespace ArchiSteamFarm {
|
||||||
internal static class Utilities {
|
internal static class Utilities {
|
||||||
internal static void Forget(this Task task) { }
|
internal static void Forget(this Task task) { }
|
||||||
|
|
||||||
internal static async Task SleepAsync(int miliseconds) {
|
internal static Task ForEachAsync<T>(this IEnumerable<T> sequence, Func<T, Task> action) {
|
||||||
await Task.Delay(miliseconds).ConfigureAwait(false);
|
return Task.WhenAll(sequence.Select(action));
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static ulong OnlyNumbers(string inputString) {
|
internal static string GetCookieValue(this CookieContainer cookieContainer, string URL, string name) {
|
||||||
if (string.IsNullOrEmpty(inputString)) {
|
if (string.IsNullOrEmpty(URL) || string.IsNullOrEmpty(name)) {
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
string resultString = OnlyNumbersString(inputString);
|
|
||||||
if (string.IsNullOrEmpty(resultString)) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
ulong result;
|
|
||||||
if (!ulong.TryParse(resultString, out result)) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
internal static string OnlyNumbersString(string text) {
|
|
||||||
if (string.IsNullOrEmpty(text)) {
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return Regex.Replace(text, @"[^\d]", "");
|
CookieCollection cookies = cookieContainer.GetCookies(new Uri(URL));
|
||||||
|
if (cookies == null || cookies.Count == 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (Cookie cookie in cookies) {
|
||||||
|
if (!cookie.Name.Equals(name, StringComparison.Ordinal)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
return cookie.Value;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static Task SleepAsync(int miliseconds) {
|
||||||
|
if (miliseconds < 0) {
|
||||||
|
return Task.FromResult(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Task.Delay(miliseconds);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static uint GetCharCountInString(string s, char c) {
|
internal static uint GetCharCountInString(string s, char c) {
|
||||||
|
|||||||
@@ -23,6 +23,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using System.Linq;
|
||||||
using System.ServiceModel;
|
using System.ServiceModel;
|
||||||
using System.ServiceModel.Channels;
|
using System.ServiceModel.Channels;
|
||||||
|
|
||||||
@@ -41,6 +42,13 @@ namespace ArchiSteamFarm {
|
|||||||
private Client Client;
|
private Client Client;
|
||||||
|
|
||||||
internal static void Init() {
|
internal static void Init() {
|
||||||
|
if (string.IsNullOrEmpty(Program.GlobalConfig.WCFHostname)) {
|
||||||
|
Program.GlobalConfig.WCFHostname = Program.GetUserInput(Program.EUserInputType.WCFHostname);
|
||||||
|
if (string.IsNullOrEmpty(Program.GlobalConfig.WCFHostname)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
URL = "http://" + Program.GlobalConfig.WCFHostname + ":" + Program.GlobalConfig.WCFPort + "/ASF";
|
URL = "http://" + Program.GlobalConfig.WCFHostname + ":" + Program.GlobalConfig.WCFPort + "/ASF";
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -100,7 +108,7 @@ namespace ArchiSteamFarm {
|
|||||||
if (args.Length > 1) { // If we have args[1] provided, use given botName
|
if (args.Length > 1) { // If we have args[1] provided, use given botName
|
||||||
botName = args[1];
|
botName = args[1];
|
||||||
} else { // If not, just pick first one
|
} else { // If not, just pick first one
|
||||||
botName = Bot.GetAnyBotName();
|
botName = Bot.Bots.Keys.FirstOrDefault();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(botName)) {
|
if (string.IsNullOrEmpty(botName)) {
|
||||||
@@ -112,12 +120,12 @@ namespace ArchiSteamFarm {
|
|||||||
return "ERROR: Couldn't find any bot named: " + botName;
|
return "ERROR: Couldn't find any bot named: " + botName;
|
||||||
}
|
}
|
||||||
|
|
||||||
Logging.LogGenericInfo("Received command: \"" + input + "\"");
|
Logging.LogGenericInfo("Received command: " + input);
|
||||||
|
|
||||||
string command = '!' + input;
|
string command = '!' + input;
|
||||||
string output = bot.HandleMessage(command).Result; // TODO: This should be asynchronous
|
string output = bot.Response(Program.GlobalConfig.SteamOwnerID, command).Result; // TODO: This should be asynchronous
|
||||||
|
|
||||||
Logging.LogGenericInfo("Answered to command: \"" + input + "\" with: \"" + output + "\"");
|
Logging.LogGenericInfo("Answered to command: " + input + " with: " + output);
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,35 +23,31 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
using HtmlAgilityPack;
|
using HtmlAgilityPack;
|
||||||
|
using Newtonsoft.Json;
|
||||||
using Newtonsoft.Json.Linq;
|
using Newtonsoft.Json.Linq;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Net.Http;
|
using System.Net.Http;
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using System.Xml;
|
||||||
|
|
||||||
namespace ArchiSteamFarm {
|
namespace ArchiSteamFarm {
|
||||||
internal static class WebBrowser {
|
internal sealed class WebBrowser {
|
||||||
internal const byte MaxConnections = 10; // Defines maximum number of connections per ServicePoint. Be careful, as it also defines maximum number of sockets in CLOSE_WAIT state
|
|
||||||
internal const byte MaxIdleTime = 15; // In seconds, how long socket is allowed to stay in CLOSE_WAIT state after there are no connections to it
|
|
||||||
internal const byte MaxRetries = 5; // Defines maximum number of retries, UrlRequest() does not handle retry by itself (it's app responsibility)
|
internal const byte MaxRetries = 5; // Defines maximum number of retries, UrlRequest() does not handle retry by itself (it's app responsibility)
|
||||||
|
|
||||||
|
private const byte MaxConnections = 10; // Defines maximum number of connections per ServicePoint. Be careful, as it also defines maximum number of sockets in CLOSE_WAIT state
|
||||||
|
private const byte MaxIdleTime = 15; // In seconds, how long socket is allowed to stay in CLOSE_WAIT state after there are no connections to it
|
||||||
|
|
||||||
private static readonly string DefaultUserAgent = "ArchiSteamFarm/" + Program.Version;
|
private static readonly string DefaultUserAgent = "ArchiSteamFarm/" + Program.Version;
|
||||||
private static readonly HttpClient HttpClient = new HttpClient(new HttpClientHandler {
|
|
||||||
UseCookies = false
|
internal readonly CookieContainer CookieContainer = new CookieContainer();
|
||||||
}) {
|
|
||||||
Timeout = TimeSpan.FromSeconds(30)
|
private readonly HttpClient HttpClient;
|
||||||
};
|
private readonly string Identifier;
|
||||||
|
|
||||||
internal static void Init() {
|
internal static void Init() {
|
||||||
HttpClient.Timeout = TimeSpan.FromSeconds(Program.GlobalConfig.HttpTimeout);
|
|
||||||
|
|
||||||
// Most web services expect that UserAgent is set, so we declare it globally
|
|
||||||
// Any request can override that on as-needed basis (see: RequestOptions.FakeUserAgent)
|
|
||||||
HttpClient.DefaultRequestHeaders.UserAgent.ParseAdd(DefaultUserAgent);
|
|
||||||
|
|
||||||
// Set max connection limit from default of 2 to desired value
|
// Set max connection limit from default of 2 to desired value
|
||||||
ServicePointManager.DefaultConnectionLimit = MaxConnections;
|
ServicePointManager.DefaultConnectionLimit = MaxConnections;
|
||||||
|
|
||||||
@@ -61,67 +57,86 @@ namespace ArchiSteamFarm {
|
|||||||
// Don't use Expect100Continue, we're sure about our POSTs, save some TCP packets
|
// Don't use Expect100Continue, we're sure about our POSTs, save some TCP packets
|
||||||
ServicePointManager.Expect100Continue = false;
|
ServicePointManager.Expect100Continue = false;
|
||||||
|
|
||||||
// Reuse ports if possible
|
#if !__MonoCS__
|
||||||
// TODO: Mono doesn't support that feature yet
|
// Reuse ports if possible (since .NET 4.6+)
|
||||||
//ServicePointManager.ReusePort = true;
|
//ServicePointManager.ReusePort = true;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static async Task<HttpResponseMessage> UrlGet(string request, Dictionary<string, string> cookies = null, string referer = null) {
|
internal WebBrowser(string identifier) {
|
||||||
|
if (string.IsNullOrEmpty(identifier)) {
|
||||||
|
throw new ArgumentNullException("identifier");
|
||||||
|
}
|
||||||
|
|
||||||
|
Identifier = identifier;
|
||||||
|
|
||||||
|
HttpClientHandler httpClientHandler = new HttpClientHandler {
|
||||||
|
AutomaticDecompression = DecompressionMethods.Deflate | DecompressionMethods.GZip,
|
||||||
|
CookieContainer = CookieContainer
|
||||||
|
};
|
||||||
|
|
||||||
|
HttpClient = new HttpClient(httpClientHandler) {
|
||||||
|
Timeout = TimeSpan.FromSeconds(Program.GlobalConfig.HttpTimeout)
|
||||||
|
};
|
||||||
|
|
||||||
|
// Most web services expect that UserAgent is set, so we declare it globally
|
||||||
|
HttpClient.DefaultRequestHeaders.UserAgent.ParseAdd(DefaultUserAgent);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal async Task<bool> UrlGet(string request, string referer = null) {
|
||||||
|
if (string.IsNullOrEmpty(request)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
using (HttpResponseMessage response = await UrlGetToResponse(request, referer).ConfigureAwait(false)) {
|
||||||
|
return response != null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal async Task<bool> UrlPost(string request, Dictionary<string, string> data = null, string referer = null) {
|
||||||
|
if (string.IsNullOrEmpty(request)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
using (HttpResponseMessage response = await UrlPostToResponse(request, data, referer).ConfigureAwait(false)) {
|
||||||
|
return response != null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal async Task<string> UrlGetToContent(string request, string referer = null) {
|
||||||
if (string.IsNullOrEmpty(request)) {
|
if (string.IsNullOrEmpty(request)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return await UrlRequest(request, HttpMethod.Get, null, cookies, referer).ConfigureAwait(false);
|
using (HttpResponseMessage httpResponse = await UrlGetToResponse(request, referer).ConfigureAwait(false)) {
|
||||||
|
if (httpResponse == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return await httpResponse.Content.ReadAsStringAsync().ConfigureAwait(false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static async Task<HttpResponseMessage> UrlPost(string request, Dictionary<string, string> data = null, Dictionary<string, string> cookies = null, string referer = null) {
|
internal async Task<byte[]> UrlGetToBytes(string request, string referer = null) {
|
||||||
if (string.IsNullOrEmpty(request)) {
|
if (string.IsNullOrEmpty(request)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return await UrlRequest(request, HttpMethod.Post, data, cookies, referer).ConfigureAwait(false);
|
using (HttpResponseMessage httpResponse = await UrlGetToResponse(request, referer).ConfigureAwait(false)) {
|
||||||
|
if (httpResponse == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return await httpResponse.Content.ReadAsByteArrayAsync().ConfigureAwait(false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static async Task<string> UrlGetToContent(string request, Dictionary<string, string> cookies = null, string referer = null) {
|
internal async Task<HtmlDocument> UrlGetToHtmlDocument(string request, string referer = null) {
|
||||||
if (string.IsNullOrEmpty(request)) {
|
if (string.IsNullOrEmpty(request)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
HttpResponseMessage httpResponse = await UrlGet(request, cookies, referer).ConfigureAwait(false);
|
string content = await UrlGetToContent(request, referer).ConfigureAwait(false);
|
||||||
if (httpResponse == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (httpResponse.Content == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return await httpResponse.Content.ReadAsStringAsync().ConfigureAwait(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
internal static async Task<Stream> UrlGetToStream(string request, Dictionary<string, string> cookies = null, string referer = null) {
|
|
||||||
if (string.IsNullOrEmpty(request)) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
HttpResponseMessage httpResponse = await UrlGet(request, cookies, referer).ConfigureAwait(false);
|
|
||||||
if (httpResponse == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (httpResponse.Content == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return await httpResponse.Content.ReadAsStreamAsync().ConfigureAwait(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
internal static async Task<HtmlDocument> UrlGetToHtmlDocument(string request, Dictionary<string, string> cookies = null, string referer = null) {
|
|
||||||
if (string.IsNullOrEmpty(request)) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
string content = await UrlGetToContent(request, cookies, referer).ConfigureAwait(false);
|
|
||||||
if (string.IsNullOrEmpty(content)) {
|
if (string.IsNullOrEmpty(content)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -133,12 +148,12 @@ namespace ArchiSteamFarm {
|
|||||||
return htmlDocument;
|
return htmlDocument;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static async Task<JObject> UrlGetToJObject(string request, Dictionary<string, string> cookies = null, string referer = null) {
|
internal async Task<JObject> UrlGetToJObject(string request, string referer = null) {
|
||||||
if (string.IsNullOrEmpty(request)) {
|
if (string.IsNullOrEmpty(request)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
string content = await UrlGetToContent(request, cookies, referer).ConfigureAwait(false);
|
string content = await UrlGetToContent(request, referer).ConfigureAwait(false);
|
||||||
if (string.IsNullOrEmpty(content)) {
|
if (string.IsNullOrEmpty(content)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -147,38 +162,72 @@ namespace ArchiSteamFarm {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
jObject = JObject.Parse(content);
|
jObject = JObject.Parse(content);
|
||||||
} catch (Exception e) {
|
} catch (JsonException e) {
|
||||||
Logging.LogGenericException(e);
|
Logging.LogGenericException(e, Identifier);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return jObject;
|
return jObject;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static async Task<HttpResponseMessage> UrlRequest(string request, HttpMethod httpMethod, Dictionary<string, string> data = null, Dictionary<string, string> cookies = null, string referer = null) {
|
internal async Task<XmlDocument> UrlGetToXML(string request, string referer = null) {
|
||||||
|
if (string.IsNullOrEmpty(request)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
string content = await UrlGetToContent(request, referer).ConfigureAwait(false);
|
||||||
|
if (string.IsNullOrEmpty(content)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
XmlDocument xmlDocument = new XmlDocument();
|
||||||
|
|
||||||
|
try {
|
||||||
|
xmlDocument.LoadXml(content);
|
||||||
|
} catch (XmlException e) {
|
||||||
|
Logging.LogGenericException(e, Identifier);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return xmlDocument;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task<HttpResponseMessage> UrlGetToResponse(string request, string referer = null) {
|
||||||
|
if (string.IsNullOrEmpty(request)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return await UrlRequest(request, HttpMethod.Get, null, referer).ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task<HttpResponseMessage> UrlPostToResponse(string request, Dictionary<string, string> data = null, string referer = null) {
|
||||||
|
if (string.IsNullOrEmpty(request)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return await UrlRequest(request, HttpMethod.Post, data, referer).ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task<HttpResponseMessage> UrlRequest(string request, HttpMethod httpMethod, Dictionary<string, string> data = null, string referer = null) {
|
||||||
if (string.IsNullOrEmpty(request) || httpMethod == null) {
|
if (string.IsNullOrEmpty(request) || httpMethod == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (request.StartsWith("https://") && Program.GlobalConfig.ForceHttp) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
HttpResponseMessage responseMessage;
|
HttpResponseMessage responseMessage;
|
||||||
using (HttpRequestMessage requestMessage = new HttpRequestMessage(httpMethod, request)) {
|
using (HttpRequestMessage requestMessage = new HttpRequestMessage(httpMethod, request)) {
|
||||||
if (data != null && data.Count > 0) {
|
if (data != null && data.Count > 0) {
|
||||||
try {
|
try {
|
||||||
requestMessage.Content = new FormUrlEncodedContent(data);
|
requestMessage.Content = new FormUrlEncodedContent(data);
|
||||||
} catch (UriFormatException e) {
|
} catch (UriFormatException e) {
|
||||||
Logging.LogGenericException(e);
|
Logging.LogGenericException(e, Identifier);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cookies != null && cookies.Count > 0) {
|
|
||||||
StringBuilder cookieHeader = new StringBuilder();
|
|
||||||
foreach (KeyValuePair<string, string> cookie in cookies) {
|
|
||||||
cookieHeader.Append(cookie.Key + "=" + cookie.Value + ";");
|
|
||||||
}
|
|
||||||
requestMessage.Headers.Add("Cookie", cookieHeader.ToString());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(referer)) {
|
if (!string.IsNullOrEmpty(referer)) {
|
||||||
requestMessage.Headers.Referrer = new Uri(referer);
|
requestMessage.Headers.Referrer = new Uri(referer);
|
||||||
}
|
}
|
||||||
@@ -191,6 +240,14 @@ namespace ArchiSteamFarm {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (responseMessage == null || !responseMessage.IsSuccessStatusCode) {
|
if (responseMessage == null || !responseMessage.IsSuccessStatusCode) {
|
||||||
|
if (Debugging.IsDebugBuild || Program.GlobalConfig.Debug) {
|
||||||
|
Logging.LogGenericError("Request: " + request + " failed!", Identifier);
|
||||||
|
if (responseMessage != null) {
|
||||||
|
Logging.LogGenericError("Status code: " + responseMessage.StatusCode, Identifier);
|
||||||
|
Logging.LogGenericError("Content: " + Environment.NewLine + await responseMessage.Content.ReadAsStringAsync().ConfigureAwait(false), Identifier);
|
||||||
|
responseMessage.Dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,12 +1,24 @@
|
|||||||
{
|
{
|
||||||
"Debug": false,
|
"Debug": false,
|
||||||
|
"Headless": false,
|
||||||
"AutoUpdates": true,
|
"AutoUpdates": true,
|
||||||
|
"AutoRestart": true,
|
||||||
"UpdateChannel": 1,
|
"UpdateChannel": 1,
|
||||||
"HttpTimeout": 30,
|
"SteamProtocol": 6,
|
||||||
|
"SteamOwnerID": 0,
|
||||||
|
"MaxFarmingTime": 10,
|
||||||
|
"IdleFarmingPeriod": 3,
|
||||||
|
"FarmingDelay": 5,
|
||||||
"AccountPlayingDelay": 5,
|
"AccountPlayingDelay": 5,
|
||||||
"RequestLimiterDelay": 7,
|
"LoginLimiterDelay": 7,
|
||||||
|
"InventoryLimiterDelay": 3,
|
||||||
|
"ForceHttp": false,
|
||||||
|
"HttpTimeout": 60,
|
||||||
"WCFHostname": "localhost",
|
"WCFHostname": "localhost",
|
||||||
"WCFPort": 1242,
|
"WCFPort": 1242,
|
||||||
|
"LogToFile": true,
|
||||||
|
"Statistics": true,
|
||||||
|
"HackIgnoreMachineID": false,
|
||||||
"Blacklist": [
|
"Blacklist": [
|
||||||
267420,
|
267420,
|
||||||
303700,
|
303700,
|
||||||
|
|||||||
@@ -11,6 +11,7 @@
|
|||||||
"DismissInventoryNotifications": true,
|
"DismissInventoryNotifications": true,
|
||||||
"FarmOffline": false,
|
"FarmOffline": false,
|
||||||
"HandleOfflineMessages": false,
|
"HandleOfflineMessages": false,
|
||||||
|
"AcceptGifts": false,
|
||||||
"ForwardKeysToOtherBots": false,
|
"ForwardKeysToOtherBots": false,
|
||||||
"DistributeKeys": false,
|
"DistributeKeys": false,
|
||||||
"UseAsfAsMobileAuthenticator": false,
|
"UseAsfAsMobileAuthenticator": false,
|
||||||
@@ -18,9 +19,9 @@
|
|||||||
"SendOnFarmingFinished": false,
|
"SendOnFarmingFinished": false,
|
||||||
"SteamTradeToken": null,
|
"SteamTradeToken": null,
|
||||||
"SendTradePeriod": 0,
|
"SendTradePeriod": 0,
|
||||||
|
"AcceptConfirmationsPeriod": 0,
|
||||||
"CustomGamePlayedWhileIdle": null,
|
"CustomGamePlayedWhileIdle": null,
|
||||||
"GamesPlayedWhileIdle": [
|
"GamesPlayedWhileIdle": [
|
||||||
0
|
0
|
||||||
],
|
]
|
||||||
"Statistics": true
|
|
||||||
}
|
}
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<packages>
|
<packages>
|
||||||
<package id="HtmlAgilityPack" version="1.4.9" targetFramework="net45" />
|
<package id="HtmlAgilityPack" version="1.4.9" targetFramework="net45" />
|
||||||
<package id="Newtonsoft.Json" version="8.0.2" targetFramework="net452" />
|
<package id="Newtonsoft.Json" version="8.0.3" targetFramework="net451" />
|
||||||
<package id="protobuf-net" version="2.0.0.668" targetFramework="net45" />
|
<package id="protobuf-net" version="2.0.0.668" targetFramework="net45" />
|
||||||
<package id="SteamKit2" version="1.7.0" targetFramework="net452" />
|
<package id="SteamKit2" version="1.7.0" targetFramework="net452" />
|
||||||
</packages>
|
</packages>
|
||||||
90
ConfigGenerator/ASFConfig.cs
Normal file
90
ConfigGenerator/ASFConfig.cs
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
/*
|
||||||
|
_ _ _ ____ _ _____
|
||||||
|
/ \ _ __ ___ | |__ (_)/ ___| | |_ ___ __ _ _ __ ___ | ___|__ _ _ __ _ __ ___
|
||||||
|
/ _ \ | '__|/ __|| '_ \ | |\___ \ | __|/ _ \ / _` || '_ ` _ \ | |_ / _` || '__|| '_ ` _ \
|
||||||
|
/ ___ \ | | | (__ | | | || | ___) || |_| __/| (_| || | | | | || _|| (_| || | | | | | | |
|
||||||
|
/_/ \_\|_| \___||_| |_||_||____/ \__|\___| \__,_||_| |_| |_||_| \__,_||_| |_| |_| |_|
|
||||||
|
|
||||||
|
Copyright 2015-2016 Łukasz "JustArchi" Domeradzki
|
||||||
|
Contact: JustArchi@JustArchi.net
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
|
||||||
|
namespace ConfigGenerator {
|
||||||
|
internal class ASFConfig {
|
||||||
|
internal static readonly HashSet<ASFConfig> ASFConfigs = new HashSet<ASFConfig>();
|
||||||
|
|
||||||
|
internal string FilePath { get; set; }
|
||||||
|
|
||||||
|
protected ASFConfig() {
|
||||||
|
ASFConfigs.Add(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected ASFConfig(string filePath) : this() {
|
||||||
|
if (string.IsNullOrEmpty(filePath)) {
|
||||||
|
throw new ArgumentNullException("filePath");
|
||||||
|
}
|
||||||
|
|
||||||
|
FilePath = filePath;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal virtual void Save() {
|
||||||
|
lock (FilePath) {
|
||||||
|
try {
|
||||||
|
File.WriteAllText(FilePath, JsonConvert.SerializeObject(this, Formatting.Indented));
|
||||||
|
} catch (Exception e) {
|
||||||
|
Logging.LogGenericException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal virtual void Remove() {
|
||||||
|
string queryPath = Path.GetFileNameWithoutExtension(FilePath);
|
||||||
|
lock (FilePath) {
|
||||||
|
foreach (string botFile in Directory.EnumerateFiles(Program.ConfigDirectory, queryPath + ".*")) {
|
||||||
|
try {
|
||||||
|
File.Delete(botFile);
|
||||||
|
} catch (Exception e) {
|
||||||
|
Logging.LogGenericException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ASFConfigs.Remove(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal virtual void Rename(string botName) {
|
||||||
|
if (string.IsNullOrEmpty(botName)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
string queryPath = Path.GetFileNameWithoutExtension(FilePath);
|
||||||
|
lock (FilePath) {
|
||||||
|
foreach (string botFile in Directory.EnumerateFiles(Program.ConfigDirectory, queryPath + ".*")) {
|
||||||
|
try {
|
||||||
|
File.Move(botFile, Path.Combine(Program.ConfigDirectory, botName + Path.GetExtension(botFile)));
|
||||||
|
} catch (Exception e) {
|
||||||
|
Logging.LogGenericException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FilePath = Path.Combine(Program.ConfigDirectory, botName + ".json");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
6
ConfigGenerator/App.config
Normal file
6
ConfigGenerator/App.config
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8" ?>
|
||||||
|
<configuration>
|
||||||
|
<startup>
|
||||||
|
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.1" />
|
||||||
|
</startup>
|
||||||
|
</configuration>
|
||||||
139
ConfigGenerator/BotConfig.cs
Normal file
139
ConfigGenerator/BotConfig.cs
Normal file
@@ -0,0 +1,139 @@
|
|||||||
|
/*
|
||||||
|
_ _ _ ____ _ _____
|
||||||
|
/ \ _ __ ___ | |__ (_)/ ___| | |_ ___ __ _ _ __ ___ | ___|__ _ _ __ _ __ ___
|
||||||
|
/ _ \ | '__|/ __|| '_ \ | |\___ \ | __|/ _ \ / _` || '_ ` _ \ | |_ / _` || '__|| '_ ` _ \
|
||||||
|
/ ___ \ | | | (__ | | | || | ___) || |_| __/| (_| || | | | | || _|| (_| || | | | | | | |
|
||||||
|
/_/ \_\|_| \___||_| |_||_||____/ \__|\___| \__,_||_| |_| |_||_| \__,_||_| |_| |_| |_|
|
||||||
|
|
||||||
|
Copyright 2015-2016 Łukasz "JustArchi" Domeradzki
|
||||||
|
Contact: JustArchi@JustArchi.net
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
|
||||||
|
namespace ConfigGenerator {
|
||||||
|
internal sealed class BotConfig : ASFConfig {
|
||||||
|
[JsonProperty(Required = Required.DisallowNull)]
|
||||||
|
public bool Enabled { get; set; } = false;
|
||||||
|
|
||||||
|
[JsonProperty(Required = Required.DisallowNull)]
|
||||||
|
public bool StartOnLaunch { get; set; } = true;
|
||||||
|
|
||||||
|
[JsonProperty]
|
||||||
|
public string SteamLogin { get; set; } = null;
|
||||||
|
|
||||||
|
[JsonProperty]
|
||||||
|
public string SteamPassword { get; set; } = null;
|
||||||
|
|
||||||
|
[JsonProperty]
|
||||||
|
public string SteamParentalPIN { get; set; } = "0";
|
||||||
|
|
||||||
|
[JsonProperty]
|
||||||
|
public string SteamApiKey { get; set; } = null;
|
||||||
|
|
||||||
|
[JsonProperty(Required = Required.DisallowNull)]
|
||||||
|
public ulong SteamMasterID { get; set; } = 0;
|
||||||
|
|
||||||
|
[JsonProperty(Required = Required.DisallowNull)]
|
||||||
|
public ulong SteamMasterClanID { get; set; } = 0;
|
||||||
|
|
||||||
|
[JsonProperty(Required = Required.DisallowNull)]
|
||||||
|
public bool CardDropsRestricted { get; set; } = false;
|
||||||
|
|
||||||
|
[JsonProperty(Required = Required.DisallowNull)]
|
||||||
|
public bool DismissInventoryNotifications { get; set; } = true;
|
||||||
|
|
||||||
|
[JsonProperty(Required = Required.DisallowNull)]
|
||||||
|
public bool FarmOffline { get; set; } = false;
|
||||||
|
|
||||||
|
[JsonProperty(Required = Required.DisallowNull)]
|
||||||
|
public bool HandleOfflineMessages { get; set; } = false;
|
||||||
|
|
||||||
|
[JsonProperty(Required = Required.DisallowNull)]
|
||||||
|
public bool AcceptGifts { get; set; } = false;
|
||||||
|
|
||||||
|
[JsonProperty(Required = Required.DisallowNull)]
|
||||||
|
public bool ForwardKeysToOtherBots { get; set; } = false;
|
||||||
|
|
||||||
|
[JsonProperty(Required = Required.DisallowNull)]
|
||||||
|
public bool DistributeKeys { get; set; } = false;
|
||||||
|
|
||||||
|
[JsonProperty(Required = Required.DisallowNull)]
|
||||||
|
public bool UseAsfAsMobileAuthenticator { get; set; } = false;
|
||||||
|
|
||||||
|
[JsonProperty(Required = Required.DisallowNull)]
|
||||||
|
public bool ShutdownOnFarmingFinished { get; set; } = false;
|
||||||
|
|
||||||
|
[JsonProperty(Required = Required.DisallowNull)]
|
||||||
|
public bool SendOnFarmingFinished { get; set; } = false;
|
||||||
|
|
||||||
|
[JsonProperty]
|
||||||
|
public string SteamTradeToken { get; set; } = null;
|
||||||
|
|
||||||
|
[JsonProperty(Required = Required.DisallowNull)]
|
||||||
|
public byte SendTradePeriod { get; set; } = 0;
|
||||||
|
|
||||||
|
[JsonProperty(Required = Required.DisallowNull)]
|
||||||
|
public byte AcceptConfirmationsPeriod { get; set; } = 0;
|
||||||
|
|
||||||
|
[JsonProperty]
|
||||||
|
public string CustomGamePlayedWhileIdle { get; set; } = null;
|
||||||
|
|
||||||
|
[JsonProperty(Required = Required.DisallowNull)]
|
||||||
|
public List<uint> GamesPlayedWhileIdle { get; set; } = new List<uint>();
|
||||||
|
|
||||||
|
internal static BotConfig Load(string filePath) {
|
||||||
|
if (string.IsNullOrEmpty(filePath)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!File.Exists(filePath)) {
|
||||||
|
return new BotConfig(filePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
BotConfig botConfig;
|
||||||
|
try {
|
||||||
|
botConfig = JsonConvert.DeserializeObject<BotConfig>(File.ReadAllText(filePath));
|
||||||
|
} catch (Exception e) {
|
||||||
|
Logging.LogGenericException(e);
|
||||||
|
return new BotConfig(filePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (botConfig == null) {
|
||||||
|
return new BotConfig(filePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
botConfig.FilePath = filePath;
|
||||||
|
|
||||||
|
return botConfig;
|
||||||
|
}
|
||||||
|
|
||||||
|
// This constructor is used only by deserializer
|
||||||
|
private BotConfig() { }
|
||||||
|
|
||||||
|
private BotConfig(string filePath) : base(filePath) {
|
||||||
|
if (string.IsNullOrEmpty(filePath)) {
|
||||||
|
throw new ArgumentNullException("filePath");
|
||||||
|
}
|
||||||
|
|
||||||
|
GamesPlayedWhileIdle.Add(0);
|
||||||
|
Save();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
122
ConfigGenerator/ConfigGenerator.csproj
Normal file
122
ConfigGenerator/ConfigGenerator.csproj
Normal file
@@ -0,0 +1,122 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||||
|
<PropertyGroup>
|
||||||
|
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||||
|
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||||
|
<ProjectGuid>{C3F6FE68-5E75-415E-BEA1-1E7C16D6A433}</ProjectGuid>
|
||||||
|
<OutputType>WinExe</OutputType>
|
||||||
|
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||||
|
<RootNamespace>ConfigGenerator</RootNamespace>
|
||||||
|
<AssemblyName>ConfigGenerator</AssemblyName>
|
||||||
|
<TargetFrameworkVersion>v4.5.1</TargetFrameworkVersion>
|
||||||
|
<FileAlignment>512</FileAlignment>
|
||||||
|
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||||
|
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||||
|
<DebugSymbols>true</DebugSymbols>
|
||||||
|
<DebugType>full</DebugType>
|
||||||
|
<Optimize>false</Optimize>
|
||||||
|
<OutputPath>bin\Debug\</OutputPath>
|
||||||
|
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
<WarningLevel>4</WarningLevel>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||||
|
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||||
|
<DebugType>none</DebugType>
|
||||||
|
<Optimize>true</Optimize>
|
||||||
|
<OutputPath>bin\Release\</OutputPath>
|
||||||
|
<DefineConstants>
|
||||||
|
</DefineConstants>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
<WarningLevel>4</WarningLevel>
|
||||||
|
<TreatWarningsAsErrors>false</TreatWarningsAsErrors>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup>
|
||||||
|
<ApplicationIcon>cirno.ico</ApplicationIcon>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Reference Include="Newtonsoft.Json, Version=8.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
|
||||||
|
<HintPath>..\packages\Newtonsoft.Json.8.0.3\lib\net45\Newtonsoft.Json.dll</HintPath>
|
||||||
|
<Private>True</Private>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System" />
|
||||||
|
<Reference Include="System.Core" />
|
||||||
|
<Reference Include="System.Drawing" />
|
||||||
|
<Reference Include="System.Windows.Forms" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Compile Include="ASFConfig.cs" />
|
||||||
|
<Compile Include="BotConfig.cs" />
|
||||||
|
<Compile Include="DialogBox.cs" />
|
||||||
|
<Compile Include="EnhancedPropertyGrid.cs">
|
||||||
|
<SubType>Component</SubType>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="Debugging.cs" />
|
||||||
|
<Compile Include="GlobalConfig.cs" />
|
||||||
|
<Compile Include="ConfigPage.cs">
|
||||||
|
<SubType>Component</SubType>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="Logging.cs" />
|
||||||
|
<Compile Include="MainForm.cs">
|
||||||
|
<SubType>Form</SubType>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="MainForm.Designer.cs">
|
||||||
|
<DependentUpon>MainForm.cs</DependentUpon>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="Program.cs" />
|
||||||
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
|
<Compile Include="Tutorial.cs" />
|
||||||
|
<EmbeddedResource Include="ConfigPage.resx">
|
||||||
|
<DependentUpon>ConfigPage.cs</DependentUpon>
|
||||||
|
</EmbeddedResource>
|
||||||
|
<EmbeddedResource Include="MainForm.resx">
|
||||||
|
<DependentUpon>MainForm.cs</DependentUpon>
|
||||||
|
</EmbeddedResource>
|
||||||
|
<EmbeddedResource Include="Properties\Resources.resx">
|
||||||
|
<Generator>ResXFileCodeGenerator</Generator>
|
||||||
|
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
|
||||||
|
<SubType>Designer</SubType>
|
||||||
|
</EmbeddedResource>
|
||||||
|
<Compile Include="Properties\Resources.Designer.cs">
|
||||||
|
<AutoGen>True</AutoGen>
|
||||||
|
<DependentUpon>Resources.resx</DependentUpon>
|
||||||
|
</Compile>
|
||||||
|
<None Include="packages.config" />
|
||||||
|
<None Include="Properties\Settings.settings">
|
||||||
|
<Generator>SettingsSingleFileGenerator</Generator>
|
||||||
|
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
|
||||||
|
</None>
|
||||||
|
<Compile Include="Properties\Settings.Designer.cs">
|
||||||
|
<AutoGen>True</AutoGen>
|
||||||
|
<DependentUpon>Settings.settings</DependentUpon>
|
||||||
|
<DesignTimeSharedInput>True</DesignTimeSharedInput>
|
||||||
|
</Compile>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<None Include="App.config" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Content Include="cirno.ico" />
|
||||||
|
</ItemGroup>
|
||||||
|
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||||
|
<PropertyGroup>
|
||||||
|
<PostBuildEvent Condition=" '$(OS)' != 'Unix' AND '$(ConfigurationName)' == 'Release' ">
|
||||||
|
"$(SolutionDir)tools\ILRepack\ILRepack.exe" /ndebug /internalize /parallel /targetplatform:v4 /wildcards /out:"$(SolutionDir)out\ASF-ConfigGenerator.exe" "$(TargetDir)$(TargetName).exe" "$(TargetDir)*.dll"
|
||||||
|
del "$(SolutionDir)out\ASF-ConfigGenerator.exe.config"
|
||||||
|
</PostBuildEvent>
|
||||||
|
<PostBuildEvent Condition=" '$(OS)' == 'Unix' AND '$(ConfigurationName)' == 'Release' ">
|
||||||
|
mono -O=all "$(SolutionDir)tools/ILRepack/ILRepack.exe" /ndebug /internalize /parallel /targetplatform:v4 /wildcards /out:"$(SolutionDir)out/ASF-ConfigGenerator.exe" "$(TargetDir)$(TargetName).exe" "$(TargetDir)*.dll"
|
||||||
|
rm "$(SolutionDir)out/ASF-ConfigGenerator.exe.config"
|
||||||
|
</PostBuildEvent>
|
||||||
|
</PropertyGroup>
|
||||||
|
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||||
|
Other similar extension points exist, see Microsoft.Common.targets.
|
||||||
|
<Target Name="BeforeBuild">
|
||||||
|
</Target>
|
||||||
|
<Target Name="AfterBuild">
|
||||||
|
</Target>
|
||||||
|
-->
|
||||||
|
</Project>
|
||||||
@@ -22,34 +22,28 @@
|
|||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
using Newtonsoft.Json;
|
using System.IO;
|
||||||
|
using System.Windows.Forms;
|
||||||
|
|
||||||
namespace ArchiSteamFarm {
|
namespace ConfigGenerator {
|
||||||
internal sealed class SteamItem {
|
internal class ConfigPage : TabPage {
|
||||||
// REF: https://developer.valvesoftware.com/wiki/Steam_Web_API/IEconService#CEcon_Asset
|
internal readonly ASFConfig ASFConfig;
|
||||||
|
|
||||||
[JsonProperty(Required = Required.DisallowNull)]
|
internal ConfigPage(ASFConfig config) {
|
||||||
internal string appid { get; set; }
|
if (config == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
[JsonProperty(Required = Required.DisallowNull)]
|
ASFConfig = config;
|
||||||
internal string contextid { get; set; }
|
|
||||||
|
|
||||||
[JsonProperty(Required = Required.DisallowNull)]
|
RefreshText();
|
||||||
internal string assetid { get; set; }
|
|
||||||
|
|
||||||
[JsonProperty(Required = Required.DisallowNull)]
|
EnhancedPropertyGrid enhancedPropertyGrid = new EnhancedPropertyGrid(config);
|
||||||
internal string id {
|
Controls.Add(enhancedPropertyGrid);
|
||||||
get { return assetid; }
|
|
||||||
set { assetid = value; }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[JsonProperty(Required = Required.AllowNull)]
|
internal void RefreshText() {
|
||||||
internal string classid { get; set; }
|
Text = Path.GetFileNameWithoutExtension(ASFConfig.FilePath);
|
||||||
|
}
|
||||||
[JsonProperty(Required = Required.AllowNull)]
|
|
||||||
internal string instanceid { get; set; }
|
|
||||||
|
|
||||||
[JsonProperty(Required = Required.Always)]
|
|
||||||
internal string amount { get; set; }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
123
ConfigGenerator/ConfigPage.resx
Normal file
123
ConfigGenerator/ConfigPage.resx
Normal file
@@ -0,0 +1,123 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<root>
|
||||||
|
<!--
|
||||||
|
Microsoft ResX Schema
|
||||||
|
|
||||||
|
Version 2.0
|
||||||
|
|
||||||
|
The primary goals of this format is to allow a simple XML format
|
||||||
|
that is mostly human readable. The generation and parsing of the
|
||||||
|
various data types are done through the TypeConverter classes
|
||||||
|
associated with the data types.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
... ado.net/XML headers & schema ...
|
||||||
|
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||||
|
<resheader name="version">2.0</resheader>
|
||||||
|
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||||
|
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||||
|
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||||
|
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||||
|
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||||
|
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
|
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||||
|
<comment>This is a comment</comment>
|
||||||
|
</data>
|
||||||
|
|
||||||
|
There are any number of "resheader" rows that contain simple
|
||||||
|
name/value pairs.
|
||||||
|
|
||||||
|
Each data row contains a name, and value. The row also contains a
|
||||||
|
type or mimetype. Type corresponds to a .NET class that support
|
||||||
|
text/value conversion through the TypeConverter architecture.
|
||||||
|
Classes that don't support this are serialized and stored with the
|
||||||
|
mimetype set.
|
||||||
|
|
||||||
|
The mimetype is used for serialized objects, and tells the
|
||||||
|
ResXResourceReader how to depersist the object. This is currently not
|
||||||
|
extensible. For a given mimetype the value must be set accordingly:
|
||||||
|
|
||||||
|
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||||
|
that the ResXResourceWriter will generate, however the reader can
|
||||||
|
read any of the formats listed below.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.binary.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.soap.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||||
|
value : The object must be serialized into a byte array
|
||||||
|
: using a System.ComponentModel.TypeConverter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
-->
|
||||||
|
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||||
|
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||||
|
<xsd:element name="root" msdata:IsDataSet="true">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:choice maxOccurs="unbounded">
|
||||||
|
<xsd:element name="metadata">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="assembly">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:attribute name="alias" type="xsd:string" />
|
||||||
|
<xsd:attribute name="name" type="xsd:string" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="data">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="resheader">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:choice>
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:schema>
|
||||||
|
<resheader name="resmimetype">
|
||||||
|
<value>text/microsoft-resx</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="version">
|
||||||
|
<value>2.0</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="reader">
|
||||||
|
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="writer">
|
||||||
|
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
<metadata name="$this.TrayLargeIcon" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||||
|
<value>False</value>
|
||||||
|
</metadata>
|
||||||
|
</root>
|
||||||
@@ -22,20 +22,14 @@
|
|||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
using Newtonsoft.Json;
|
namespace ConfigGenerator {
|
||||||
|
internal static class Debugging {
|
||||||
|
#if DEBUG
|
||||||
|
internal static readonly bool IsDebugBuild = true;
|
||||||
|
#else
|
||||||
|
internal static readonly bool IsDebugBuild = false;
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace ArchiSteamFarm {
|
internal static bool IsReleaseBuild => !IsDebugBuild;
|
||||||
internal sealed class SteamTradeOfferRequest {
|
|
||||||
[JsonProperty(Required = Required.Always)]
|
|
||||||
internal bool newversion { get; } = true;
|
|
||||||
|
|
||||||
[JsonProperty(Required = Required.Always)]
|
|
||||||
internal int version { get; } = 2;
|
|
||||||
|
|
||||||
[JsonProperty(Required = Required.Always)]
|
|
||||||
internal SteamItemList me { get; } = new SteamItemList();
|
|
||||||
|
|
||||||
[JsonProperty(Required = Required.Always)]
|
|
||||||
internal SteamItemList them { get; } = new SteamItemList();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
119
ConfigGenerator/DialogBox.cs
Normal file
119
ConfigGenerator/DialogBox.cs
Normal file
@@ -0,0 +1,119 @@
|
|||||||
|
/*
|
||||||
|
_ _ _ ____ _ _____
|
||||||
|
/ \ _ __ ___ | |__ (_)/ ___| | |_ ___ __ _ _ __ ___ | ___|__ _ _ __ _ __ ___
|
||||||
|
/ _ \ | '__|/ __|| '_ \ | |\___ \ | __|/ _ \ / _` || '_ ` _ \ | |_ / _` || '__|| '_ ` _ \
|
||||||
|
/ ___ \ | | | (__ | | | || | ___) || |_| __/| (_| || | | | | || _|| (_| || | | | | | | |
|
||||||
|
/_/ \_\|_| \___||_| |_||_||____/ \__|\___| \__,_||_| |_| |_||_| \__,_||_| |_| |_| |_|
|
||||||
|
|
||||||
|
Copyright 2015-2016 Łukasz "JustArchi" Domeradzki
|
||||||
|
Contact: JustArchi@JustArchi.net
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Drawing;
|
||||||
|
using System.Windows.Forms;
|
||||||
|
|
||||||
|
namespace ConfigGenerator {
|
||||||
|
class DialogBox {
|
||||||
|
public static DialogResult InputBox(string title, string promptText, out string value) {
|
||||||
|
if (string.IsNullOrEmpty(title) || string.IsNullOrEmpty(promptText)) {
|
||||||
|
value = null;
|
||||||
|
return DialogResult.Abort;
|
||||||
|
}
|
||||||
|
|
||||||
|
Form form = new Form();
|
||||||
|
Label label = new Label();
|
||||||
|
TextBox textBox = new TextBox();
|
||||||
|
|
||||||
|
textBox.Width = 1000;
|
||||||
|
Button buttonOk = new Button();
|
||||||
|
Button buttonCancel = new Button();
|
||||||
|
|
||||||
|
form.Text = title;
|
||||||
|
label.Text = promptText;
|
||||||
|
|
||||||
|
buttonOk.Text = "OK";
|
||||||
|
buttonCancel.Text = "Cancel";
|
||||||
|
buttonOk.DialogResult = DialogResult.OK;
|
||||||
|
buttonCancel.DialogResult = DialogResult.Cancel;
|
||||||
|
|
||||||
|
label.SetBounds(9, 20, 372, 13);
|
||||||
|
textBox.SetBounds(12, 36, 372, 20);
|
||||||
|
buttonOk.SetBounds(228, 72, 75, 23);
|
||||||
|
buttonCancel.SetBounds(309, 72, 75, 23);
|
||||||
|
|
||||||
|
label.AutoSize = true;
|
||||||
|
textBox.Anchor = textBox.Anchor | AnchorStyles.Right;
|
||||||
|
buttonOk.Anchor = AnchorStyles.Bottom | AnchorStyles.Right;
|
||||||
|
buttonCancel.Anchor = AnchorStyles.Bottom | AnchorStyles.Right;
|
||||||
|
|
||||||
|
form.ClientSize = new Size(396, 107);
|
||||||
|
form.Controls.AddRange(new Control[] { label, textBox, buttonOk, buttonCancel });
|
||||||
|
form.ClientSize = new Size(Math.Max(300, label.Right + 10), form.ClientSize.Height);
|
||||||
|
form.FormBorderStyle = FormBorderStyle.FixedDialog;
|
||||||
|
form.StartPosition = FormStartPosition.CenterScreen;
|
||||||
|
form.MinimizeBox = false;
|
||||||
|
form.MaximizeBox = false;
|
||||||
|
form.AcceptButton = buttonOk;
|
||||||
|
form.CancelButton = buttonCancel;
|
||||||
|
|
||||||
|
DialogResult dialogResult = form.ShowDialog();
|
||||||
|
value = textBox.Text;
|
||||||
|
return dialogResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static DialogResult YesNoBox(string title, string promptText) {
|
||||||
|
if (string.IsNullOrEmpty(title) || string.IsNullOrEmpty(promptText)) {
|
||||||
|
return DialogResult.Abort;
|
||||||
|
}
|
||||||
|
|
||||||
|
Form form = new Form();
|
||||||
|
Label label = new Label();
|
||||||
|
|
||||||
|
Button buttonOk = new Button();
|
||||||
|
Button buttonCancel = new Button();
|
||||||
|
|
||||||
|
form.Text = title;
|
||||||
|
label.Text = promptText;
|
||||||
|
|
||||||
|
buttonOk.Text = "Yes";
|
||||||
|
buttonCancel.Text = "No";
|
||||||
|
buttonOk.DialogResult = DialogResult.Yes;
|
||||||
|
buttonCancel.DialogResult = DialogResult.No;
|
||||||
|
|
||||||
|
label.SetBounds(9, 20, 372, 13);
|
||||||
|
buttonOk.SetBounds(228, 50, 75, 23);
|
||||||
|
buttonCancel.SetBounds(309, 50, 75, 23);
|
||||||
|
|
||||||
|
label.AutoSize = true;
|
||||||
|
buttonOk.Anchor = AnchorStyles.Bottom | AnchorStyles.Right;
|
||||||
|
buttonCancel.Anchor = AnchorStyles.Bottom | AnchorStyles.Right;
|
||||||
|
|
||||||
|
form.ClientSize = new Size(396, 80);
|
||||||
|
form.Controls.AddRange(new Control[] { label, buttonOk, buttonCancel });
|
||||||
|
form.ClientSize = new Size(Math.Max(300, label.Right + 10), form.ClientSize.Height);
|
||||||
|
form.FormBorderStyle = FormBorderStyle.FixedDialog;
|
||||||
|
form.StartPosition = FormStartPosition.CenterScreen;
|
||||||
|
form.MinimizeBox = false;
|
||||||
|
form.MaximizeBox = false;
|
||||||
|
form.AcceptButton = buttonOk;
|
||||||
|
form.CancelButton = buttonCancel;
|
||||||
|
|
||||||
|
DialogResult dialogResult = form.ShowDialog();
|
||||||
|
return dialogResult;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
82
ConfigGenerator/EnhancedPropertyGrid.cs
Normal file
82
ConfigGenerator/EnhancedPropertyGrid.cs
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
/*
|
||||||
|
_ _ _ ____ _ _____
|
||||||
|
/ \ _ __ ___ | |__ (_)/ ___| | |_ ___ __ _ _ __ ___ | ___|__ _ _ __ _ __ ___
|
||||||
|
/ _ \ | '__|/ __|| '_ \ | |\___ \ | __|/ _ \ / _` || '_ ` _ \ | |_ / _` || '__|| '_ ` _ \
|
||||||
|
/ ___ \ | | | (__ | | | || | ___) || |_| __/| (_| || | | | | || _|| (_| || | | | | | | |
|
||||||
|
/_/ \_\|_| \___||_| |_||_||____/ \__|\___| \__,_||_| |_| |_||_| \__,_||_| |_| |_| |_|
|
||||||
|
|
||||||
|
Copyright 2015-2016 Łukasz "JustArchi" Domeradzki
|
||||||
|
Contact: JustArchi@JustArchi.net
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Windows.Forms;
|
||||||
|
|
||||||
|
namespace ConfigGenerator {
|
||||||
|
internal sealed class EnhancedPropertyGrid : PropertyGrid {
|
||||||
|
private readonly ASFConfig ASFConfig;
|
||||||
|
|
||||||
|
internal EnhancedPropertyGrid(ASFConfig config) {
|
||||||
|
if (config == null) {
|
||||||
|
throw new ArgumentNullException("config");
|
||||||
|
}
|
||||||
|
|
||||||
|
ASFConfig = config;
|
||||||
|
|
||||||
|
SelectedObject = config;
|
||||||
|
Anchor = AnchorStyles.Left | AnchorStyles.Right | AnchorStyles.Top;
|
||||||
|
Dock = DockStyle.Fill;
|
||||||
|
HelpVisible = false;
|
||||||
|
ToolbarVisible = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnPropertyValueChanged(PropertyValueChangedEventArgs e) {
|
||||||
|
if (e == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
base.OnPropertyValueChanged(e);
|
||||||
|
ASFConfig.Save();
|
||||||
|
|
||||||
|
BotConfig botConfig = ASFConfig as BotConfig;
|
||||||
|
if (botConfig != null) {
|
||||||
|
if (botConfig.Enabled) {
|
||||||
|
Tutorial.OnAction(Tutorial.EPhase.BotEnabled);
|
||||||
|
if (!string.IsNullOrEmpty(botConfig.SteamLogin) && !string.IsNullOrEmpty(botConfig.SteamPassword)) {
|
||||||
|
Tutorial.OnAction(Tutorial.EPhase.BotReady);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
GlobalConfig globalConfig = ASFConfig as GlobalConfig;
|
||||||
|
if (globalConfig != null) {
|
||||||
|
if (globalConfig.SteamOwnerID != 0) {
|
||||||
|
Tutorial.OnAction(Tutorial.EPhase.GlobalConfigReady);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnGotFocus(EventArgs e) {
|
||||||
|
if (e == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
base.OnGotFocus(e);
|
||||||
|
ASFConfig.Save();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
184
ConfigGenerator/GlobalConfig.cs
Normal file
184
ConfigGenerator/GlobalConfig.cs
Normal file
@@ -0,0 +1,184 @@
|
|||||||
|
/*
|
||||||
|
_ _ _ ____ _ _____
|
||||||
|
/ \ _ __ ___ | |__ (_)/ ___| | |_ ___ __ _ _ __ ___ | ___|__ _ _ __ _ __ ___
|
||||||
|
/ _ \ | '__|/ __|| '_ \ | |\___ \ | __|/ _ \ / _` || '_ ` _ \ | |_ / _` || '__|| '_ ` _ \
|
||||||
|
/ ___ \ | | | (__ | | | || | ___) || |_| __/| (_| || | | | | || _|| (_| || | | | | | | |
|
||||||
|
/_/ \_\|_| \___||_| |_||_||____/ \__|\___| \__,_||_| |_| |_||_| \__,_||_| |_| |_| |_|
|
||||||
|
|
||||||
|
Copyright 2015-2016 Łukasz "JustArchi" Domeradzki
|
||||||
|
Contact: JustArchi@JustArchi.net
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Net.Sockets;
|
||||||
|
|
||||||
|
namespace ConfigGenerator {
|
||||||
|
internal sealed class GlobalConfig : ASFConfig {
|
||||||
|
internal enum EUpdateChannel : byte {
|
||||||
|
Unknown,
|
||||||
|
Stable,
|
||||||
|
Experimental
|
||||||
|
}
|
||||||
|
|
||||||
|
private const byte DefaultMaxFarmingTime = 10;
|
||||||
|
private const byte DefaultFarmingDelay = 5;
|
||||||
|
private const byte DefaultHttpTimeout = 60;
|
||||||
|
private const ushort DefaultWCFPort = 1242;
|
||||||
|
private const 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 };
|
||||||
|
|
||||||
|
[JsonProperty(Required = Required.DisallowNull)]
|
||||||
|
public bool Debug { get; set; } = false;
|
||||||
|
|
||||||
|
[JsonProperty(Required = Required.DisallowNull)]
|
||||||
|
public bool Headless { get; set; } = false;
|
||||||
|
|
||||||
|
[JsonProperty(Required = Required.DisallowNull)]
|
||||||
|
public bool AutoUpdates { get; set; } = true;
|
||||||
|
|
||||||
|
[JsonProperty(Required = Required.DisallowNull)]
|
||||||
|
public bool AutoRestart { get; set; } = true;
|
||||||
|
|
||||||
|
[JsonProperty(Required = Required.DisallowNull)]
|
||||||
|
public EUpdateChannel UpdateChannel { get; set; } = EUpdateChannel.Stable;
|
||||||
|
|
||||||
|
[JsonProperty(Required = Required.DisallowNull)]
|
||||||
|
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; } = DefaultMaxFarmingTime;
|
||||||
|
|
||||||
|
[JsonProperty(Required = Required.DisallowNull)]
|
||||||
|
public byte IdleFarmingPeriod { get; set; } = 3;
|
||||||
|
|
||||||
|
[JsonProperty(Required = Required.DisallowNull)]
|
||||||
|
public byte FarmingDelay { get; set; } = DefaultFarmingDelay;
|
||||||
|
|
||||||
|
[JsonProperty(Required = Required.DisallowNull)]
|
||||||
|
public byte AccountPlayingDelay { get; set; } = 5;
|
||||||
|
|
||||||
|
[JsonProperty(Required = Required.DisallowNull)]
|
||||||
|
public byte LoginLimiterDelay { get; set; } = 7;
|
||||||
|
|
||||||
|
[JsonProperty(Required = Required.DisallowNull)]
|
||||||
|
public byte InventoryLimiterDelay { get; set; } = 3;
|
||||||
|
|
||||||
|
[JsonProperty(Required = Required.DisallowNull)]
|
||||||
|
public bool ForceHttp { get; set; } = false;
|
||||||
|
|
||||||
|
[JsonProperty(Required = Required.DisallowNull)]
|
||||||
|
public byte HttpTimeout { get; set; } = DefaultHttpTimeout;
|
||||||
|
|
||||||
|
[JsonProperty]
|
||||||
|
public string WCFHostname { get; set; } = "localhost";
|
||||||
|
|
||||||
|
[JsonProperty(Required = Required.DisallowNull)]
|
||||||
|
public ushort WCFPort { get; set; } = DefaultWCFPort;
|
||||||
|
|
||||||
|
[JsonProperty(Required = Required.DisallowNull)]
|
||||||
|
public bool LogToFile { get; set; } = true;
|
||||||
|
|
||||||
|
[JsonProperty(Required = Required.DisallowNull)]
|
||||||
|
public bool Statistics { get; set; } = true;
|
||||||
|
|
||||||
|
// TODO: Please remove me immediately after https://github.com/SteamRE/SteamKit/issues/254 gets fixed
|
||||||
|
[JsonProperty(Required = Required.DisallowNull)]
|
||||||
|
public bool HackIgnoreMachineID { get; set; } = false;
|
||||||
|
|
||||||
|
[JsonProperty(Required = Required.DisallowNull)]
|
||||||
|
public List<uint> Blacklist { get; set; } = new List<uint>();
|
||||||
|
|
||||||
|
internal static GlobalConfig Load(string filePath) {
|
||||||
|
if (string.IsNullOrEmpty(filePath)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!File.Exists(filePath)) {
|
||||||
|
return new GlobalConfig(filePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
GlobalConfig globalConfig;
|
||||||
|
try {
|
||||||
|
globalConfig = JsonConvert.DeserializeObject<GlobalConfig>(File.ReadAllText(filePath));
|
||||||
|
} catch (Exception e) {
|
||||||
|
Logging.LogGenericException(e);
|
||||||
|
return new GlobalConfig(filePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (globalConfig == null) {
|
||||||
|
return new GlobalConfig(filePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
globalConfig.FilePath = filePath;
|
||||||
|
|
||||||
|
// SK2 supports only TCP and UDP steam protocols
|
||||||
|
// 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 + ". 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
// This constructor is used only by deserializer
|
||||||
|
private GlobalConfig() { }
|
||||||
|
|
||||||
|
private GlobalConfig(string filePath) : base(filePath) {
|
||||||
|
if (string.IsNullOrEmpty(filePath)) {
|
||||||
|
throw new ArgumentNullException("filePath");
|
||||||
|
}
|
||||||
|
|
||||||
|
Blacklist.AddRange(GlobalBlacklist);
|
||||||
|
Save();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
93
ConfigGenerator/Logging.cs
Normal file
93
ConfigGenerator/Logging.cs
Normal file
@@ -0,0 +1,93 @@
|
|||||||
|
/*
|
||||||
|
_ _ _ ____ _ _____
|
||||||
|
/ \ _ __ ___ | |__ (_)/ ___| | |_ ___ __ _ _ __ ___ | ___|__ _ _ __ _ __ ___
|
||||||
|
/ _ \ | '__|/ __|| '_ \ | |\___ \ | __|/ _ \ / _` || '_ ` _ \ | |_ / _` || '__|| '_ ` _ \
|
||||||
|
/ ___ \ | | | (__ | | | || | ___) || |_| __/| (_| || | | | | || _|| (_| || | | | | | | |
|
||||||
|
/_/ \_\|_| \___||_| |_||_||____/ \__|\___| \__,_||_| |_| |_||_| \__,_||_| |_| |_| |_|
|
||||||
|
|
||||||
|
Copyright 2015-2016 Łukasz "JustArchi" Domeradzki
|
||||||
|
Contact: JustArchi@JustArchi.net
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
using System.Windows.Forms;
|
||||||
|
|
||||||
|
namespace ConfigGenerator {
|
||||||
|
internal static class Logging {
|
||||||
|
internal static void LogGenericInfo(string message) {
|
||||||
|
if (string.IsNullOrEmpty(message)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
MessageBox.Show(message, "Information", MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static void LogGenericWTF(string message, [CallerMemberName] string previousMethodName = "") {
|
||||||
|
if (string.IsNullOrEmpty(message)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
MessageBox.Show(previousMethodName + "() " + message, "WTF", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static void LogGenericError(string message, [CallerMemberName] string previousMethodName = "") {
|
||||||
|
if (string.IsNullOrEmpty(message)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
MessageBox.Show(previousMethodName + "() " + message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static void LogGenericException(Exception exception, [CallerMemberName] string previousMethodName = "") {
|
||||||
|
if (exception == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
MessageBox.Show(previousMethodName + "() " + exception.Message + Environment.NewLine + exception.StackTrace, "Exception", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
|
|
||||||
|
if (exception.InnerException != null) {
|
||||||
|
LogGenericException(exception.InnerException, previousMethodName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static void LogGenericWarning(string message, [CallerMemberName] string previousMethodName = "") {
|
||||||
|
if (string.IsNullOrEmpty(message)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
MessageBox.Show(previousMethodName + "() " + message, "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static void LogNullError(string nullObjectName, [CallerMemberName] string previousMethodName = "") {
|
||||||
|
if (string.IsNullOrEmpty(nullObjectName)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
LogGenericError(nullObjectName + " is null!", previousMethodName);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Conditional("DEBUG")]
|
||||||
|
internal static void LogGenericDebug(string message, [CallerMemberName] string previousMethodName = "") {
|
||||||
|
if (string.IsNullOrEmpty(message)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
MessageBox.Show(previousMethodName + "() " + message, "Debug", MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
78
ConfigGenerator/MainForm.Designer.cs
generated
Normal file
78
ConfigGenerator/MainForm.Designer.cs
generated
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
namespace ConfigGenerator {
|
||||||
|
partial class MainForm {
|
||||||
|
/// <summary>
|
||||||
|
/// Required designer variable.
|
||||||
|
/// </summary>
|
||||||
|
private System.ComponentModel.IContainer components = null;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Clean up any resources being used.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||||
|
protected override void Dispose(bool disposing) {
|
||||||
|
if (disposing && (components != null)) {
|
||||||
|
components.Dispose();
|
||||||
|
}
|
||||||
|
base.Dispose(disposing);
|
||||||
|
}
|
||||||
|
|
||||||
|
#region Windows Form Designer generated code
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Required method for Designer support - do not modify
|
||||||
|
/// the contents of this method with the code editor.
|
||||||
|
/// </summary>
|
||||||
|
private void InitializeComponent() {
|
||||||
|
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(MainForm));
|
||||||
|
this.MainTab = new System.Windows.Forms.TabControl();
|
||||||
|
this.SuspendLayout();
|
||||||
|
//
|
||||||
|
// MainTab
|
||||||
|
//
|
||||||
|
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(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(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(7F, 17F);
|
||||||
|
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||||
|
this.AutoScroll = true;
|
||||||
|
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("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);
|
||||||
|
this.MaximizeBox = false;
|
||||||
|
this.MinimizeBox = false;
|
||||||
|
this.Name = "MainForm";
|
||||||
|
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
|
||||||
|
this.Text = "ASF Config Generator";
|
||||||
|
this.HelpButtonClicked += new System.ComponentModel.CancelEventHandler(this.MainForm_HelpButtonClicked);
|
||||||
|
this.Load += new System.EventHandler(this.MainForm_Load);
|
||||||
|
this.Shown += new System.EventHandler(this.MainForm_Shown);
|
||||||
|
this.ResumeLayout(false);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
private System.Windows.Forms.TabControl MainTab;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
199
ConfigGenerator/MainForm.cs
Normal file
199
ConfigGenerator/MainForm.cs
Normal file
@@ -0,0 +1,199 @@
|
|||||||
|
/*
|
||||||
|
_ _ _ ____ _ _____
|
||||||
|
/ \ _ __ ___ | |__ (_)/ ___| | |_ ___ __ _ _ __ ___ | ___|__ _ _ __ _ __ ___
|
||||||
|
/ _ \ | '__|/ __|| '_ \ | |\___ \ | __|/ _ \ / _` || '_ ` _ \ | |_ / _` || '__|| '_ ` _ \
|
||||||
|
/ ___ \ | | | (__ | | | || | ___) || |_| __/| (_| || | | | | || _|| (_| || | | | | | | |
|
||||||
|
/_/ \_\|_| \___||_| |_||_||____/ \__|\___| \__,_||_| |_| |_||_| \__,_||_| |_| |_| |_|
|
||||||
|
|
||||||
|
Copyright 2015-2016 Łukasz "JustArchi" Domeradzki
|
||||||
|
Contact: JustArchi@JustArchi.net
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.IO;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
using System.Windows.Forms;
|
||||||
|
|
||||||
|
namespace ConfigGenerator {
|
||||||
|
public partial class MainForm : Form {
|
||||||
|
private const byte ReservedTabs = 3;
|
||||||
|
|
||||||
|
private readonly TabPage NewTab = new TabPage { Text = "+" };
|
||||||
|
private readonly TabPage RemoveTab = new TabPage { Text = "-" };
|
||||||
|
private readonly TabPage RenameTab = new TabPage { Text = "~" };
|
||||||
|
|
||||||
|
private ConfigPage ASFTab;
|
||||||
|
private TabPage OldTab;
|
||||||
|
|
||||||
|
public MainForm() {
|
||||||
|
InitializeComponent();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void MainForm_Load(object sender, EventArgs e) {
|
||||||
|
if (sender == null || e == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ASFTab = new ConfigPage(GlobalConfig.Load(Path.Combine(Program.ConfigDirectory, Program.GlobalConfigFile)));
|
||||||
|
|
||||||
|
MainTab.TabPages.Add(ASFTab);
|
||||||
|
|
||||||
|
foreach (var configFile in Directory.EnumerateFiles(Program.ConfigDirectory, "*.json")) {
|
||||||
|
string botName = Path.GetFileNameWithoutExtension(configFile);
|
||||||
|
switch (botName) {
|
||||||
|
case Program.ASF:
|
||||||
|
case "example":
|
||||||
|
case "minimal":
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
MainTab.TabPages.Add(new ConfigPage(BotConfig.Load(configFile)));
|
||||||
|
Tutorial.Enabled = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
MainTab.TabPages.AddRange(new[] { RemoveTab, RenameTab, NewTab });
|
||||||
|
Tutorial.OnAction(Tutorial.EPhase.Start);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void MainTab_Selected(object sender, TabControlEventArgs e) {
|
||||||
|
if (sender == null || e == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (e.TabPage == RemoveTab) {
|
||||||
|
ConfigPage configPage = OldTab as ConfigPage;
|
||||||
|
if (configPage == null) {
|
||||||
|
MainTab.SelectedIndex = -1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (configPage == ASFTab) {
|
||||||
|
MainTab.SelectedTab = ASFTab;
|
||||||
|
Logging.LogGenericError("You can't remove global config!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
MainTab.SelectedTab = configPage;
|
||||||
|
|
||||||
|
if (DialogBox.YesNoBox("Removal", "Do you really want to remove this config?") != DialogResult.Yes) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
MainTab.SelectedIndex = 0;
|
||||||
|
configPage.ASFConfig.Remove();
|
||||||
|
MainTab.TabPages.Remove(configPage);
|
||||||
|
} else if (e.TabPage == RenameTab) {
|
||||||
|
ConfigPage configPage = OldTab as ConfigPage;
|
||||||
|
if (configPage == null) {
|
||||||
|
MainTab.SelectedIndex = -1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (configPage == ASFTab) {
|
||||||
|
MainTab.SelectedTab = ASFTab;
|
||||||
|
Logging.LogGenericError("You can't rename global config!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
MainTab.SelectedTab = configPage;
|
||||||
|
|
||||||
|
string input;
|
||||||
|
if (DialogBox.InputBox("Rename", "Your new bot name:", out input) != DialogResult.OK) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (string.IsNullOrEmpty(input)) {
|
||||||
|
Logging.LogGenericError("Your bot name is empty!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get rid of any potential whitespaces in bot name
|
||||||
|
input = Regex.Replace(input, @"\s+", "");
|
||||||
|
|
||||||
|
configPage.ASFConfig.Rename(input);
|
||||||
|
configPage.RefreshText();
|
||||||
|
} else if (e.TabPage == NewTab) {
|
||||||
|
ConfigPage configPage = OldTab as ConfigPage;
|
||||||
|
if (configPage == null) {
|
||||||
|
MainTab.SelectedIndex = -1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
MainTab.SelectedTab = configPage;
|
||||||
|
|
||||||
|
Tutorial.OnAction(Tutorial.EPhase.BotNickname);
|
||||||
|
|
||||||
|
string input;
|
||||||
|
if (DialogBox.InputBox("New", "Your new bot name:", out input) != DialogResult.OK) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (string.IsNullOrEmpty(input)) {
|
||||||
|
Logging.LogGenericError("Your bot name is empty!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get rid of any potential whitespaces in bot name
|
||||||
|
input = Regex.Replace(input, @"\s+", "");
|
||||||
|
|
||||||
|
foreach (ASFConfig config in ASFConfig.ASFConfigs) {
|
||||||
|
if (Path.GetFileNameWithoutExtension(config.FilePath).Equals(input)) {
|
||||||
|
Logging.LogGenericError("Bot with such name exists already!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
input = Path.Combine(Program.ConfigDirectory, input + ".json");
|
||||||
|
|
||||||
|
ConfigPage newConfigPage = new ConfigPage(BotConfig.Load(input));
|
||||||
|
MainTab.TabPages.Insert(MainTab.TabPages.Count - ReservedTabs, newConfigPage);
|
||||||
|
MainTab.SelectedTab = newConfigPage;
|
||||||
|
Tutorial.OnAction(Tutorial.EPhase.BotNicknameFinished);
|
||||||
|
} else if (e.TabPage == ASFTab) {
|
||||||
|
Tutorial.OnAction(Tutorial.EPhase.GlobalConfigOpened);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void MainTab_Deselecting(object sender, TabControlCancelEventArgs e) {
|
||||||
|
if (sender == null || e == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
OldTab = e.TabPage;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void MainForm_Shown(object sender, EventArgs e) {
|
||||||
|
if (sender == null || e == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Tutorial.OnAction(Tutorial.EPhase.Shown);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void MainForm_HelpButtonClicked(object sender, CancelEventArgs e) {
|
||||||
|
if (sender == null || e == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
e.Cancel = true;
|
||||||
|
Tutorial.OnAction(Tutorial.EPhase.Help);
|
||||||
|
Process.Start("https://github.com/JustArchi/ArchiSteamFarm/wiki/Configuration");
|
||||||
|
Tutorial.OnAction(Tutorial.EPhase.HelpFinished);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
6293
ConfigGenerator/MainForm.resx
Normal file
6293
ConfigGenerator/MainForm.resx
Normal file
File diff suppressed because it is too large
Load Diff
98
ConfigGenerator/Program.cs
Normal file
98
ConfigGenerator/Program.cs
Normal file
@@ -0,0 +1,98 @@
|
|||||||
|
/*
|
||||||
|
_ _ _ ____ _ _____
|
||||||
|
/ \ _ __ ___ | |__ (_)/ ___| | |_ ___ __ _ _ __ ___ | ___|__ _ _ __ _ __ ___
|
||||||
|
/ _ \ | '__|/ __|| '_ \ | |\___ \ | __|/ _ \ / _` || '_ ` _ \ | |_ / _` || '__|| '_ ` _ \
|
||||||
|
/ ___ \ | | | (__ | | | || | ___) || |_| __/| (_| || | | | | || _|| (_| || | | | | | | |
|
||||||
|
/_/ \_\|_| \___||_| |_||_||____/ \__|\___| \__,_||_| |_| |_||_| \__,_||_| |_| |_| |_|
|
||||||
|
|
||||||
|
Copyright 2015-2016 Łukasz "JustArchi" Domeradzki
|
||||||
|
Contact: JustArchi@JustArchi.net
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Windows.Forms;
|
||||||
|
|
||||||
|
namespace ConfigGenerator {
|
||||||
|
internal static class Program {
|
||||||
|
internal const string ASF = "ASF";
|
||||||
|
internal const string ConfigDirectory = "config";
|
||||||
|
internal const string GlobalConfigFile = ASF + ".json";
|
||||||
|
|
||||||
|
private const string ASFDirectory = "ArchiSteamFarm";
|
||||||
|
|
||||||
|
private static readonly string ExecutableDirectory = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The main entry point for the application.
|
||||||
|
/// </summary>
|
||||||
|
[STAThread]
|
||||||
|
private static void Main() {
|
||||||
|
Init();
|
||||||
|
Application.EnableVisualStyles();
|
||||||
|
Application.SetCompatibleTextRenderingDefault(false);
|
||||||
|
Application.Run(new MainForm());
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void Init() {
|
||||||
|
AppDomain.CurrentDomain.UnhandledException += UnhandledExceptionHandler;
|
||||||
|
TaskScheduler.UnobservedTaskException += UnobservedTaskExceptionHandler;
|
||||||
|
|
||||||
|
Directory.SetCurrentDirectory(ExecutableDirectory);
|
||||||
|
|
||||||
|
// Allow loading configs from source tree if it's a debug build
|
||||||
|
if (Debugging.IsDebugBuild) {
|
||||||
|
|
||||||
|
// Common structure is bin/(x64/)Debug/ArchiSteamFarm.exe, so we allow up to 4 directories up
|
||||||
|
for (byte i = 0; i < 4; i++) {
|
||||||
|
Directory.SetCurrentDirectory("..");
|
||||||
|
if (Directory.Exists(ASFDirectory)) {
|
||||||
|
Directory.SetCurrentDirectory(ASFDirectory);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If config directory doesn't exist after our adjustment, abort all of that
|
||||||
|
if (!Directory.Exists(ConfigDirectory)) {
|
||||||
|
Directory.SetCurrentDirectory(ExecutableDirectory);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!Directory.Exists(ConfigDirectory)) {
|
||||||
|
Logging.LogGenericError("Config directory could not be found!");
|
||||||
|
Environment.Exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void UnhandledExceptionHandler(object sender, UnhandledExceptionEventArgs args) {
|
||||||
|
if (sender == null || args == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Logging.LogGenericException((Exception) args.ExceptionObject);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void UnobservedTaskExceptionHandler(object sender, UnobservedTaskExceptionEventArgs args) {
|
||||||
|
if (sender == null || args == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Logging.LogGenericException(args.Exception);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
36
ConfigGenerator/Properties/AssemblyInfo.cs
Normal file
36
ConfigGenerator/Properties/AssemblyInfo.cs
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
using System.Reflection;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
|
// General Information about an assembly is controlled through the following
|
||||||
|
// set of attributes. Change these attribute values to modify the information
|
||||||
|
// associated with an assembly.
|
||||||
|
[assembly: AssemblyTitle("ConfigGenerator")]
|
||||||
|
[assembly: AssemblyDescription("")]
|
||||||
|
[assembly: AssemblyConfiguration("")]
|
||||||
|
[assembly: AssemblyCompany("")]
|
||||||
|
[assembly: AssemblyProduct("ConfigGenerator")]
|
||||||
|
[assembly: AssemblyCopyright("Copyright © ArchiSteamFarm 2015-2016")]
|
||||||
|
[assembly: AssemblyTrademark("")]
|
||||||
|
[assembly: AssemblyCulture("")]
|
||||||
|
|
||||||
|
// Setting ComVisible to false makes the types in this assembly not visible
|
||||||
|
// to COM components. If you need to access a type in this assembly from
|
||||||
|
// COM, set the ComVisible attribute to true on that type.
|
||||||
|
[assembly: ComVisible(false)]
|
||||||
|
|
||||||
|
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||||
|
[assembly: Guid("c3f6fe68-5e75-415e-bea1-1e7c16d6a433")]
|
||||||
|
|
||||||
|
// Version information for an assembly consists of the following four values:
|
||||||
|
//
|
||||||
|
// Major Version
|
||||||
|
// Minor Version
|
||||||
|
// Build Number
|
||||||
|
// Revision
|
||||||
|
//
|
||||||
|
// 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("1.0.0.0")]
|
||||||
|
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||||
62
ConfigGenerator/Properties/Resources.Designer.cs
generated
Normal file
62
ConfigGenerator/Properties/Resources.Designer.cs
generated
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// <auto-generated>
|
||||||
|
// This code was generated by a tool.
|
||||||
|
// Runtime Version:4.0.30319.42000
|
||||||
|
//
|
||||||
|
// Changes to this file may cause incorrect behavior and will be lost if
|
||||||
|
// the code is regenerated.
|
||||||
|
// </auto-generated>
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
namespace ConfigGenerator.Properties {
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A strongly-typed resource class, for looking up localized strings, etc.
|
||||||
|
/// </summary>
|
||||||
|
// This class was auto-generated by the StronglyTypedResourceBuilder
|
||||||
|
// class via a tool like ResGen or Visual Studio.
|
||||||
|
// To add or remove a member, edit your .ResX file then rerun ResGen
|
||||||
|
// with the /str option, or rebuild your VS project.
|
||||||
|
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
|
||||||
|
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||||
|
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||||
|
internal class Resources {
|
||||||
|
|
||||||
|
private static global::System.Resources.ResourceManager resourceMan;
|
||||||
|
|
||||||
|
private static global::System.Globalization.CultureInfo resourceCulture;
|
||||||
|
|
||||||
|
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
|
||||||
|
internal Resources() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns the cached ResourceManager instance used by this class.
|
||||||
|
/// </summary>
|
||||||
|
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||||
|
internal static global::System.Resources.ResourceManager ResourceManager {
|
||||||
|
get {
|
||||||
|
if ((resourceMan == null)) {
|
||||||
|
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("ConfigGenerator.Properties.Resources", typeof(Resources).Assembly);
|
||||||
|
resourceMan = temp;
|
||||||
|
}
|
||||||
|
return resourceMan;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Overrides the current thread's CurrentUICulture property for all
|
||||||
|
/// resource lookups using this strongly typed resource class.
|
||||||
|
/// </summary>
|
||||||
|
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||||
|
internal static global::System.Globalization.CultureInfo Culture {
|
||||||
|
get {
|
||||||
|
return resourceCulture;
|
||||||
|
}
|
||||||
|
set {
|
||||||
|
resourceCulture = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
117
ConfigGenerator/Properties/Resources.resx
Normal file
117
ConfigGenerator/Properties/Resources.resx
Normal file
@@ -0,0 +1,117 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<root>
|
||||||
|
<!--
|
||||||
|
Microsoft ResX Schema
|
||||||
|
|
||||||
|
Version 2.0
|
||||||
|
|
||||||
|
The primary goals of this format is to allow a simple XML format
|
||||||
|
that is mostly human readable. The generation and parsing of the
|
||||||
|
various data types are done through the TypeConverter classes
|
||||||
|
associated with the data types.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
... ado.net/XML headers & schema ...
|
||||||
|
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||||
|
<resheader name="version">2.0</resheader>
|
||||||
|
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||||
|
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||||
|
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||||
|
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||||
|
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||||
|
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
|
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||||
|
<comment>This is a comment</comment>
|
||||||
|
</data>
|
||||||
|
|
||||||
|
There are any number of "resheader" rows that contain simple
|
||||||
|
name/value pairs.
|
||||||
|
|
||||||
|
Each data row contains a name, and value. The row also contains a
|
||||||
|
type or mimetype. Type corresponds to a .NET class that support
|
||||||
|
text/value conversion through the TypeConverter architecture.
|
||||||
|
Classes that don't support this are serialized and stored with the
|
||||||
|
mimetype set.
|
||||||
|
|
||||||
|
The mimetype is used for serialized objects, and tells the
|
||||||
|
ResXResourceReader how to depersist the object. This is currently not
|
||||||
|
extensible. For a given mimetype the value must be set accordingly:
|
||||||
|
|
||||||
|
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||||
|
that the ResXResourceWriter will generate, however the reader can
|
||||||
|
read any of the formats listed below.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.binary.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Serialization.Formatters.Binary.BinaryFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.soap.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||||
|
value : The object must be serialized into a byte array
|
||||||
|
: using a System.ComponentModel.TypeConverter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
-->
|
||||||
|
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||||
|
<xsd:element name="root" msdata:IsDataSet="true">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:choice maxOccurs="unbounded">
|
||||||
|
<xsd:element name="metadata">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="assembly">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:attribute name="alias" type="xsd:string" />
|
||||||
|
<xsd:attribute name="name" type="xsd:string" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="data">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="resheader">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:choice>
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:schema>
|
||||||
|
<resheader name="resmimetype">
|
||||||
|
<value>text/microsoft-resx</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="version">
|
||||||
|
<value>2.0</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="reader">
|
||||||
|
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="writer">
|
||||||
|
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
</root>
|
||||||
26
ConfigGenerator/Properties/Settings.Designer.cs
generated
Normal file
26
ConfigGenerator/Properties/Settings.Designer.cs
generated
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// <auto-generated>
|
||||||
|
// This code was generated by a tool.
|
||||||
|
// Runtime Version:4.0.30319.42000
|
||||||
|
//
|
||||||
|
// Changes to this file may cause incorrect behavior and will be lost if
|
||||||
|
// the code is regenerated.
|
||||||
|
// </auto-generated>
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
namespace ConfigGenerator.Properties {
|
||||||
|
|
||||||
|
|
||||||
|
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||||
|
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")]
|
||||||
|
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
|
||||||
|
|
||||||
|
private static Settings defaultInstance = ((Settings) (global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
|
||||||
|
|
||||||
|
public static Settings Default {
|
||||||
|
get {
|
||||||
|
return defaultInstance;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
7
ConfigGenerator/Properties/Settings.settings
Normal file
7
ConfigGenerator/Properties/Settings.settings
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
<?xml version='1.0' encoding='utf-8'?>
|
||||||
|
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)">
|
||||||
|
<Profiles>
|
||||||
|
<Profile Name="(Default)" />
|
||||||
|
</Profiles>
|
||||||
|
<Settings />
|
||||||
|
</SettingsFile>
|
||||||
97
ConfigGenerator/Tutorial.cs
Normal file
97
ConfigGenerator/Tutorial.cs
Normal file
@@ -0,0 +1,97 @@
|
|||||||
|
/*
|
||||||
|
_ _ _ ____ _ _____
|
||||||
|
/ \ _ __ ___ | |__ (_)/ ___| | |_ ___ __ _ _ __ ___ | ___|__ _ _ __ _ __ ___
|
||||||
|
/ _ \ | '__|/ __|| '_ \ | |\___ \ | __|/ _ \ / _` || '_ ` _ \ | |_ / _` || '__|| '_ ` _ \
|
||||||
|
/ ___ \ | | | (__ | | | || | ___) || |_| __/| (_| || | | | | || _|| (_| || | | | | | | |
|
||||||
|
/_/ \_\|_| \___||_| |_||_||____/ \__|\___| \__,_||_| |_| |_||_| \__,_||_| |_| |_| |_|
|
||||||
|
|
||||||
|
Copyright 2015-2016 Łukasz "JustArchi" Domeradzki
|
||||||
|
Contact: JustArchi@JustArchi.net
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace ConfigGenerator {
|
||||||
|
internal static class Tutorial {
|
||||||
|
internal enum EPhase : byte {
|
||||||
|
Unknown,
|
||||||
|
Start,
|
||||||
|
Shown,
|
||||||
|
Help,
|
||||||
|
HelpFinished,
|
||||||
|
BotNickname,
|
||||||
|
BotNicknameFinished,
|
||||||
|
BotEnabled,
|
||||||
|
BotReady,
|
||||||
|
GlobalConfigOpened,
|
||||||
|
GlobalConfigReady
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static bool Enabled { get; set; } = true;
|
||||||
|
|
||||||
|
private static EPhase NextPhase = EPhase.Start;
|
||||||
|
|
||||||
|
internal static void OnAction(EPhase phase) {
|
||||||
|
if (!Enabled || phase != NextPhase) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (phase) {
|
||||||
|
case EPhase.Unknown:
|
||||||
|
break;
|
||||||
|
case EPhase.Start:
|
||||||
|
Logging.LogGenericInfo("Hello there! I noticed that you're using ASF Config Generator for the first time, so let me help you a bit.");
|
||||||
|
break;
|
||||||
|
case EPhase.Shown:
|
||||||
|
Logging.LogGenericInfo("You can now notice the main ASF Config Generator screen, it's really easy to use!");
|
||||||
|
Logging.LogGenericInfo("At the top of the window you can notice currently loaded configs, and 3 extra buttons for removing, renaming and adding new ones.");
|
||||||
|
Logging.LogGenericInfo("In the middle of the window you will be able to configure all config properties that are available for you.");
|
||||||
|
Logging.LogGenericInfo("In the top right corner you can find help button [?] which will redirect you to ASF wiki where you can find more information.");
|
||||||
|
Logging.LogGenericInfo("Please click the help button to continue.");
|
||||||
|
break;
|
||||||
|
case EPhase.Help:
|
||||||
|
Logging.LogGenericInfo("Well done! On ASF wiki you can find detailed help about every config property you're going to configure in a moment.");
|
||||||
|
break;
|
||||||
|
case EPhase.HelpFinished:
|
||||||
|
Logging.LogGenericInfo("Alright, let's start configuring our ASF. Click on the plus [+] button to add your first steam account to ASF!");
|
||||||
|
break;
|
||||||
|
case EPhase.BotNickname:
|
||||||
|
Logging.LogGenericInfo("Good job! You'll be asked for your bot name now. A good example would be a nickname that you're using for the steam account you're configuring right now, or any other name of your choice which will be easy for you to connect with bot instance that is being configured. Please don't use spaces in the name.");
|
||||||
|
break;
|
||||||
|
case EPhase.BotNicknameFinished:
|
||||||
|
Logging.LogGenericInfo("As you can see your bot config is now ready to configure!");
|
||||||
|
Logging.LogGenericInfo("First thing that you want to do is switching \"Enabled\" property from False to True, try it!");
|
||||||
|
break;
|
||||||
|
case EPhase.BotEnabled:
|
||||||
|
Logging.LogGenericInfo("Excellent! Now your bot instance is enabled. You need to configure at least 2 more config properties - \"SteamLogin\" and \"SteamPassword\". The tutorial will continue after you're done with it. Remember to visit ASF wiki by clicking the help icon if you're unsure how given property should be configured!");
|
||||||
|
break;
|
||||||
|
case EPhase.BotReady:
|
||||||
|
Logging.LogGenericInfo("If the data you put is proper, then your bot is ready to run! We need to do only one more thing now. Visit global ASF config, which is labelled as \"ASF\" on your config tab.");
|
||||||
|
break;
|
||||||
|
case EPhase.GlobalConfigOpened:
|
||||||
|
Logging.LogGenericInfo("While bot config affects only given bot instance you're configuring, global config affects whole ASF process, including all configured bots.");
|
||||||
|
Logging.LogGenericInfo("In order to fully configure your ASF, I suggest to fill \"SteamOwnerID\" property. Remember, if you don't know what to put, help button is always there for you!");
|
||||||
|
break;
|
||||||
|
case EPhase.GlobalConfigReady:
|
||||||
|
Logging.LogGenericInfo("Your ASF is now ready! Simply launch ASF process by double-clicking ASF.exe binary and if you did everything properly, you should now notice that ASF logs in on your account and starts farming. If you have SteamGuard or 2FA authorization enabled, ASF will ask you for that once");
|
||||||
|
Logging.LogGenericInfo("Congratulations! You've done everything that is needed in order to make ASF \"work\". I highly recommend reading the wiki now, as ASF offers some really neat features for you to configure, such as offline farming or deciding upon most efficient cards farming algorithm.");
|
||||||
|
Logging.LogGenericInfo("If you'd like to add another steam account for farming, simply click the plus [+] button and add another instance. You can also rename bots [~] and remove them [-]. Good luck!");
|
||||||
|
Enabled = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
NextPhase++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
BIN
ConfigGenerator/cirno.ico
Normal file
BIN
ConfigGenerator/cirno.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 361 KiB |
4
ConfigGenerator/packages.config
Normal file
4
ConfigGenerator/packages.config
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<packages>
|
||||||
|
<package id="Newtonsoft.Json" version="8.0.3" targetFramework="net451" />
|
||||||
|
</packages>
|
||||||
6
GUI/App.config
Normal file
6
GUI/App.config
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<configuration>
|
||||||
|
<startup>
|
||||||
|
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.1"/>
|
||||||
|
</startup>
|
||||||
|
</configuration>
|
||||||
@@ -22,12 +22,14 @@
|
|||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
using Newtonsoft.Json;
|
namespace GUI {
|
||||||
using System.Collections.Generic;
|
internal static class Debugging {
|
||||||
|
#if DEBUG
|
||||||
|
internal static readonly bool IsDebugBuild = true;
|
||||||
|
#else
|
||||||
|
internal static readonly bool IsDebugBuild = false;
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace ArchiSteamFarm {
|
internal static bool IsReleaseBuild => !IsDebugBuild;
|
||||||
internal sealed class SteamItemList {
|
|
||||||
[JsonProperty(Required = Required.Always)]
|
|
||||||
internal List<SteamItem> assets { get; } = new List<SteamItem>();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
513
GUI/Form1.Designer.cs
generated
Normal file
513
GUI/Form1.Designer.cs
generated
Normal file
@@ -0,0 +1,513 @@
|
|||||||
|
namespace GUI {
|
||||||
|
partial class Form1 {
|
||||||
|
/// <summary>
|
||||||
|
/// Erforderliche Designervariable.
|
||||||
|
/// </summary>
|
||||||
|
private System.ComponentModel.IContainer components = null;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Verwendete Ressourcen bereinigen.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="disposing">True, wenn verwaltete Ressourcen gelöscht werden sollen; andernfalls False.</param>
|
||||||
|
protected override void Dispose(bool disposing) {
|
||||||
|
if (disposing && (components != null)) {
|
||||||
|
components.Dispose();
|
||||||
|
}
|
||||||
|
base.Dispose(disposing);
|
||||||
|
}
|
||||||
|
|
||||||
|
#region Vom Windows Form-Designer generierter Code
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Erforderliche Methode für die Designerunterstützung.
|
||||||
|
/// Der Inhalt der Methode darf nicht mit dem Code-Editor geändert werden.
|
||||||
|
/// </summary>
|
||||||
|
private void InitializeComponent() {
|
||||||
|
this.components = new System.ComponentModel.Container();
|
||||||
|
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(Form1));
|
||||||
|
this.button5 = new System.Windows.Forms.Button();
|
||||||
|
this.button4 = new System.Windows.Forms.Button();
|
||||||
|
this.button3 = new System.Windows.Forms.Button();
|
||||||
|
this.button2 = new System.Windows.Forms.Button();
|
||||||
|
this.button1 = new System.Windows.Forms.Button();
|
||||||
|
this.label2 = new System.Windows.Forms.Label();
|
||||||
|
this.label1 = new System.Windows.Forms.Label();
|
||||||
|
this.textBox2 = new System.Windows.Forms.TextBox();
|
||||||
|
this.textBox1 = new System.Windows.Forms.TextBox();
|
||||||
|
this.comboBox1 = new System.Windows.Forms.ComboBox();
|
||||||
|
this.checkBox3 = new System.Windows.Forms.CheckBox();
|
||||||
|
this.checkBox2 = new System.Windows.Forms.CheckBox();
|
||||||
|
this.checkBox1 = new System.Windows.Forms.CheckBox();
|
||||||
|
this.textBox3 = new System.Windows.Forms.TextBox();
|
||||||
|
this.ASFGUI = new System.Windows.Forms.NotifyIcon(this.components);
|
||||||
|
this.checkBox4 = new System.Windows.Forms.CheckBox();
|
||||||
|
this.button6 = new System.Windows.Forms.Button();
|
||||||
|
this.button7 = new System.Windows.Forms.Button();
|
||||||
|
this.button8 = new System.Windows.Forms.Button();
|
||||||
|
this.button9 = new System.Windows.Forms.Button();
|
||||||
|
this.button10 = new System.Windows.Forms.Button();
|
||||||
|
this.button11 = new System.Windows.Forms.Button();
|
||||||
|
this.button12 = new System.Windows.Forms.Button();
|
||||||
|
this.button13 = new System.Windows.Forms.Button();
|
||||||
|
this.button14 = new System.Windows.Forms.Button();
|
||||||
|
this.button15 = new System.Windows.Forms.Button();
|
||||||
|
this.button16 = new System.Windows.Forms.Button();
|
||||||
|
this.button17 = new System.Windows.Forms.Button();
|
||||||
|
this.button18 = new System.Windows.Forms.Button();
|
||||||
|
this.button19 = new System.Windows.Forms.Button();
|
||||||
|
this.label3 = new System.Windows.Forms.Label();
|
||||||
|
this.label4 = new System.Windows.Forms.Label();
|
||||||
|
this.button20 = new System.Windows.Forms.Button();
|
||||||
|
this.label5 = new System.Windows.Forms.Label();
|
||||||
|
this.SuspendLayout();
|
||||||
|
//
|
||||||
|
// button5
|
||||||
|
//
|
||||||
|
this.button5.Location = new System.Drawing.Point(86, 204);
|
||||||
|
this.button5.Margin = new System.Windows.Forms.Padding(2, 2, 2, 2);
|
||||||
|
this.button5.Name = "button5";
|
||||||
|
this.button5.Size = new System.Drawing.Size(56, 19);
|
||||||
|
this.button5.TabIndex = 27;
|
||||||
|
this.button5.Text = "2fa ok";
|
||||||
|
this.button5.UseVisualStyleBackColor = true;
|
||||||
|
this.button5.Click += new System.EventHandler(this.button5_Click);
|
||||||
|
//
|
||||||
|
// button4
|
||||||
|
//
|
||||||
|
this.button4.Location = new System.Drawing.Point(26, 204);
|
||||||
|
this.button4.Margin = new System.Windows.Forms.Padding(2, 2, 2, 2);
|
||||||
|
this.button4.Name = "button4";
|
||||||
|
this.button4.Size = new System.Drawing.Size(56, 19);
|
||||||
|
this.button4.TabIndex = 26;
|
||||||
|
this.button4.Text = "2fa code";
|
||||||
|
this.button4.UseVisualStyleBackColor = true;
|
||||||
|
this.button4.Click += new System.EventHandler(this.button4_Click);
|
||||||
|
//
|
||||||
|
// button3
|
||||||
|
//
|
||||||
|
this.button3.Location = new System.Drawing.Point(26, 286);
|
||||||
|
this.button3.Margin = new System.Windows.Forms.Padding(2, 2, 2, 2);
|
||||||
|
this.button3.Name = "button3";
|
||||||
|
this.button3.Size = new System.Drawing.Size(56, 19);
|
||||||
|
this.button3.TabIndex = 24;
|
||||||
|
this.button3.Text = "Redeem";
|
||||||
|
this.button3.UseVisualStyleBackColor = true;
|
||||||
|
this.button3.Click += new System.EventHandler(this.button3_Click);
|
||||||
|
//
|
||||||
|
// button2
|
||||||
|
//
|
||||||
|
this.button2.Location = new System.Drawing.Point(26, 171);
|
||||||
|
this.button2.Margin = new System.Windows.Forms.Padding(2, 2, 2, 2);
|
||||||
|
this.button2.Name = "button2";
|
||||||
|
this.button2.Size = new System.Drawing.Size(56, 19);
|
||||||
|
this.button2.TabIndex = 23;
|
||||||
|
this.button2.Text = "Loot";
|
||||||
|
this.button2.UseVisualStyleBackColor = true;
|
||||||
|
this.button2.Click += new System.EventHandler(this.button2_Click);
|
||||||
|
//
|
||||||
|
// button1
|
||||||
|
//
|
||||||
|
this.button1.Location = new System.Drawing.Point(169, 130);
|
||||||
|
this.button1.Margin = new System.Windows.Forms.Padding(2, 2, 2, 2);
|
||||||
|
this.button1.Name = "button1";
|
||||||
|
this.button1.Size = new System.Drawing.Size(56, 19);
|
||||||
|
this.button1.TabIndex = 22;
|
||||||
|
this.button1.Text = "Send";
|
||||||
|
this.button1.UseVisualStyleBackColor = true;
|
||||||
|
this.button1.Click += new System.EventHandler(this.button1_Click);
|
||||||
|
//
|
||||||
|
// label2
|
||||||
|
//
|
||||||
|
this.label2.AutoSize = true;
|
||||||
|
this.label2.Location = new System.Drawing.Point(579, 13);
|
||||||
|
this.label2.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0);
|
||||||
|
this.label2.Name = "label2";
|
||||||
|
this.label2.Size = new System.Drawing.Size(39, 13);
|
||||||
|
this.label2.TabIndex = 21;
|
||||||
|
this.label2.Text = "Output";
|
||||||
|
//
|
||||||
|
// label1
|
||||||
|
//
|
||||||
|
this.label1.AutoSize = true;
|
||||||
|
this.label1.Location = new System.Drawing.Point(258, 39);
|
||||||
|
this.label1.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0);
|
||||||
|
this.label1.Name = "label1";
|
||||||
|
this.label1.Size = new System.Drawing.Size(31, 13);
|
||||||
|
this.label1.TabIndex = 20;
|
||||||
|
this.label1.Text = "Input";
|
||||||
|
//
|
||||||
|
// textBox2
|
||||||
|
//
|
||||||
|
this.textBox2.Location = new System.Drawing.Point(413, 34);
|
||||||
|
this.textBox2.Margin = new System.Windows.Forms.Padding(2, 2, 2, 2);
|
||||||
|
this.textBox2.Multiline = true;
|
||||||
|
this.textBox2.Name = "textBox2";
|
||||||
|
this.textBox2.ReadOnly = true;
|
||||||
|
this.textBox2.ScrollBars = System.Windows.Forms.ScrollBars.Vertical;
|
||||||
|
this.textBox2.Size = new System.Drawing.Size(432, 370);
|
||||||
|
this.textBox2.TabIndex = 19;
|
||||||
|
//
|
||||||
|
// textBox1
|
||||||
|
//
|
||||||
|
this.textBox1.Location = new System.Drawing.Point(169, 61);
|
||||||
|
this.textBox1.Margin = new System.Windows.Forms.Padding(2, 2, 2, 2);
|
||||||
|
this.textBox1.Multiline = true;
|
||||||
|
this.textBox1.Name = "textBox1";
|
||||||
|
this.textBox1.Size = new System.Drawing.Size(223, 65);
|
||||||
|
this.textBox1.TabIndex = 18;
|
||||||
|
//
|
||||||
|
// comboBox1
|
||||||
|
//
|
||||||
|
this.comboBox1.FormattingEnabled = true;
|
||||||
|
this.comboBox1.Location = new System.Drawing.Point(26, 116);
|
||||||
|
this.comboBox1.Margin = new System.Windows.Forms.Padding(2, 2, 2, 2);
|
||||||
|
this.comboBox1.Name = "comboBox1";
|
||||||
|
this.comboBox1.Size = new System.Drawing.Size(92, 21);
|
||||||
|
this.comboBox1.TabIndex = 17;
|
||||||
|
this.comboBox1.SelectedIndexChanged += new System.EventHandler(this.comboBox1_SelectedIndexChanged);
|
||||||
|
//
|
||||||
|
// checkBox3
|
||||||
|
//
|
||||||
|
this.checkBox3.AutoSize = true;
|
||||||
|
this.checkBox3.Location = new System.Drawing.Point(26, 94);
|
||||||
|
this.checkBox3.Margin = new System.Windows.Forms.Padding(2, 2, 2, 2);
|
||||||
|
this.checkBox3.Name = "checkBox3";
|
||||||
|
this.checkBox3.Size = new System.Drawing.Size(102, 17);
|
||||||
|
this.checkBox3.TabIndex = 16;
|
||||||
|
this.checkBox3.Text = "Send to specific";
|
||||||
|
this.checkBox3.UseVisualStyleBackColor = true;
|
||||||
|
this.checkBox3.CheckedChanged += new System.EventHandler(this.checkBox3_CheckedChanged);
|
||||||
|
//
|
||||||
|
// checkBox2
|
||||||
|
//
|
||||||
|
this.checkBox2.AutoSize = true;
|
||||||
|
this.checkBox2.Location = new System.Drawing.Point(26, 72);
|
||||||
|
this.checkBox2.Margin = new System.Windows.Forms.Padding(2, 2, 2, 2);
|
||||||
|
this.checkBox2.Name = "checkBox2";
|
||||||
|
this.checkBox2.Size = new System.Drawing.Size(100, 17);
|
||||||
|
this.checkBox2.TabIndex = 15;
|
||||||
|
this.checkBox2.Text = "Send to all Bots";
|
||||||
|
this.checkBox2.UseVisualStyleBackColor = true;
|
||||||
|
this.checkBox2.CheckedChanged += new System.EventHandler(this.checkBox2_CheckedChanged);
|
||||||
|
//
|
||||||
|
// checkBox1
|
||||||
|
//
|
||||||
|
this.checkBox1.AutoSize = true;
|
||||||
|
this.checkBox1.Location = new System.Drawing.Point(107, 11);
|
||||||
|
this.checkBox1.Margin = new System.Windows.Forms.Padding(2, 2, 2, 2);
|
||||||
|
this.checkBox1.Name = "checkBox1";
|
||||||
|
this.checkBox1.Size = new System.Drawing.Size(74, 17);
|
||||||
|
this.checkBox1.TabIndex = 14;
|
||||||
|
this.checkBox1.Text = "Safemode";
|
||||||
|
this.checkBox1.UseVisualStyleBackColor = true;
|
||||||
|
this.checkBox1.CheckedChanged += new System.EventHandler(this.checkBox1_CheckedChanged);
|
||||||
|
//
|
||||||
|
// textBox3
|
||||||
|
//
|
||||||
|
this.textBox3.Location = new System.Drawing.Point(26, 387);
|
||||||
|
this.textBox3.Margin = new System.Windows.Forms.Padding(2, 2, 2, 2);
|
||||||
|
this.textBox3.Name = "textBox3";
|
||||||
|
this.textBox3.Size = new System.Drawing.Size(366, 20);
|
||||||
|
this.textBox3.TabIndex = 28;
|
||||||
|
this.textBox3.TextChanged += new System.EventHandler(this.textBox3_TextChanged);
|
||||||
|
//
|
||||||
|
// ASFGUI
|
||||||
|
//
|
||||||
|
this.ASFGUI.Text = "notifyIcon1";
|
||||||
|
this.ASFGUI.Visible = true;
|
||||||
|
this.ASFGUI.MouseDoubleClick += new System.Windows.Forms.MouseEventHandler(this.ASFGUI_MouseDoubleClick);
|
||||||
|
//
|
||||||
|
// checkBox4
|
||||||
|
//
|
||||||
|
this.checkBox4.AutoSize = true;
|
||||||
|
this.checkBox4.Location = new System.Drawing.Point(26, 11);
|
||||||
|
this.checkBox4.Margin = new System.Windows.Forms.Padding(2, 2, 2, 2);
|
||||||
|
this.checkBox4.Name = "checkBox4";
|
||||||
|
this.checkBox4.Size = new System.Drawing.Size(83, 17);
|
||||||
|
this.checkBox4.TabIndex = 29;
|
||||||
|
this.checkBox4.Text = "Send to any";
|
||||||
|
this.checkBox4.UseVisualStyleBackColor = true;
|
||||||
|
this.checkBox4.CheckedChanged += new System.EventHandler(this.checkBox4_CheckedChanged);
|
||||||
|
//
|
||||||
|
// button6
|
||||||
|
//
|
||||||
|
this.button6.Location = new System.Drawing.Point(26, 41);
|
||||||
|
this.button6.Margin = new System.Windows.Forms.Padding(2, 2, 2, 2);
|
||||||
|
this.button6.Name = "button6";
|
||||||
|
this.button6.Size = new System.Drawing.Size(94, 27);
|
||||||
|
this.button6.TabIndex = 30;
|
||||||
|
this.button6.Text = "generate Botlist";
|
||||||
|
this.button6.UseVisualStyleBackColor = true;
|
||||||
|
this.button6.Click += new System.EventHandler(this.button6_Click);
|
||||||
|
//
|
||||||
|
// button7
|
||||||
|
//
|
||||||
|
this.button7.Location = new System.Drawing.Point(147, 204);
|
||||||
|
this.button7.Margin = new System.Windows.Forms.Padding(2, 2, 2, 2);
|
||||||
|
this.button7.Name = "button7";
|
||||||
|
this.button7.Size = new System.Drawing.Size(56, 19);
|
||||||
|
this.button7.TabIndex = 31;
|
||||||
|
this.button7.Text = "2fano";
|
||||||
|
this.button7.UseVisualStyleBackColor = true;
|
||||||
|
this.button7.Click += new System.EventHandler(this.button7_Click);
|
||||||
|
//
|
||||||
|
// button8
|
||||||
|
//
|
||||||
|
this.button8.Location = new System.Drawing.Point(87, 286);
|
||||||
|
this.button8.Margin = new System.Windows.Forms.Padding(2, 2, 2, 2);
|
||||||
|
this.button8.Name = "button8";
|
||||||
|
this.button8.Size = new System.Drawing.Size(56, 19);
|
||||||
|
this.button8.TabIndex = 32;
|
||||||
|
this.button8.Text = "2faoff";
|
||||||
|
this.button8.UseVisualStyleBackColor = true;
|
||||||
|
this.button8.Click += new System.EventHandler(this.button8_Click);
|
||||||
|
//
|
||||||
|
// button9
|
||||||
|
//
|
||||||
|
this.button9.Location = new System.Drawing.Point(148, 286);
|
||||||
|
this.button9.Margin = new System.Windows.Forms.Padding(2, 2, 2, 2);
|
||||||
|
this.button9.Name = "button9";
|
||||||
|
this.button9.Size = new System.Drawing.Size(56, 19);
|
||||||
|
this.button9.TabIndex = 33;
|
||||||
|
this.button9.Text = "exit";
|
||||||
|
this.button9.UseVisualStyleBackColor = true;
|
||||||
|
this.button9.Click += new System.EventHandler(this.button9_Click);
|
||||||
|
//
|
||||||
|
// button10
|
||||||
|
//
|
||||||
|
this.button10.Location = new System.Drawing.Point(86, 171);
|
||||||
|
this.button10.Margin = new System.Windows.Forms.Padding(2, 2, 2, 2);
|
||||||
|
this.button10.Name = "button10";
|
||||||
|
this.button10.Size = new System.Drawing.Size(56, 19);
|
||||||
|
this.button10.TabIndex = 34;
|
||||||
|
this.button10.Text = "farm";
|
||||||
|
this.button10.UseVisualStyleBackColor = true;
|
||||||
|
this.button10.Click += new System.EventHandler(this.button10_Click);
|
||||||
|
//
|
||||||
|
// button11
|
||||||
|
//
|
||||||
|
this.button11.Location = new System.Drawing.Point(147, 171);
|
||||||
|
this.button11.Margin = new System.Windows.Forms.Padding(2, 2, 2, 2);
|
||||||
|
this.button11.Name = "button11";
|
||||||
|
this.button11.Size = new System.Drawing.Size(56, 19);
|
||||||
|
this.button11.TabIndex = 35;
|
||||||
|
this.button11.Text = "help";
|
||||||
|
this.button11.UseVisualStyleBackColor = true;
|
||||||
|
this.button11.Click += new System.EventHandler(this.button11_Click);
|
||||||
|
//
|
||||||
|
// button12
|
||||||
|
//
|
||||||
|
this.button12.Location = new System.Drawing.Point(208, 171);
|
||||||
|
this.button12.Margin = new System.Windows.Forms.Padding(2, 2, 2, 2);
|
||||||
|
this.button12.Name = "button12";
|
||||||
|
this.button12.Size = new System.Drawing.Size(56, 19);
|
||||||
|
this.button12.TabIndex = 36;
|
||||||
|
this.button12.Text = "start";
|
||||||
|
this.button12.UseVisualStyleBackColor = true;
|
||||||
|
this.button12.Click += new System.EventHandler(this.button12_Click);
|
||||||
|
//
|
||||||
|
// button13
|
||||||
|
//
|
||||||
|
this.button13.Location = new System.Drawing.Point(268, 171);
|
||||||
|
this.button13.Margin = new System.Windows.Forms.Padding(2, 2, 2, 2);
|
||||||
|
this.button13.Name = "button13";
|
||||||
|
this.button13.Size = new System.Drawing.Size(56, 19);
|
||||||
|
this.button13.TabIndex = 37;
|
||||||
|
this.button13.Text = "stop";
|
||||||
|
this.button13.UseVisualStyleBackColor = true;
|
||||||
|
this.button13.Click += new System.EventHandler(this.button13_Click);
|
||||||
|
//
|
||||||
|
// button14
|
||||||
|
//
|
||||||
|
this.button14.Location = new System.Drawing.Point(329, 171);
|
||||||
|
this.button14.Margin = new System.Windows.Forms.Padding(2, 2, 2, 2);
|
||||||
|
this.button14.Name = "button14";
|
||||||
|
this.button14.Size = new System.Drawing.Size(56, 19);
|
||||||
|
this.button14.TabIndex = 38;
|
||||||
|
this.button14.Text = "pause";
|
||||||
|
this.button14.UseVisualStyleBackColor = true;
|
||||||
|
this.button14.Click += new System.EventHandler(this.button14_Click);
|
||||||
|
//
|
||||||
|
// button15
|
||||||
|
//
|
||||||
|
this.button15.Location = new System.Drawing.Point(268, 204);
|
||||||
|
this.button15.Margin = new System.Windows.Forms.Padding(2, 2, 2, 2);
|
||||||
|
this.button15.Name = "button15";
|
||||||
|
this.button15.Size = new System.Drawing.Size(56, 19);
|
||||||
|
this.button15.TabIndex = 39;
|
||||||
|
this.button15.Text = "status";
|
||||||
|
this.button15.UseVisualStyleBackColor = true;
|
||||||
|
this.button15.Click += new System.EventHandler(this.button15_Click);
|
||||||
|
//
|
||||||
|
// button16
|
||||||
|
//
|
||||||
|
this.button16.Location = new System.Drawing.Point(329, 204);
|
||||||
|
this.button16.Margin = new System.Windows.Forms.Padding(2, 2, 2, 2);
|
||||||
|
this.button16.Name = "button16";
|
||||||
|
this.button16.Size = new System.Drawing.Size(56, 19);
|
||||||
|
this.button16.TabIndex = 40;
|
||||||
|
this.button16.Text = "status all";
|
||||||
|
this.button16.UseVisualStyleBackColor = true;
|
||||||
|
this.button16.Click += new System.EventHandler(this.button16_Click);
|
||||||
|
//
|
||||||
|
// button17
|
||||||
|
//
|
||||||
|
this.button17.Location = new System.Drawing.Point(26, 318);
|
||||||
|
this.button17.Margin = new System.Windows.Forms.Padding(2, 2, 2, 2);
|
||||||
|
this.button17.Name = "button17";
|
||||||
|
this.button17.Size = new System.Drawing.Size(56, 19);
|
||||||
|
this.button17.TabIndex = 41;
|
||||||
|
this.button17.Text = "owns";
|
||||||
|
this.button17.UseVisualStyleBackColor = true;
|
||||||
|
this.button17.Click += new System.EventHandler(this.button17_Click);
|
||||||
|
//
|
||||||
|
// button18
|
||||||
|
//
|
||||||
|
this.button18.Location = new System.Drawing.Point(147, 318);
|
||||||
|
this.button18.Margin = new System.Windows.Forms.Padding(2, 2, 2, 2);
|
||||||
|
this.button18.Name = "button18";
|
||||||
|
this.button18.Size = new System.Drawing.Size(56, 19);
|
||||||
|
this.button18.TabIndex = 42;
|
||||||
|
this.button18.Text = "addlicense";
|
||||||
|
this.button18.UseVisualStyleBackColor = true;
|
||||||
|
this.button18.Click += new System.EventHandler(this.button18_Click);
|
||||||
|
//
|
||||||
|
// button19
|
||||||
|
//
|
||||||
|
this.button19.Location = new System.Drawing.Point(87, 318);
|
||||||
|
this.button19.Margin = new System.Windows.Forms.Padding(2, 2, 2, 2);
|
||||||
|
this.button19.Name = "button19";
|
||||||
|
this.button19.Size = new System.Drawing.Size(56, 19);
|
||||||
|
this.button19.TabIndex = 43;
|
||||||
|
this.button19.Text = "play";
|
||||||
|
this.button19.UseVisualStyleBackColor = true;
|
||||||
|
this.button19.Click += new System.EventHandler(this.button19_Click);
|
||||||
|
//
|
||||||
|
// label3
|
||||||
|
//
|
||||||
|
this.label3.AutoSize = true;
|
||||||
|
this.label3.Location = new System.Drawing.Point(24, 245);
|
||||||
|
this.label3.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0);
|
||||||
|
this.label3.Name = "label3";
|
||||||
|
this.label3.Size = new System.Drawing.Size(235, 13);
|
||||||
|
this.label3.TabIndex = 44;
|
||||||
|
this.label3.Text = "The following do not work with \"Send to all\" and";
|
||||||
|
//
|
||||||
|
// label4
|
||||||
|
//
|
||||||
|
this.label4.AutoSize = true;
|
||||||
|
this.label4.Location = new System.Drawing.Point(24, 259);
|
||||||
|
this.label4.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0);
|
||||||
|
this.label4.Name = "label4";
|
||||||
|
this.label4.Size = new System.Drawing.Size(224, 13);
|
||||||
|
this.label4.TabIndex = 45;
|
||||||
|
this.label4.Text = "require confirmation even without \"Safemode\"";
|
||||||
|
//
|
||||||
|
// button20
|
||||||
|
//
|
||||||
|
this.button20.Location = new System.Drawing.Point(231, 130);
|
||||||
|
this.button20.Margin = new System.Windows.Forms.Padding(2, 2, 2, 2);
|
||||||
|
this.button20.Name = "button20";
|
||||||
|
this.button20.Size = new System.Drawing.Size(56, 19);
|
||||||
|
this.button20.TabIndex = 46;
|
||||||
|
this.button20.Text = "clear";
|
||||||
|
this.button20.UseVisualStyleBackColor = true;
|
||||||
|
this.button20.Click += new System.EventHandler(this.button20_Click);
|
||||||
|
//
|
||||||
|
// label5
|
||||||
|
//
|
||||||
|
this.label5.AutoSize = true;
|
||||||
|
this.label5.Location = new System.Drawing.Point(29, 370);
|
||||||
|
this.label5.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0);
|
||||||
|
this.label5.Name = "label5";
|
||||||
|
this.label5.Size = new System.Drawing.Size(221, 13);
|
||||||
|
this.label5.TabIndex = 47;
|
||||||
|
this.label5.Text = "If you don\'t know what this is... Don\'t touch it!";
|
||||||
|
//
|
||||||
|
// Form1
|
||||||
|
//
|
||||||
|
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||||
|
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||||
|
this.ClientSize = new System.Drawing.Size(854, 414);
|
||||||
|
this.Controls.Add(this.label5);
|
||||||
|
this.Controls.Add(this.button20);
|
||||||
|
this.Controls.Add(this.label4);
|
||||||
|
this.Controls.Add(this.label3);
|
||||||
|
this.Controls.Add(this.button19);
|
||||||
|
this.Controls.Add(this.button18);
|
||||||
|
this.Controls.Add(this.button17);
|
||||||
|
this.Controls.Add(this.button16);
|
||||||
|
this.Controls.Add(this.button15);
|
||||||
|
this.Controls.Add(this.button14);
|
||||||
|
this.Controls.Add(this.button13);
|
||||||
|
this.Controls.Add(this.button12);
|
||||||
|
this.Controls.Add(this.button11);
|
||||||
|
this.Controls.Add(this.button10);
|
||||||
|
this.Controls.Add(this.button9);
|
||||||
|
this.Controls.Add(this.button8);
|
||||||
|
this.Controls.Add(this.button7);
|
||||||
|
this.Controls.Add(this.button6);
|
||||||
|
this.Controls.Add(this.checkBox4);
|
||||||
|
this.Controls.Add(this.textBox3);
|
||||||
|
this.Controls.Add(this.button5);
|
||||||
|
this.Controls.Add(this.button4);
|
||||||
|
this.Controls.Add(this.button3);
|
||||||
|
this.Controls.Add(this.button2);
|
||||||
|
this.Controls.Add(this.button1);
|
||||||
|
this.Controls.Add(this.label2);
|
||||||
|
this.Controls.Add(this.label1);
|
||||||
|
this.Controls.Add(this.textBox2);
|
||||||
|
this.Controls.Add(this.textBox1);
|
||||||
|
this.Controls.Add(this.comboBox1);
|
||||||
|
this.Controls.Add(this.checkBox3);
|
||||||
|
this.Controls.Add(this.checkBox2);
|
||||||
|
this.Controls.Add(this.checkBox1);
|
||||||
|
this.Icon = ((System.Drawing.Icon) (resources.GetObject("$this.Icon")));
|
||||||
|
this.Margin = new System.Windows.Forms.Padding(2, 2, 2, 2);
|
||||||
|
this.Name = "Form1";
|
||||||
|
this.Text = "Form1";
|
||||||
|
this.Load += new System.EventHandler(this.Form1_Load);
|
||||||
|
this.ResumeLayout(false);
|
||||||
|
this.PerformLayout();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
private System.Windows.Forms.Button button5;
|
||||||
|
private System.Windows.Forms.Button button4;
|
||||||
|
private System.Windows.Forms.Button button3;
|
||||||
|
private System.Windows.Forms.Button button2;
|
||||||
|
private System.Windows.Forms.Button button1;
|
||||||
|
private System.Windows.Forms.Label label2;
|
||||||
|
private System.Windows.Forms.Label label1;
|
||||||
|
private System.Windows.Forms.TextBox textBox2;
|
||||||
|
private System.Windows.Forms.TextBox textBox1;
|
||||||
|
private System.Windows.Forms.ComboBox comboBox1;
|
||||||
|
private System.Windows.Forms.CheckBox checkBox3;
|
||||||
|
private System.Windows.Forms.CheckBox checkBox2;
|
||||||
|
private System.Windows.Forms.CheckBox checkBox1;
|
||||||
|
private System.Windows.Forms.TextBox textBox3;
|
||||||
|
private System.Windows.Forms.NotifyIcon ASFGUI;
|
||||||
|
private System.Windows.Forms.CheckBox checkBox4;
|
||||||
|
private System.Windows.Forms.Button button6;
|
||||||
|
private System.Windows.Forms.Button button7;
|
||||||
|
private System.Windows.Forms.Button button8;
|
||||||
|
private System.Windows.Forms.Button button9;
|
||||||
|
private System.Windows.Forms.Button button10;
|
||||||
|
private System.Windows.Forms.Button button11;
|
||||||
|
private System.Windows.Forms.Button button12;
|
||||||
|
private System.Windows.Forms.Button button13;
|
||||||
|
private System.Windows.Forms.Button button14;
|
||||||
|
private System.Windows.Forms.Button button15;
|
||||||
|
private System.Windows.Forms.Button button16;
|
||||||
|
private System.Windows.Forms.Button button17;
|
||||||
|
private System.Windows.Forms.Button button18;
|
||||||
|
private System.Windows.Forms.Button button19;
|
||||||
|
private System.Windows.Forms.Label label3;
|
||||||
|
private System.Windows.Forms.Label label4;
|
||||||
|
private System.Windows.Forms.Button button20;
|
||||||
|
private System.Windows.Forms.Label label5;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
310
GUI/Form1.cs
Normal file
310
GUI/Form1.cs
Normal file
@@ -0,0 +1,310 @@
|
|||||||
|
/*
|
||||||
|
_ _ _ ____ _ _____
|
||||||
|
/ \ _ __ ___ | |__ (_)/ ___| | |_ ___ __ _ _ __ ___ | ___|__ _ _ __ _ __ ___
|
||||||
|
/ _ \ | '__|/ __|| '_ \ | |\___ \ | __|/ _ \ / _` || '_ ` _ \ | |_ / _` || '__|| '_ ` _ \
|
||||||
|
/ ___ \ | | | (__ | | | || | ___) || |_| __/| (_| || | | | | || _|| (_| || | | | | | | |
|
||||||
|
/_/ \_\|_| \___||_| |_||_||____/ \__|\___| \__,_||_| |_| |_||_| \__,_||_| |_| |_| |_|
|
||||||
|
|
||||||
|
Copyright 2015-2016 Florian "KlappPC" Lang
|
||||||
|
Contact: ichhoeremusik@gmx.net
|
||||||
|
|
||||||
|
Copyright 2015-2016 Łukasz "JustArchi" Domeradzki
|
||||||
|
Contact: JustArchi@JustArchi.net
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Windows.Forms;
|
||||||
|
using System.ServiceModel;
|
||||||
|
using System.IO;
|
||||||
|
|
||||||
|
namespace GUI {
|
||||||
|
|
||||||
|
public partial class Form1 : Form {
|
||||||
|
private bool safeMode = false;
|
||||||
|
private bool sendAll = false;
|
||||||
|
private bool sendAny = true;
|
||||||
|
private bool sendOne = false;
|
||||||
|
private string botName = "";
|
||||||
|
string[] botList;
|
||||||
|
private string URL = "";
|
||||||
|
ServerProcess proc;
|
||||||
|
private Client Client;
|
||||||
|
public Form1() {
|
||||||
|
InitializeComponent();
|
||||||
|
|
||||||
|
// So either the ASF.exe is in the same directory, or we assume development environment.
|
||||||
|
string ASF = "ASF.exe";
|
||||||
|
if (!File.Exists(ASF)) {
|
||||||
|
ASF = "../../../ArchiSteamFarm/bin/" + (Debugging.IsDebugBuild ? "Debug" : "Release") + "/ArchiSteamFarm.exe";
|
||||||
|
if (!File.Exists(ASF)) {
|
||||||
|
Logging.LogGenericError("ASF binary could not be found!");
|
||||||
|
Environment.Exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
proc = new ServerProcess(ASF, "--server", textBox2);
|
||||||
|
proc.Start();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected override void OnFormClosing(FormClosingEventArgs e) {
|
||||||
|
proc.Stop();
|
||||||
|
base.OnFormClosing(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends a single command. can be lead by a ! but it does not have to.
|
||||||
|
*/
|
||||||
|
private string sendCommand(string command) {
|
||||||
|
if (command.StartsWith("!")) {
|
||||||
|
command = command.Substring(1);
|
||||||
|
}
|
||||||
|
if (Client == null) {
|
||||||
|
Client = new Client(new BasicHttpBinding(), new EndpointAddress(URL));
|
||||||
|
}
|
||||||
|
return Client.HandleCommand(command);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Maximize again when double clicked on tray icon
|
||||||
|
*/
|
||||||
|
private void ASFGUI_MouseDoubleClick(object sender, MouseEventArgs e) {
|
||||||
|
this.Show();
|
||||||
|
this.WindowState = FormWindowState.Normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Form1_Load(object sender, System.EventArgs e) {
|
||||||
|
this.Resize += new System.EventHandler(this.Form1_Resize);
|
||||||
|
textBox2.ScrollBars = ScrollBars.Vertical;
|
||||||
|
textBox1.ScrollBars = ScrollBars.Vertical;
|
||||||
|
checkBox4.Checked = true;
|
||||||
|
textBox3.Text = "http://localhost:1242/ASF";
|
||||||
|
URL = "http://localhost:1242/ASF";
|
||||||
|
textBox2.Anchor = (AnchorStyles.Right | AnchorStyles.Left);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Minimize to tray instead of taskbar
|
||||||
|
*/
|
||||||
|
private void Form1_Resize(object sender, EventArgs e) {
|
||||||
|
if (FormWindowState.Minimized == this.WindowState) {
|
||||||
|
ASFGUI.Visible = true;
|
||||||
|
this.Hide();
|
||||||
|
} else if (FormWindowState.Normal == this.WindowState) {
|
||||||
|
ASFGUI.Visible = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* generate a command from a simple command
|
||||||
|
* That means, adds a botName or makes multiple commands for multiple bots.
|
||||||
|
*/
|
||||||
|
private string generateCommand(string command, string arg = "") {
|
||||||
|
if (sendOne)
|
||||||
|
return command + " " + botName + " " + arg;
|
||||||
|
if (sendAll) {
|
||||||
|
string ret = "";
|
||||||
|
foreach (string str in botList) {
|
||||||
|
ret = ret + command + " " + str + " " + arg + "\r\n";
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
return command + arg;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* One of the simple buttons got pressed
|
||||||
|
*/
|
||||||
|
private void buttonPressed(string command) {
|
||||||
|
textBox1.Text = generateCommand(command);
|
||||||
|
if (!safeMode)
|
||||||
|
button1_Click(this, null);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* One of the complicated buttons was pressed
|
||||||
|
* We get an argumentlist
|
||||||
|
*/
|
||||||
|
private void multiCommand(string command) {
|
||||||
|
if (sendAll)
|
||||||
|
return;
|
||||||
|
string[] arr = textBox1.Lines;
|
||||||
|
string cmd = "";
|
||||||
|
for (int i = 0; i < arr.Length; i++) {
|
||||||
|
if (!String.IsNullOrEmpty(arr[i].Trim())) {
|
||||||
|
cmd = cmd + generateCommand(command, arr[i].Trim()) + "\r\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
textBox1.Text = cmd;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* updates the WCF URL in case of custom URL
|
||||||
|
*/
|
||||||
|
private void textBox3_TextChanged(object sender, EventArgs e) {
|
||||||
|
URL = textBox3.Text;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e) {
|
||||||
|
botName = comboBox1.SelectedItem.ToString();
|
||||||
|
}
|
||||||
|
//Ok, radiobuttons would have been better I guess, to lazy to change now.
|
||||||
|
private void checkBox3_CheckedChanged(object sender, EventArgs e) {
|
||||||
|
//specific
|
||||||
|
if (checkBox3.Checked) {
|
||||||
|
sendAll = false;
|
||||||
|
sendAny = false;
|
||||||
|
sendOne = true;
|
||||||
|
checkBox2.Checked = false;
|
||||||
|
checkBox4.Checked = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkBox2_CheckedChanged(object sender, EventArgs e) {
|
||||||
|
//all
|
||||||
|
if (checkBox2.Checked) {
|
||||||
|
sendAll = true;
|
||||||
|
sendAny = false;
|
||||||
|
sendOne = false;
|
||||||
|
checkBox3.Checked = false;
|
||||||
|
checkBox4.Checked = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkBox4_CheckedChanged(object sender, EventArgs e) {
|
||||||
|
//any
|
||||||
|
if (checkBox4.Checked) {
|
||||||
|
sendAll = false;
|
||||||
|
sendAny = true;
|
||||||
|
sendOne = false;
|
||||||
|
checkBox2.Checked = false;
|
||||||
|
checkBox3.Checked = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkBox1_CheckedChanged(object sender, EventArgs e) {
|
||||||
|
safeMode = checkBox1.Checked;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send command button.
|
||||||
|
*/
|
||||||
|
private void button1_Click(object sender, System.EventArgs e) {
|
||||||
|
for (int i = 0; i < textBox1.Lines.Length; i++) {
|
||||||
|
string command = textBox1.Lines[i];
|
||||||
|
if (!String.IsNullOrEmpty(command.Trim())) {
|
||||||
|
sendCommand(command);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Update /Generate Botlist button
|
||||||
|
*/
|
||||||
|
private void button6_Click(object sender, EventArgs e) {
|
||||||
|
string ret = sendCommand("statusall");
|
||||||
|
string[] arr = ret.Split('\n');
|
||||||
|
int botAmount = Convert.ToInt16(arr[arr.Length - 1].Split('/')[1].Trim().Split(' ')[0]);
|
||||||
|
botList = new string[botAmount];
|
||||||
|
for (int i = 0; i < botAmount; i++) {
|
||||||
|
botList[i] = arr[arr.Length - 2 - i].Substring(3).Trim().Split(' ')[0];
|
||||||
|
}
|
||||||
|
comboBox1.Items.AddRange(botList);
|
||||||
|
}
|
||||||
|
|
||||||
|
//The Rest are simple buttons.
|
||||||
|
private void button3_Click(object sender, EventArgs e) {
|
||||||
|
multiCommand("redeem");
|
||||||
|
}
|
||||||
|
private void button2_Click(object sender, EventArgs e) {
|
||||||
|
textBox1.Text = generateCommand("loot");
|
||||||
|
if (!safeMode)
|
||||||
|
button1_Click(this, null);
|
||||||
|
}
|
||||||
|
private void button4_Click(object sender, EventArgs e) {
|
||||||
|
//2fa
|
||||||
|
textBox1.Text = generateCommand("2fa");
|
||||||
|
if (!safeMode)
|
||||||
|
button1_Click(this, null);
|
||||||
|
}
|
||||||
|
private void button5_Click(object sender, EventArgs e) {
|
||||||
|
buttonPressed("2faok");
|
||||||
|
}
|
||||||
|
private void button7_Click(object sender, EventArgs e) {
|
||||||
|
buttonPressed("2fano");
|
||||||
|
}
|
||||||
|
private void button8_Click(object sender, EventArgs e) {
|
||||||
|
if (sendAll)
|
||||||
|
return;
|
||||||
|
textBox1.Text = generateCommand("2faoff");
|
||||||
|
}
|
||||||
|
private void button9_Click(object sender, EventArgs e) {
|
||||||
|
textBox1.Text = "exit";
|
||||||
|
}
|
||||||
|
private void button10_Click(object sender, EventArgs e) {
|
||||||
|
buttonPressed("farm");
|
||||||
|
}
|
||||||
|
private void button11_Click(object sender, EventArgs e) {
|
||||||
|
buttonPressed("help");
|
||||||
|
}
|
||||||
|
private void button12_Click(object sender, EventArgs e) {
|
||||||
|
buttonPressed("start");
|
||||||
|
}
|
||||||
|
private void button13_Click(object sender, EventArgs e) {
|
||||||
|
buttonPressed("stop");
|
||||||
|
}
|
||||||
|
private void button14_Click(object sender, EventArgs e) {
|
||||||
|
buttonPressed("pause");
|
||||||
|
}
|
||||||
|
private void button15_Click(object sender, EventArgs e) {
|
||||||
|
buttonPressed("status");
|
||||||
|
}
|
||||||
|
private void button16_Click(object sender, EventArgs e) {
|
||||||
|
textBox1.Text = "statusall";
|
||||||
|
if (!safeMode)
|
||||||
|
button1_Click(this, null);
|
||||||
|
}
|
||||||
|
private void button17_Click(object sender, EventArgs e) {
|
||||||
|
multiCommand("owns");
|
||||||
|
}
|
||||||
|
private void button18_Click(object sender, EventArgs e) {
|
||||||
|
multiCommand("addlicense");
|
||||||
|
}
|
||||||
|
private void button19_Click(object sender, EventArgs e) {
|
||||||
|
multiCommand("play");
|
||||||
|
}
|
||||||
|
private void button20_Click(object sender, EventArgs e) {
|
||||||
|
textBox1.Text = "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//############### After this point copied from Archie's WCF ###################
|
||||||
|
[ServiceContract]
|
||||||
|
interface IWCF {
|
||||||
|
[OperationContract]
|
||||||
|
string HandleCommand(string input);
|
||||||
|
}
|
||||||
|
class Client : ClientBase<IWCF>, IWCF {
|
||||||
|
internal Client(System.ServiceModel.Channels.Binding binding, EndpointAddress address) : base(binding, address) { }
|
||||||
|
|
||||||
|
public string HandleCommand(string input) {
|
||||||
|
try {
|
||||||
|
return Channel.HandleCommand(input);
|
||||||
|
} catch (Exception e) {
|
||||||
|
//Logging.LogGenericException(e);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
6296
GUI/Form1.resx
Normal file
6296
GUI/Form1.resx
Normal file
File diff suppressed because it is too large
Load Diff
84
GUI/Form2.Designer.cs
generated
Normal file
84
GUI/Form2.Designer.cs
generated
Normal file
@@ -0,0 +1,84 @@
|
|||||||
|
namespace GUI {
|
||||||
|
partial class Form2 {
|
||||||
|
/// <summary>
|
||||||
|
/// Required designer variable.
|
||||||
|
/// </summary>
|
||||||
|
private System.ComponentModel.IContainer components = null;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Clean up any resources being used.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||||
|
protected override void Dispose(bool disposing) {
|
||||||
|
if (disposing && (components != null)) {
|
||||||
|
components.Dispose();
|
||||||
|
}
|
||||||
|
base.Dispose(disposing);
|
||||||
|
}
|
||||||
|
|
||||||
|
#region Windows Form Designer generated code
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Required method for Designer support - do not modify
|
||||||
|
/// the contents of this method with the code editor.
|
||||||
|
/// </summary>
|
||||||
|
private void InitializeComponent() {
|
||||||
|
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(Form2));
|
||||||
|
this.button1 = new System.Windows.Forms.Button();
|
||||||
|
this.textBox1 = new System.Windows.Forms.TextBox();
|
||||||
|
this.label1 = new System.Windows.Forms.Label();
|
||||||
|
this.SuspendLayout();
|
||||||
|
//
|
||||||
|
// button1
|
||||||
|
//
|
||||||
|
this.button1.Location = new System.Drawing.Point(134, 93);
|
||||||
|
this.button1.Margin = new System.Windows.Forms.Padding(2, 2, 2, 2);
|
||||||
|
this.button1.Name = "button1";
|
||||||
|
this.button1.Size = new System.Drawing.Size(87, 28);
|
||||||
|
this.button1.TabIndex = 0;
|
||||||
|
this.button1.Text = "OK";
|
||||||
|
this.button1.UseVisualStyleBackColor = true;
|
||||||
|
this.button1.Click += new System.EventHandler(this.button1_Click);
|
||||||
|
//
|
||||||
|
// textBox1
|
||||||
|
//
|
||||||
|
this.textBox1.Location = new System.Drawing.Point(12, 63);
|
||||||
|
this.textBox1.Margin = new System.Windows.Forms.Padding(2, 2, 2, 2);
|
||||||
|
this.textBox1.Name = "textBox1";
|
||||||
|
this.textBox1.Size = new System.Drawing.Size(336, 20);
|
||||||
|
this.textBox1.TabIndex = 1;
|
||||||
|
//
|
||||||
|
// label1
|
||||||
|
//
|
||||||
|
this.label1.AutoSize = true;
|
||||||
|
this.label1.Location = new System.Drawing.Point(10, 7);
|
||||||
|
this.label1.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0);
|
||||||
|
this.label1.Name = "label1";
|
||||||
|
this.label1.Size = new System.Drawing.Size(35, 13);
|
||||||
|
this.label1.TabIndex = 2;
|
||||||
|
this.label1.Text = "label1";
|
||||||
|
//
|
||||||
|
// Form2
|
||||||
|
//
|
||||||
|
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||||
|
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||||
|
this.ClientSize = new System.Drawing.Size(356, 132);
|
||||||
|
this.Controls.Add(this.label1);
|
||||||
|
this.Controls.Add(this.textBox1);
|
||||||
|
this.Controls.Add(this.button1);
|
||||||
|
this.Icon = ((System.Drawing.Icon) (resources.GetObject("$this.Icon")));
|
||||||
|
this.Margin = new System.Windows.Forms.Padding(2, 2, 2, 2);
|
||||||
|
this.Name = "Form2";
|
||||||
|
this.Text = "Input";
|
||||||
|
this.ResumeLayout(false);
|
||||||
|
this.PerformLayout();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
private System.Windows.Forms.Button button1;
|
||||||
|
private System.Windows.Forms.TextBox textBox1;
|
||||||
|
private System.Windows.Forms.Label label1;
|
||||||
|
}
|
||||||
|
}
|
||||||
44
GUI/Form2.cs
Normal file
44
GUI/Form2.cs
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
/*
|
||||||
|
_ _ _ ____ _ _____
|
||||||
|
/ \ _ __ ___ | |__ (_)/ ___| | |_ ___ __ _ _ __ ___ | ___|__ _ _ __ _ __ ___
|
||||||
|
/ _ \ | '__|/ __|| '_ \ | |\___ \ | __|/ _ \ / _` || '_ ` _ \ | |_ / _` || '__|| '_ ` _ \
|
||||||
|
/ ___ \ | | | (__ | | | || | ___) || |_| __/| (_| || | | | | || _|| (_| || | | | | | | |
|
||||||
|
/_/ \_\|_| \___||_| |_||_||____/ \__|\___| \__,_||_| |_| |_||_| \__,_||_| |_| |_| |_|
|
||||||
|
|
||||||
|
Copyright 2015-2016 Florian "KlappPC" Lang
|
||||||
|
Contact: ichhoeremusik@gmx.net
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
|
||||||
|
*/
|
||||||
|
using System;
|
||||||
|
using System.Windows.Forms;
|
||||||
|
|
||||||
|
namespace GUI {
|
||||||
|
/**
|
||||||
|
* popup Message when Input is required
|
||||||
|
*/
|
||||||
|
public partial class Form2 : Form {
|
||||||
|
ServerProcess proc;
|
||||||
|
public Form2(ServerProcess proc, string msg) {
|
||||||
|
this.proc = proc;
|
||||||
|
InitializeComponent();
|
||||||
|
label1.Text = msg;
|
||||||
|
button1.DialogResult = DialogResult.OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void button1_Click(object sender, EventArgs e) {
|
||||||
|
proc.Write(textBox1.Text);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
6293
GUI/Form2.resx
Normal file
6293
GUI/Form2.resx
Normal file
File diff suppressed because it is too large
Load Diff
156
GUI/GUI.csproj
Normal file
156
GUI/GUI.csproj
Normal file
@@ -0,0 +1,156 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||||
|
<PropertyGroup>
|
||||||
|
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||||
|
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||||
|
<ProjectGuid>{599121A9-5887-4522-A3D6-61470B90BAD4}</ProjectGuid>
|
||||||
|
<OutputType>WinExe</OutputType>
|
||||||
|
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||||
|
<RootNamespace>GUI</RootNamespace>
|
||||||
|
<AssemblyName>GUI</AssemblyName>
|
||||||
|
<TargetFrameworkVersion>v4.5.1</TargetFrameworkVersion>
|
||||||
|
<FileAlignment>512</FileAlignment>
|
||||||
|
<PublishUrl>publish\</PublishUrl>
|
||||||
|
<Install>true</Install>
|
||||||
|
<InstallFrom>Disk</InstallFrom>
|
||||||
|
<UpdateEnabled>false</UpdateEnabled>
|
||||||
|
<UpdateMode>Foreground</UpdateMode>
|
||||||
|
<UpdateInterval>7</UpdateInterval>
|
||||||
|
<UpdateIntervalUnits>Days</UpdateIntervalUnits>
|
||||||
|
<UpdatePeriodically>false</UpdatePeriodically>
|
||||||
|
<UpdateRequired>false</UpdateRequired>
|
||||||
|
<MapFileExtensions>true</MapFileExtensions>
|
||||||
|
<ApplicationRevision>0</ApplicationRevision>
|
||||||
|
<ApplicationVersion>1.0.0.%2a</ApplicationVersion>
|
||||||
|
<IsWebBootstrapper>false</IsWebBootstrapper>
|
||||||
|
<UseApplicationTrust>false</UseApplicationTrust>
|
||||||
|
<BootstrapperEnabled>true</BootstrapperEnabled>
|
||||||
|
<TargetFrameworkProfile />
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||||
|
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||||
|
<DebugSymbols>true</DebugSymbols>
|
||||||
|
<DebugType>full</DebugType>
|
||||||
|
<Optimize>false</Optimize>
|
||||||
|
<OutputPath>bin\Debug\</OutputPath>
|
||||||
|
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
<WarningLevel>4</WarningLevel>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||||
|
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||||
|
<DebugType>none</DebugType>
|
||||||
|
<Optimize>true</Optimize>
|
||||||
|
<OutputPath>bin\Release\</OutputPath>
|
||||||
|
<DefineConstants>
|
||||||
|
</DefineConstants>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
<WarningLevel>4</WarningLevel>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup>
|
||||||
|
<ApplicationManifest>app.manifest</ApplicationManifest>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup>
|
||||||
|
<ApplicationIcon>cirno.ico</ApplicationIcon>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Reference Include="System" />
|
||||||
|
<Reference Include="System.Core" />
|
||||||
|
<Reference Include="System.ServiceModel" />
|
||||||
|
<Reference Include="System.ServiceModel.Web" />
|
||||||
|
<Reference Include="System.Drawing" />
|
||||||
|
<Reference Include="System.Windows.Forms" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Compile Include="Debugging.cs" />
|
||||||
|
<Compile Include="Form1.cs">
|
||||||
|
<SubType>Form</SubType>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="Form1.Designer.cs">
|
||||||
|
<DependentUpon>Form1.cs</DependentUpon>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="Form2.cs">
|
||||||
|
<SubType>Form</SubType>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="Form2.Designer.cs">
|
||||||
|
<DependentUpon>Form2.cs</DependentUpon>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="Logging.cs" />
|
||||||
|
<Compile Include="Program.cs" />
|
||||||
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
|
<Compile Include="ServerProcess.cs" />
|
||||||
|
<EmbeddedResource Include="Form1.resx">
|
||||||
|
<DependentUpon>Form1.cs</DependentUpon>
|
||||||
|
</EmbeddedResource>
|
||||||
|
<EmbeddedResource Include="Form2.resx">
|
||||||
|
<DependentUpon>Form2.cs</DependentUpon>
|
||||||
|
</EmbeddedResource>
|
||||||
|
<EmbeddedResource Include="Properties\Resources.resx">
|
||||||
|
<Generator>ResXFileCodeGenerator</Generator>
|
||||||
|
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
|
||||||
|
<SubType>Designer</SubType>
|
||||||
|
</EmbeddedResource>
|
||||||
|
<Compile Include="Properties\Resources.Designer.cs">
|
||||||
|
<AutoGen>True</AutoGen>
|
||||||
|
<DependentUpon>Resources.resx</DependentUpon>
|
||||||
|
<DesignTime>True</DesignTime>
|
||||||
|
</Compile>
|
||||||
|
<None Include="app.manifest" />
|
||||||
|
<None Include="Properties\Settings.settings">
|
||||||
|
<Generator>SettingsSingleFileGenerator</Generator>
|
||||||
|
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
|
||||||
|
</None>
|
||||||
|
<Compile Include="Properties\Settings.Designer.cs">
|
||||||
|
<AutoGen>True</AutoGen>
|
||||||
|
<DependentUpon>Settings.settings</DependentUpon>
|
||||||
|
<DesignTimeSharedInput>True</DesignTimeSharedInput>
|
||||||
|
</Compile>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<None Include="App.config" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<WCFMetadata Include="Service References\" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<BootstrapperPackage Include=".NETFramework,Version=v4.5">
|
||||||
|
<Visible>False</Visible>
|
||||||
|
<ProductName>Microsoft .NET Framework 4.5 %28x86 and x64%29</ProductName>
|
||||||
|
<Install>true</Install>
|
||||||
|
</BootstrapperPackage>
|
||||||
|
<BootstrapperPackage Include="Microsoft.Net.Client.3.5">
|
||||||
|
<Visible>False</Visible>
|
||||||
|
<ProductName>.NET Framework 3.5 SP1 Client Profile</ProductName>
|
||||||
|
<Install>false</Install>
|
||||||
|
</BootstrapperPackage>
|
||||||
|
<BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
|
||||||
|
<Visible>False</Visible>
|
||||||
|
<ProductName>.NET Framework 3.5 SP1</ProductName>
|
||||||
|
<Install>false</Install>
|
||||||
|
</BootstrapperPackage>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Content Include="cirno.ico" />
|
||||||
|
</ItemGroup>
|
||||||
|
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||||
|
<PropertyGroup>
|
||||||
|
<!--
|
||||||
|
<PostBuildEvent Condition=" '$(OS)' != 'Unix' AND '$(ConfigurationName)' == 'Release' ">
|
||||||
|
"$(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' ">
|
||||||
|
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>
|
||||||
|
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||||
|
Other similar extension points exist, see Microsoft.Common.targets.
|
||||||
|
<Target Name="BeforeBuild">
|
||||||
|
</Target>
|
||||||
|
<Target Name="AfterBuild">
|
||||||
|
</Target>
|
||||||
|
-->
|
||||||
|
</Project>
|
||||||
93
GUI/Logging.cs
Normal file
93
GUI/Logging.cs
Normal file
@@ -0,0 +1,93 @@
|
|||||||
|
/*
|
||||||
|
_ _ _ ____ _ _____
|
||||||
|
/ \ _ __ ___ | |__ (_)/ ___| | |_ ___ __ _ _ __ ___ | ___|__ _ _ __ _ __ ___
|
||||||
|
/ _ \ | '__|/ __|| '_ \ | |\___ \ | __|/ _ \ / _` || '_ ` _ \ | |_ / _` || '__|| '_ ` _ \
|
||||||
|
/ ___ \ | | | (__ | | | || | ___) || |_| __/| (_| || | | | | || _|| (_| || | | | | | | |
|
||||||
|
/_/ \_\|_| \___||_| |_||_||____/ \__|\___| \__,_||_| |_| |_||_| \__,_||_| |_| |_| |_|
|
||||||
|
|
||||||
|
Copyright 2015-2016 Łukasz "JustArchi" Domeradzki
|
||||||
|
Contact: JustArchi@JustArchi.net
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
using System.Windows.Forms;
|
||||||
|
|
||||||
|
namespace GUI {
|
||||||
|
internal static class Logging {
|
||||||
|
internal static void LogGenericInfo(string message) {
|
||||||
|
if (string.IsNullOrEmpty(message)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
MessageBox.Show(message, "Information", MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static void LogGenericWTF(string message, [CallerMemberName] string previousMethodName = "") {
|
||||||
|
if (string.IsNullOrEmpty(message)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
MessageBox.Show(previousMethodName + "() " + message, "WTF", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static void LogGenericError(string message, [CallerMemberName] string previousMethodName = "") {
|
||||||
|
if (string.IsNullOrEmpty(message)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
MessageBox.Show(previousMethodName + "() " + message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static void LogGenericException(Exception exception, [CallerMemberName] string previousMethodName = "") {
|
||||||
|
if (exception == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
MessageBox.Show(previousMethodName + "() " + exception.Message + Environment.NewLine + exception.StackTrace, "Exception", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
|
|
||||||
|
if (exception.InnerException != null) {
|
||||||
|
LogGenericException(exception.InnerException, previousMethodName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static void LogGenericWarning(string message, [CallerMemberName] string previousMethodName = "") {
|
||||||
|
if (string.IsNullOrEmpty(message)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
MessageBox.Show(previousMethodName + "() " + message, "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static void LogNullError(string nullObjectName, [CallerMemberName] string previousMethodName = "") {
|
||||||
|
if (string.IsNullOrEmpty(nullObjectName)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
LogGenericError(nullObjectName + " is null!", previousMethodName);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Conditional("DEBUG")]
|
||||||
|
internal static void LogGenericDebug(string message, [CallerMemberName] string previousMethodName = "") {
|
||||||
|
if (string.IsNullOrEmpty(message)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
MessageBox.Show(previousMethodName + "() " + message, "Debug", MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
16
GUI/Program.cs
Normal file
16
GUI/Program.cs
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
using System;
|
||||||
|
using System.Windows.Forms;
|
||||||
|
|
||||||
|
namespace GUI {
|
||||||
|
static class Program {
|
||||||
|
/// <summary>
|
||||||
|
/// Der Haupteinstiegspunkt für die Anwendung.
|
||||||
|
/// </summary>
|
||||||
|
[STAThread]
|
||||||
|
static void Main() {
|
||||||
|
Application.EnableVisualStyles();
|
||||||
|
Application.SetCompatibleTextRenderingDefault(false);
|
||||||
|
Application.Run(new Form1());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
36
GUI/Properties/AssemblyInfo.cs
Normal file
36
GUI/Properties/AssemblyInfo.cs
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
using System.Reflection;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
|
// Allgemeine Informationen über eine Assembly werden über die folgenden
|
||||||
|
// Attribute gesteuert. Ändern Sie diese Attributwerte, um die Informationen zu ändern,
|
||||||
|
// die mit einer Assembly verknüpft sind.
|
||||||
|
[assembly: AssemblyTitle("GUI")]
|
||||||
|
[assembly: AssemblyDescription("")]
|
||||||
|
[assembly: AssemblyConfiguration("")]
|
||||||
|
[assembly: AssemblyCompany("")]
|
||||||
|
[assembly: AssemblyProduct("GUI")]
|
||||||
|
[assembly: AssemblyCopyright("Copyright © ArchiSteamFarm 2015-2016")]
|
||||||
|
[assembly: AssemblyTrademark("")]
|
||||||
|
[assembly: AssemblyCulture("")]
|
||||||
|
|
||||||
|
// Durch Festlegen von ComVisible auf "false" werden die Typen in dieser Assembly unsichtbar
|
||||||
|
// für COM-Komponenten. Wenn Sie auf einen Typ in dieser Assembly von
|
||||||
|
// COM zugreifen müssen, legen Sie das ComVisible-Attribut für diesen Typ auf "true" fest.
|
||||||
|
[assembly: ComVisible(false)]
|
||||||
|
|
||||||
|
// Die folgende GUID bestimmt die ID der Typbibliothek, wenn dieses Projekt für COM verfügbar gemacht wird
|
||||||
|
[assembly: Guid("18b85645-1c80-4e25-9dcb-e01684a48fca")]
|
||||||
|
|
||||||
|
// Versionsinformationen für eine Assembly bestehen aus den folgenden vier Werten:
|
||||||
|
//
|
||||||
|
// Hauptversion
|
||||||
|
// Nebenversion
|
||||||
|
// Buildnummer
|
||||||
|
// Revision
|
||||||
|
//
|
||||||
|
// Sie können alle Werte angeben oder die standardmäßigen Build- und Revisionsnummern
|
||||||
|
// übernehmen, indem Sie "*" eingeben:
|
||||||
|
// [assembly: AssemblyVersion("1.0.*")]
|
||||||
|
[assembly: AssemblyVersion("1.0.0.0")]
|
||||||
|
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||||
63
GUI/Properties/Resources.Designer.cs
generated
Normal file
63
GUI/Properties/Resources.Designer.cs
generated
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// <auto-generated>
|
||||||
|
// This code was generated by a tool.
|
||||||
|
// Runtime Version:4.0.30319.42000
|
||||||
|
//
|
||||||
|
// Changes to this file may cause incorrect behavior and will be lost if
|
||||||
|
// the code is regenerated.
|
||||||
|
// </auto-generated>
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
namespace GUI.Properties {
|
||||||
|
using System;
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A strongly-typed resource class, for looking up localized strings, etc.
|
||||||
|
/// </summary>
|
||||||
|
// This class was auto-generated by the StronglyTypedResourceBuilder
|
||||||
|
// class via a tool like ResGen or Visual Studio.
|
||||||
|
// To add or remove a member, edit your .ResX file then rerun ResGen
|
||||||
|
// with the /str option, or rebuild your VS project.
|
||||||
|
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
|
||||||
|
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||||
|
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||||
|
internal class Resources {
|
||||||
|
|
||||||
|
private static global::System.Resources.ResourceManager resourceMan;
|
||||||
|
|
||||||
|
private static global::System.Globalization.CultureInfo resourceCulture;
|
||||||
|
|
||||||
|
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
|
||||||
|
internal Resources() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns the cached ResourceManager instance used by this class.
|
||||||
|
/// </summary>
|
||||||
|
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||||
|
internal static global::System.Resources.ResourceManager ResourceManager {
|
||||||
|
get {
|
||||||
|
if (object.ReferenceEquals(resourceMan, null)) {
|
||||||
|
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("GUI.Properties.Resources", typeof(Resources).Assembly);
|
||||||
|
resourceMan = temp;
|
||||||
|
}
|
||||||
|
return resourceMan;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Overrides the current thread's CurrentUICulture property for all
|
||||||
|
/// resource lookups using this strongly typed resource class.
|
||||||
|
/// </summary>
|
||||||
|
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||||
|
internal static global::System.Globalization.CultureInfo Culture {
|
||||||
|
get {
|
||||||
|
return resourceCulture;
|
||||||
|
}
|
||||||
|
set {
|
||||||
|
resourceCulture = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
117
GUI/Properties/Resources.resx
Normal file
117
GUI/Properties/Resources.resx
Normal file
@@ -0,0 +1,117 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<root>
|
||||||
|
<!--
|
||||||
|
Microsoft ResX Schema
|
||||||
|
|
||||||
|
Version 2.0
|
||||||
|
|
||||||
|
The primary goals of this format is to allow a simple XML format
|
||||||
|
that is mostly human readable. The generation and parsing of the
|
||||||
|
various data types are done through the TypeConverter classes
|
||||||
|
associated with the data types.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
... ado.net/XML headers & schema ...
|
||||||
|
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||||
|
<resheader name="version">2.0</resheader>
|
||||||
|
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||||
|
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||||
|
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||||
|
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||||
|
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||||
|
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
|
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||||
|
<comment>This is a comment</comment>
|
||||||
|
</data>
|
||||||
|
|
||||||
|
There are any number of "resheader" rows that contain simple
|
||||||
|
name/value pairs.
|
||||||
|
|
||||||
|
Each data row contains a name, and value. The row also contains a
|
||||||
|
type or mimetype. Type corresponds to a .NET class that support
|
||||||
|
text/value conversion through the TypeConverter architecture.
|
||||||
|
Classes that don't support this are serialized and stored with the
|
||||||
|
mimetype set.
|
||||||
|
|
||||||
|
The mimetype is used for serialized objects, and tells the
|
||||||
|
ResXResourceReader how to depersist the object. This is currently not
|
||||||
|
extensible. For a given mimetype the value must be set accordingly:
|
||||||
|
|
||||||
|
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||||
|
that the ResXResourceWriter will generate, however the reader can
|
||||||
|
read any of the formats listed below.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.binary.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Serialization.Formatters.Binary.BinaryFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.soap.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||||
|
value : The object must be serialized into a byte array
|
||||||
|
: using a System.ComponentModel.TypeConverter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
-->
|
||||||
|
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||||
|
<xsd:element name="root" msdata:IsDataSet="true">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:choice maxOccurs="unbounded">
|
||||||
|
<xsd:element name="metadata">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="assembly">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:attribute name="alias" type="xsd:string" />
|
||||||
|
<xsd:attribute name="name" type="xsd:string" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="data">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="resheader">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:choice>
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:schema>
|
||||||
|
<resheader name="resmimetype">
|
||||||
|
<value>text/microsoft-resx</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="version">
|
||||||
|
<value>2.0</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="reader">
|
||||||
|
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="writer">
|
||||||
|
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
</root>
|
||||||
26
GUI/Properties/Settings.Designer.cs
generated
Normal file
26
GUI/Properties/Settings.Designer.cs
generated
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// <auto-generated>
|
||||||
|
// This code was generated by a tool.
|
||||||
|
// Runtime Version:4.0.30319.42000
|
||||||
|
//
|
||||||
|
// Changes to this file may cause incorrect behavior and will be lost if
|
||||||
|
// the code is regenerated.
|
||||||
|
// </auto-generated>
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
namespace GUI.Properties {
|
||||||
|
|
||||||
|
|
||||||
|
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||||
|
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "14.0.0.0")]
|
||||||
|
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
|
||||||
|
|
||||||
|
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
|
||||||
|
|
||||||
|
public static Settings Default {
|
||||||
|
get {
|
||||||
|
return defaultInstance;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
7
GUI/Properties/Settings.settings
Normal file
7
GUI/Properties/Settings.settings
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
<?xml version='1.0' encoding='utf-8'?>
|
||||||
|
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)">
|
||||||
|
<Profiles>
|
||||||
|
<Profile Name="(Default)" />
|
||||||
|
</Profiles>
|
||||||
|
<Settings />
|
||||||
|
</SettingsFile>
|
||||||
180
GUI/ServerProcess.cs
Normal file
180
GUI/ServerProcess.cs
Normal file
@@ -0,0 +1,180 @@
|
|||||||
|
/*
|
||||||
|
_ _ _ ____ _ _____
|
||||||
|
/ \ _ __ ___ | |__ (_)/ ___| | |_ ___ __ _ _ __ ___ | ___|__ _ _ __ _ __ ___
|
||||||
|
/ _ \ | '__|/ __|| '_ \ | |\___ \ | __|/ _ \ / _` || '_ ` _ \ | |_ / _` || '__|| '_ ` _ \
|
||||||
|
/ ___ \ | | | (__ | | | || | ___) || |_| __/| (_| || | | | | || _|| (_| || | | | | | | |
|
||||||
|
/_/ \_\|_| \___||_| |_||_||____/ \__|\___| \__,_||_| |_| |_||_| \__,_||_| |_| |_| |_|
|
||||||
|
|
||||||
|
Copyright 2015-2016 Florian "KlappPC" Lang
|
||||||
|
Contact: ichhoeremusik@gmx.net
|
||||||
|
This file is mostly done by a friend who explicitly does not want to get mentioned in any way.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
using System.Threading;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Windows.Forms;
|
||||||
|
|
||||||
|
namespace GUI {
|
||||||
|
/*basically a class to run executables as controlled prozess in the background*/
|
||||||
|
public class ServerProcess {
|
||||||
|
//ASF.exe in our case
|
||||||
|
protected Process process;
|
||||||
|
//handling the output.
|
||||||
|
protected Thread outputThread;
|
||||||
|
protected bool stopping;
|
||||||
|
|
||||||
|
//the textbox from our Form, where we want to display output.
|
||||||
|
private TextBox output;
|
||||||
|
|
||||||
|
private object lockObj = new object();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* New SeverProcess for filename with arguments and output to textBox.
|
||||||
|
* Console is hidden and IO redirected.
|
||||||
|
*/
|
||||||
|
public ServerProcess(string fileName, string argumants, TextBox textBox) {
|
||||||
|
|
||||||
|
|
||||||
|
output = textBox;
|
||||||
|
process = new System.Diagnostics.Process();
|
||||||
|
|
||||||
|
process.StartInfo.FileName = fileName;
|
||||||
|
process.StartInfo.Arguments = argumants;
|
||||||
|
process.StartInfo.UseShellExecute = false;
|
||||||
|
process.StartInfo.RedirectStandardInput = true;
|
||||||
|
process.StartInfo.RedirectStandardError = true;
|
||||||
|
process.StartInfo.RedirectStandardOutput = true;
|
||||||
|
process.StartInfo.CreateNoWindow = true;
|
||||||
|
|
||||||
|
}
|
||||||
|
//needed for realizing when input is needed.
|
||||||
|
private int dotcounter = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* I'm not quite happy with this. I could not figure a way to notice when input is required
|
||||||
|
* besides reading char by char and searching for keywords. Will stop working, if the "Please enter"
|
||||||
|
* lines gets changed.
|
||||||
|
* Only tested for "Enter Password."
|
||||||
|
*/
|
||||||
|
private void NewOutput(object sender, char e) {
|
||||||
|
MethodInvoker mi = delegate {
|
||||||
|
output.AppendText(e.ToString());
|
||||||
|
};
|
||||||
|
|
||||||
|
if (e == '.') {
|
||||||
|
dotcounter++;
|
||||||
|
} else if (e == ':') {
|
||||||
|
dotcounter = 3;
|
||||||
|
} else {
|
||||||
|
dotcounter = 0;
|
||||||
|
}
|
||||||
|
if (dotcounter == 3) {
|
||||||
|
string[] arr = output.Lines;
|
||||||
|
string str = arr[arr.Length - 1];
|
||||||
|
if (str.Contains("Hit enter")) {
|
||||||
|
str = arr[arr.Length - 2] + " | " + str;
|
||||||
|
Form f = new Form2(this, str);
|
||||||
|
f.ShowDialog();
|
||||||
|
mi = delegate { output.AppendText(e.ToString() + "\n"); };
|
||||||
|
}
|
||||||
|
if (str.Contains("Please enter")) {
|
||||||
|
Form f = new Form2(this, str);
|
||||||
|
f.ShowDialog();
|
||||||
|
mi = delegate { output.AppendText(e.ToString() + "\n"); };
|
||||||
|
}
|
||||||
|
|
||||||
|
dotcounter = 0;
|
||||||
|
}
|
||||||
|
output.Invoke(mi);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void NewOutput(object sender, string e) {
|
||||||
|
MethodInvoker mi = delegate {
|
||||||
|
output.AppendText(e + "\n");
|
||||||
|
};
|
||||||
|
output.Invoke(mi);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void printOutPut() {
|
||||||
|
char str;
|
||||||
|
int i;
|
||||||
|
string s;
|
||||||
|
while (!stopping) {
|
||||||
|
//thats ugly, but when using readline we can't catch input.
|
||||||
|
while (((i = process.StandardOutput.Read()) != 0)) {
|
||||||
|
str = System.Convert.ToChar(i);
|
||||||
|
NewOutput(this, str);
|
||||||
|
if (stopping)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (((s = process.StandardError.ReadLine()) != null)) {
|
||||||
|
NewOutput(this, s);
|
||||||
|
if (stopping)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Write(string msg) {
|
||||||
|
process.StandardInput.WriteLine(msg);
|
||||||
|
process.StandardInput.Flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Stop() {
|
||||||
|
Thread stopThread = new Thread(StopProcess);
|
||||||
|
stopThread.Start();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void StopProcess() {
|
||||||
|
|
||||||
|
if (process == null)
|
||||||
|
return;
|
||||||
|
stopping = true;
|
||||||
|
|
||||||
|
outputThread.Abort();
|
||||||
|
|
||||||
|
Thread.Sleep(1000);
|
||||||
|
|
||||||
|
if (process == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (process.HasExited)
|
||||||
|
process.Close();
|
||||||
|
else
|
||||||
|
process.Kill();
|
||||||
|
|
||||||
|
process = null;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* starts the process and a second thread to listen for output.
|
||||||
|
*/
|
||||||
|
public void Start() {
|
||||||
|
outputThread = new Thread(printOutPut);
|
||||||
|
process.Start();
|
||||||
|
outputThread.Start();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Process Process {
|
||||||
|
get {
|
||||||
|
return process;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
58
GUI/app.manifest
Normal file
58
GUI/app.manifest
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<asmv1:assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1" xmlns:asmv1="urn:schemas-microsoft-com:asm.v1" xmlns:asmv2="urn:schemas-microsoft-com:asm.v2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||||
|
<assemblyIdentity version="1.0.0.0" name="MyApplication.app"/>
|
||||||
|
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
|
||||||
|
<security>
|
||||||
|
<requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3">
|
||||||
|
<!-- UAC-Manifestoptionen
|
||||||
|
Wenn Sie die Zugangsebene für das Windows-Benutzerkonto ändern möchten, ersetzen Sie den
|
||||||
|
requestedExecutionLevel-Knoten durch eines der folgenden Elemente.
|
||||||
|
|
||||||
|
<requestedExecutionLevel level="asInvoker" uiAccess="false" />
|
||||||
|
<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
|
||||||
|
<requestedExecutionLevel level="highestAvailable" uiAccess="false" />
|
||||||
|
|
||||||
|
Durch Angeben des requestedExecutionLevel-Knotens wird die Datei- und Registrierungsvirtualisierung deaktiviert.
|
||||||
|
Wenn Sie Datei- und Registrierungsvirtualisierung für Abwärts-
|
||||||
|
kompatibilität verwenden möchten, löschen Sie den requestedExecutionLevel-Knoten.
|
||||||
|
-->
|
||||||
|
<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
|
||||||
|
</requestedPrivileges>
|
||||||
|
</security>
|
||||||
|
</trustInfo>
|
||||||
|
|
||||||
|
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
|
||||||
|
<application>
|
||||||
|
<!-- Eine Liste aller Windows-Versionen, mit denen die Anwendung kompatibel ist.
|
||||||
|
Windows wählt automatisch die am stärksten kompatible Umgebung aus.-->
|
||||||
|
|
||||||
|
<!-- Wenn die Anwendung mit Windows Vista kompatibel ist, heben Sie die Auskommentierung des folgenden supportedOS-Knotens auf-->
|
||||||
|
<!--<supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"></supportedOS>-->
|
||||||
|
|
||||||
|
<!-- Wenn die Anwendung mit Windows 7 kompatibel ist, heben Sie die Kommentierung des folgenden supportedOS-Knotens auf.-->
|
||||||
|
<!--<supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>-->
|
||||||
|
|
||||||
|
<!-- Wenn die Anwendung mit Windows 8 kompatibel ist, heben Sie die Auskommentierung des folgenden supportedOS-Knotens auf-->
|
||||||
|
<!--<supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"></supportedOS>-->
|
||||||
|
|
||||||
|
<!-- Wenn die Anwendung mit Windows 8.1 kompatibel ist, die Kommentierung des folgenden supportedOS-Knotens aufheben.-->
|
||||||
|
<!--<supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>-->
|
||||||
|
|
||||||
|
</application>
|
||||||
|
</compatibility>
|
||||||
|
|
||||||
|
<!-- Designs für allgemeine Windows-Steuerelemente und -Dialogfelder (Windows XP und höher) aktivieren -->
|
||||||
|
<!-- <dependency>
|
||||||
|
<dependentAssembly>
|
||||||
|
<assemblyIdentity
|
||||||
|
type="win32"
|
||||||
|
name="Microsoft.Windows.Common-Controls"
|
||||||
|
version="6.0.0.0"
|
||||||
|
processorArchitecture="*"
|
||||||
|
publicKeyToken="6595b64144ccf1df"
|
||||||
|
language="*"
|
||||||
|
/>
|
||||||
|
</dependentAssembly>
|
||||||
|
</dependency>-->
|
||||||
|
|
||||||
|
</asmv1:assembly>
|
||||||
BIN
GUI/cirno.ico
Normal file
BIN
GUI/cirno.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 361 KiB |
@@ -1,7 +1,12 @@
|
|||||||
ArchiSteamFarm
|
ArchiSteamFarm
|
||||||
===================
|
===================
|
||||||
|
|
||||||
[](https://ci.appveyor.com/project/JustArchi/archisteamfarm) [](https://github.com/JustArchi/ArchiSteamFarm/releases/latest) [](https://github.com/JustArchi/ArchiSteamFarm/releases) [](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=HD2P2P3WGS5Y4) [](https://steamcommunity.com/tradeoffer/new/?partner=46697991&token=0ix2Ruv_)
|
[](https://ci.appveyor.com/project/JustArchi/ArchiSteamFarm)
|
||||||
|
[](https://travis-ci.org/JustArchi/ArchiSteamFarm)
|
||||||
|
[](https://github.com/JustArchi/ArchiSteamFarm/releases/latest)
|
||||||
|
[](https://github.com/JustArchi/ArchiSteamFarm/releases)
|
||||||
|
[](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=HD2P2P3WGS5Y4)
|
||||||
|
[](https://steamcommunity.com/tradeoffer/new/?partner=46697991&token=0ix2Ruv_)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
@@ -8,8 +8,29 @@ namespace SteamAuth
|
|||||||
{
|
{
|
||||||
public class Confirmation
|
public class Confirmation
|
||||||
{
|
{
|
||||||
public string ConfirmationID;
|
public string ID;
|
||||||
public string ConfirmationKey;
|
public string Key;
|
||||||
public string ConfirmationDescription;
|
public string Description;
|
||||||
|
|
||||||
|
public ConfirmationType ConfType
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (String.IsNullOrEmpty(Description)) return ConfirmationType.Unknown;
|
||||||
|
if (Description.StartsWith("Confirm ")) return ConfirmationType.GenericConfirmation;
|
||||||
|
if (Description.StartsWith("Trade with ")) return ConfirmationType.Trade;
|
||||||
|
if (Description.StartsWith("Sell -")) return ConfirmationType.MarketSellTransaction;
|
||||||
|
|
||||||
|
return ConfirmationType.Unknown;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum ConfirmationType
|
||||||
|
{
|
||||||
|
GenericConfirmation,
|
||||||
|
Trade,
|
||||||
|
MarketSellTransaction,
|
||||||
|
Unknown
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,7 +33,7 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Reference Include="Newtonsoft.Json, Version=8.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
|
<Reference Include="Newtonsoft.Json, Version=8.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
|
||||||
<HintPath>..\packages\Newtonsoft.Json.8.0.2\lib\net45\Newtonsoft.Json.dll</HintPath>
|
<HintPath>..\packages\Newtonsoft.Json.8.0.3\lib\net45\Newtonsoft.Json.dll</HintPath>
|
||||||
<Private>True</Private>
|
<Private>True</Private>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="System" />
|
<Reference Include="System" />
|
||||||
|
|||||||
@@ -71,7 +71,7 @@ namespace SteamAuth
|
|||||||
if (removeResponse == null || removeResponse.Response == null || !removeResponse.Response.Success) return false;
|
if (removeResponse == null || removeResponse.Response == null || !removeResponse.Response.Success) return false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -115,7 +115,7 @@ namespace SteamAuth
|
|||||||
codePoint /= steamGuardCodeTranslations.Length;
|
codePoint /= steamGuardCodeTranslations.Length;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception)
|
||||||
{
|
{
|
||||||
return null; //Change later, catch-alls are bad!
|
return null; //Change later, catch-alls are bad!
|
||||||
}
|
}
|
||||||
@@ -162,9 +162,9 @@ namespace SteamAuth
|
|||||||
string confDesc = confDescs[i].Groups[1].Value;
|
string confDesc = confDescs[i].Groups[1].Value;
|
||||||
Confirmation conf = new Confirmation()
|
Confirmation conf = new Confirmation()
|
||||||
{
|
{
|
||||||
ConfirmationDescription = confDesc,
|
Description = confDesc,
|
||||||
ConfirmationID = confID,
|
ID = confID,
|
||||||
ConfirmationKey = confKey
|
Key = confKey
|
||||||
};
|
};
|
||||||
ret.Add(conf);
|
ret.Add(conf);
|
||||||
}
|
}
|
||||||
@@ -212,9 +212,9 @@ namespace SteamAuth
|
|||||||
string confDesc = confDescs[i].Groups[1].Value;
|
string confDesc = confDescs[i].Groups[1].Value;
|
||||||
Confirmation conf = new Confirmation()
|
Confirmation conf = new Confirmation()
|
||||||
{
|
{
|
||||||
ConfirmationDescription = confDesc,
|
Description = confDesc,
|
||||||
ConfirmationID = confID,
|
ID = confID,
|
||||||
ConfirmationKey = confKey
|
Key = confKey
|
||||||
};
|
};
|
||||||
ret.Add(conf);
|
ret.Add(conf);
|
||||||
}
|
}
|
||||||
@@ -268,7 +268,7 @@ namespace SteamAuth
|
|||||||
this.Session.SteamLoginSecure = tokenSecure;
|
this.Session.SteamLoginSecure = tokenSecure;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -300,7 +300,7 @@ namespace SteamAuth
|
|||||||
this.Session.SteamLoginSecure = tokenSecure;
|
this.Session.SteamLoginSecure = tokenSecure;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -308,7 +308,7 @@ namespace SteamAuth
|
|||||||
|
|
||||||
private ConfirmationDetailsResponse _getConfirmationDetails(Confirmation conf)
|
private ConfirmationDetailsResponse _getConfirmationDetails(Confirmation conf)
|
||||||
{
|
{
|
||||||
string url = APIEndpoints.COMMUNITY_BASE + "/mobileconf/details/" + conf.ConfirmationID + "?";
|
string url = APIEndpoints.COMMUNITY_BASE + "/mobileconf/details/" + conf.ID + "?";
|
||||||
string queryString = GenerateConfirmationQueryParams("details");
|
string queryString = GenerateConfirmationQueryParams("details");
|
||||||
url += queryString;
|
url += queryString;
|
||||||
|
|
||||||
@@ -329,7 +329,7 @@ namespace SteamAuth
|
|||||||
string url = APIEndpoints.COMMUNITY_BASE + "/mobileconf/ajaxop";
|
string url = APIEndpoints.COMMUNITY_BASE + "/mobileconf/ajaxop";
|
||||||
string queryString = "?op=" + op + "&";
|
string queryString = "?op=" + op + "&";
|
||||||
queryString += GenerateConfirmationQueryParams(op);
|
queryString += GenerateConfirmationQueryParams(op);
|
||||||
queryString += "&cid=" + conf.ConfirmationID + "&ck=" + conf.ConfirmationKey;
|
queryString += "&cid=" + conf.ID + "&ck=" + conf.Key;
|
||||||
url += queryString;
|
url += queryString;
|
||||||
|
|
||||||
CookieContainer cookies = new CookieContainer();
|
CookieContainer cookies = new CookieContainer();
|
||||||
@@ -401,7 +401,7 @@ namespace SteamAuth
|
|||||||
string hash = WebUtility.UrlEncode(encodedData);
|
string hash = WebUtility.UrlEncode(encodedData);
|
||||||
return hash;
|
return hash;
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception)
|
||||||
{
|
{
|
||||||
return null; //Fix soon: catch-all is BAD!
|
return null; //Fix soon: catch-all is BAD!
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -161,8 +161,6 @@ namespace SteamAuth
|
|||||||
this.LoggedIn = true;
|
this.LoggedIn = true;
|
||||||
return LoginResult.LoginOkay;
|
return LoginResult.LoginOkay;
|
||||||
}
|
}
|
||||||
|
|
||||||
return LoginResult.GeneralFailure;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private class LoginResponse
|
private class LoginResponse
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<packages>
|
<packages>
|
||||||
<package id="Newtonsoft.Json" version="8.0.2" targetFramework="net452" />
|
<package id="Newtonsoft.Json" version="8.0.3" targetFramework="net451" />
|
||||||
</packages>
|
</packages>
|
||||||
66
cc.sh
Executable file
66
cc.sh
Executable file
@@ -0,0 +1,66 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
set -eu
|
||||||
|
|
||||||
|
BUILD="Release"
|
||||||
|
CLEAN=0
|
||||||
|
|
||||||
|
MONO_ARGS=("--aot" "--llvm" "--server" "-O=all")
|
||||||
|
XBUILD_ARGS=("/nologo")
|
||||||
|
BINARIES=("ArchiSteamFarm/bin/Release/ArchiSteamFarm.exe")
|
||||||
|
SOLUTION="ArchiSteamFarm.sln"
|
||||||
|
|
||||||
|
PRINT_USAGE() {
|
||||||
|
echo "Usage: $0 [--clean] [debug/release]"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
for ARG in "$@"; do
|
||||||
|
case "$ARG" in
|
||||||
|
release|Release) BUILD="Release" ;;
|
||||||
|
debug|Debug) BUILD="Debug" ;;
|
||||||
|
--clean) CLEAN=1 ;;
|
||||||
|
*) PRINT_USAGE
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
XBUILD_ARGS+=("/p:Configuration=$BUILD")
|
||||||
|
|
||||||
|
cd "$(dirname "$(readlink -f "$0")")"
|
||||||
|
|
||||||
|
if [[ -d ".git" ]] && hash git &>/dev/null; then
|
||||||
|
git pull
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ ! -f "$SOLUTION" ]]; then
|
||||||
|
echo "ERROR: $SOLUTION could not be found!"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if hash nuget &>/dev/null; then
|
||||||
|
nuget restore "$SOLUTION"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "$CLEAN" -eq 1 ]]; then
|
||||||
|
rm -rf out
|
||||||
|
xbuild "${XBUILD_ARGS[@]}" "/t:Clean" "$SOLUTION"
|
||||||
|
fi
|
||||||
|
|
||||||
|
xbuild "${XBUILD_ARGS[@]}" "$SOLUTION"
|
||||||
|
|
||||||
|
if [[ ! -f "${BINARIES[0]}" ]]; then
|
||||||
|
echo "ERROR: ${BINARIES[0]} binary could not be found!"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# If it's release build, use Mono AOT for output binaries
|
||||||
|
if [[ "$BUILD" = "Release" ]]; then
|
||||||
|
for BINARY in "${BINARIES[@]}"; do
|
||||||
|
if [[ ! -f "$BINARY" ]]; then
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
mono "${MONO_ARGS[@]}" "$BINARY"
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo
|
||||||
|
echo "Compilation finished successfully! :)"
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
packages/Newtonsoft.Json.8.0.3/Newtonsoft.Json.8.0.3.nupkg
vendored
Normal file
BIN
packages/Newtonsoft.Json.8.0.3/Newtonsoft.Json.8.0.3.nupkg
vendored
Normal file
Binary file not shown.
BIN
packages/Newtonsoft.Json.8.0.3/lib/net20/Newtonsoft.Json.dll
vendored
Normal file
BIN
packages/Newtonsoft.Json.8.0.3/lib/net20/Newtonsoft.Json.dll
vendored
Normal file
Binary file not shown.
@@ -604,6 +604,12 @@
|
|||||||
Initializes a new instance of the <see cref="T:Newtonsoft.Json.Converters.StringEnumConverter"/> class.
|
Initializes a new instance of the <see cref="T:Newtonsoft.Json.Converters.StringEnumConverter"/> class.
|
||||||
</summary>
|
</summary>
|
||||||
</member>
|
</member>
|
||||||
|
<member name="M:Newtonsoft.Json.Converters.StringEnumConverter.#ctor(System.Boolean)">
|
||||||
|
<summary>
|
||||||
|
Initializes a new instance of the <see cref="T:Newtonsoft.Json.Converters.StringEnumConverter"/> class.
|
||||||
|
</summary>
|
||||||
|
<param name="camelCaseText"><c>true</c> if the written enum text will be camel case; otherwise, <c>false</c>.</param>
|
||||||
|
</member>
|
||||||
<member name="M:Newtonsoft.Json.Converters.StringEnumConverter.WriteJson(Newtonsoft.Json.JsonWriter,System.Object,Newtonsoft.Json.JsonSerializer)">
|
<member name="M:Newtonsoft.Json.Converters.StringEnumConverter.WriteJson(Newtonsoft.Json.JsonWriter,System.Object,Newtonsoft.Json.JsonSerializer)">
|
||||||
<summary>
|
<summary>
|
||||||
Writes the JSON representation of the object.
|
Writes the JSON representation of the object.
|
||||||
@@ -1058,6 +1064,12 @@
|
|||||||
</summary>
|
</summary>
|
||||||
<value>The method used when merging JSON arrays.</value>
|
<value>The method used when merging JSON arrays.</value>
|
||||||
</member>
|
</member>
|
||||||
|
<member name="P:Newtonsoft.Json.Linq.JsonMergeSettings.MergeNullValueHandling">
|
||||||
|
<summary>
|
||||||
|
Gets or sets how how null value properties are merged.
|
||||||
|
</summary>
|
||||||
|
<value>How null value properties are merged.</value>
|
||||||
|
</member>
|
||||||
<member name="T:Newtonsoft.Json.Linq.MergeArrayHandling">
|
<member name="T:Newtonsoft.Json.Linq.MergeArrayHandling">
|
||||||
<summary>
|
<summary>
|
||||||
Specifies how JSON arrays are merged together.
|
Specifies how JSON arrays are merged together.
|
||||||
@@ -1075,6 +1087,21 @@
|
|||||||
<member name="F:Newtonsoft.Json.Linq.MergeArrayHandling.Merge">
|
<member name="F:Newtonsoft.Json.Linq.MergeArrayHandling.Merge">
|
||||||
<summary>Merge array items together, matched by index.</summary>
|
<summary>Merge array items together, matched by index.</summary>
|
||||||
</member>
|
</member>
|
||||||
|
<member name="T:Newtonsoft.Json.Linq.MergeNullValueHandling">
|
||||||
|
<summary>
|
||||||
|
Specifies how null value properties are merged.
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="F:Newtonsoft.Json.Linq.MergeNullValueHandling.Ignore">
|
||||||
|
<summary>
|
||||||
|
The content's null value properties will be ignored during merging.
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="F:Newtonsoft.Json.Linq.MergeNullValueHandling.Merge">
|
||||||
|
<summary>
|
||||||
|
The content's null value properties will be merged.
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
<member name="T:Newtonsoft.Json.Linq.JPropertyDescriptor">
|
<member name="T:Newtonsoft.Json.Linq.JPropertyDescriptor">
|
||||||
<summary>
|
<summary>
|
||||||
Represents a view of a <see cref="T:Newtonsoft.Json.Linq.JProperty"/>.
|
Represents a view of a <see cref="T:Newtonsoft.Json.Linq.JProperty"/>.
|
||||||
@@ -3511,9 +3538,9 @@
|
|||||||
</member>
|
</member>
|
||||||
<member name="M:Newtonsoft.Json.Linq.JValue.CreateUndefined">
|
<member name="M:Newtonsoft.Json.Linq.JValue.CreateUndefined">
|
||||||
<summary>
|
<summary>
|
||||||
Creates a <see cref="T:Newtonsoft.Json.Linq.JValue"/> null value.
|
Creates a <see cref="T:Newtonsoft.Json.Linq.JValue"/> undefined value.
|
||||||
</summary>
|
</summary>
|
||||||
<returns>A <see cref="T:Newtonsoft.Json.Linq.JValue"/> null value.</returns>
|
<returns>A <see cref="T:Newtonsoft.Json.Linq.JValue"/> undefined value.</returns>
|
||||||
</member>
|
</member>
|
||||||
<member name="P:Newtonsoft.Json.Linq.JValue.Type">
|
<member name="P:Newtonsoft.Json.Linq.JValue.Type">
|
||||||
<summary>
|
<summary>
|
||||||
@@ -6646,7 +6673,7 @@
|
|||||||
</member>
|
</member>
|
||||||
<member name="F:Newtonsoft.Json.MemberSerialization.OptIn">
|
<member name="F:Newtonsoft.Json.MemberSerialization.OptIn">
|
||||||
<summary>
|
<summary>
|
||||||
Only members must be marked with <see cref="T:Newtonsoft.Json.JsonPropertyAttribute"/> or <see cref="!:DataMemberAttribute"/> are serialized.
|
Only members marked with <see cref="T:Newtonsoft.Json.JsonPropertyAttribute"/> or <see cref="!:DataMemberAttribute"/> are serialized.
|
||||||
This member serialization mode can also be set by marking the class with <see cref="!:DataContractAttribute"/>.
|
This member serialization mode can also be set by marking the class with <see cref="!:DataContractAttribute"/>.
|
||||||
</summary>
|
</summary>
|
||||||
</member>
|
</member>
|
||||||
BIN
packages/Newtonsoft.Json.8.0.3/lib/net35/Newtonsoft.Json.dll
vendored
Normal file
BIN
packages/Newtonsoft.Json.8.0.3/lib/net35/Newtonsoft.Json.dll
vendored
Normal file
Binary file not shown.
@@ -627,6 +627,12 @@
|
|||||||
Initializes a new instance of the <see cref="T:Newtonsoft.Json.Converters.StringEnumConverter"/> class.
|
Initializes a new instance of the <see cref="T:Newtonsoft.Json.Converters.StringEnumConverter"/> class.
|
||||||
</summary>
|
</summary>
|
||||||
</member>
|
</member>
|
||||||
|
<member name="M:Newtonsoft.Json.Converters.StringEnumConverter.#ctor(System.Boolean)">
|
||||||
|
<summary>
|
||||||
|
Initializes a new instance of the <see cref="T:Newtonsoft.Json.Converters.StringEnumConverter"/> class.
|
||||||
|
</summary>
|
||||||
|
<param name="camelCaseText"><c>true</c> if the written enum text will be camel case; otherwise, <c>false</c>.</param>
|
||||||
|
</member>
|
||||||
<member name="M:Newtonsoft.Json.Converters.StringEnumConverter.WriteJson(Newtonsoft.Json.JsonWriter,System.Object,Newtonsoft.Json.JsonSerializer)">
|
<member name="M:Newtonsoft.Json.Converters.StringEnumConverter.WriteJson(Newtonsoft.Json.JsonWriter,System.Object,Newtonsoft.Json.JsonSerializer)">
|
||||||
<summary>
|
<summary>
|
||||||
Writes the JSON representation of the object.
|
Writes the JSON representation of the object.
|
||||||
@@ -1190,6 +1196,12 @@
|
|||||||
</summary>
|
</summary>
|
||||||
<value>The method used when merging JSON arrays.</value>
|
<value>The method used when merging JSON arrays.</value>
|
||||||
</member>
|
</member>
|
||||||
|
<member name="P:Newtonsoft.Json.Linq.JsonMergeSettings.MergeNullValueHandling">
|
||||||
|
<summary>
|
||||||
|
Gets or sets how how null value properties are merged.
|
||||||
|
</summary>
|
||||||
|
<value>How null value properties are merged.</value>
|
||||||
|
</member>
|
||||||
<member name="T:Newtonsoft.Json.Linq.MergeArrayHandling">
|
<member name="T:Newtonsoft.Json.Linq.MergeArrayHandling">
|
||||||
<summary>
|
<summary>
|
||||||
Specifies how JSON arrays are merged together.
|
Specifies how JSON arrays are merged together.
|
||||||
@@ -1207,6 +1219,21 @@
|
|||||||
<member name="F:Newtonsoft.Json.Linq.MergeArrayHandling.Merge">
|
<member name="F:Newtonsoft.Json.Linq.MergeArrayHandling.Merge">
|
||||||
<summary>Merge array items together, matched by index.</summary>
|
<summary>Merge array items together, matched by index.</summary>
|
||||||
</member>
|
</member>
|
||||||
|
<member name="T:Newtonsoft.Json.Linq.MergeNullValueHandling">
|
||||||
|
<summary>
|
||||||
|
Specifies how null value properties are merged.
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="F:Newtonsoft.Json.Linq.MergeNullValueHandling.Ignore">
|
||||||
|
<summary>
|
||||||
|
The content's null value properties will be ignored during merging.
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="F:Newtonsoft.Json.Linq.MergeNullValueHandling.Merge">
|
||||||
|
<summary>
|
||||||
|
The content's null value properties will be merged.
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
<member name="T:Newtonsoft.Json.Linq.JRaw">
|
<member name="T:Newtonsoft.Json.Linq.JRaw">
|
||||||
<summary>
|
<summary>
|
||||||
Represents a raw JSON string.
|
Represents a raw JSON string.
|
||||||
@@ -3605,9 +3632,9 @@
|
|||||||
</member>
|
</member>
|
||||||
<member name="M:Newtonsoft.Json.Linq.JValue.CreateUndefined">
|
<member name="M:Newtonsoft.Json.Linq.JValue.CreateUndefined">
|
||||||
<summary>
|
<summary>
|
||||||
Creates a <see cref="T:Newtonsoft.Json.Linq.JValue"/> null value.
|
Creates a <see cref="T:Newtonsoft.Json.Linq.JValue"/> undefined value.
|
||||||
</summary>
|
</summary>
|
||||||
<returns>A <see cref="T:Newtonsoft.Json.Linq.JValue"/> null value.</returns>
|
<returns>A <see cref="T:Newtonsoft.Json.Linq.JValue"/> undefined value.</returns>
|
||||||
</member>
|
</member>
|
||||||
<member name="P:Newtonsoft.Json.Linq.JValue.Type">
|
<member name="P:Newtonsoft.Json.Linq.JValue.Type">
|
||||||
<summary>
|
<summary>
|
||||||
@@ -5688,7 +5715,7 @@
|
|||||||
</member>
|
</member>
|
||||||
<member name="F:Newtonsoft.Json.MemberSerialization.OptIn">
|
<member name="F:Newtonsoft.Json.MemberSerialization.OptIn">
|
||||||
<summary>
|
<summary>
|
||||||
Only members must be marked with <see cref="T:Newtonsoft.Json.JsonPropertyAttribute"/> or <see cref="T:System.Runtime.Serialization.DataMemberAttribute"/> are serialized.
|
Only members marked with <see cref="T:Newtonsoft.Json.JsonPropertyAttribute"/> or <see cref="T:System.Runtime.Serialization.DataMemberAttribute"/> are serialized.
|
||||||
This member serialization mode can also be set by marking the class with <see cref="T:System.Runtime.Serialization.DataContractAttribute"/>.
|
This member serialization mode can also be set by marking the class with <see cref="T:System.Runtime.Serialization.DataContractAttribute"/>.
|
||||||
</summary>
|
</summary>
|
||||||
</member>
|
</member>
|
||||||
BIN
packages/Newtonsoft.Json.8.0.3/lib/net40/Newtonsoft.Json.dll
vendored
Normal file
BIN
packages/Newtonsoft.Json.8.0.3/lib/net40/Newtonsoft.Json.dll
vendored
Normal file
Binary file not shown.
@@ -699,6 +699,12 @@
|
|||||||
Initializes a new instance of the <see cref="T:Newtonsoft.Json.Converters.StringEnumConverter"/> class.
|
Initializes a new instance of the <see cref="T:Newtonsoft.Json.Converters.StringEnumConverter"/> class.
|
||||||
</summary>
|
</summary>
|
||||||
</member>
|
</member>
|
||||||
|
<member name="M:Newtonsoft.Json.Converters.StringEnumConverter.#ctor(System.Boolean)">
|
||||||
|
<summary>
|
||||||
|
Initializes a new instance of the <see cref="T:Newtonsoft.Json.Converters.StringEnumConverter"/> class.
|
||||||
|
</summary>
|
||||||
|
<param name="camelCaseText"><c>true</c> if the written enum text will be camel case; otherwise, <c>false</c>.</param>
|
||||||
|
</member>
|
||||||
<member name="M:Newtonsoft.Json.Converters.StringEnumConverter.WriteJson(Newtonsoft.Json.JsonWriter,System.Object,Newtonsoft.Json.JsonSerializer)">
|
<member name="M:Newtonsoft.Json.Converters.StringEnumConverter.WriteJson(Newtonsoft.Json.JsonWriter,System.Object,Newtonsoft.Json.JsonSerializer)">
|
||||||
<summary>
|
<summary>
|
||||||
Writes the JSON representation of the object.
|
Writes the JSON representation of the object.
|
||||||
@@ -1173,6 +1179,12 @@
|
|||||||
</summary>
|
</summary>
|
||||||
<value>The method used when merging JSON arrays.</value>
|
<value>The method used when merging JSON arrays.</value>
|
||||||
</member>
|
</member>
|
||||||
|
<member name="P:Newtonsoft.Json.Linq.JsonMergeSettings.MergeNullValueHandling">
|
||||||
|
<summary>
|
||||||
|
Gets or sets how how null value properties are merged.
|
||||||
|
</summary>
|
||||||
|
<value>How null value properties are merged.</value>
|
||||||
|
</member>
|
||||||
<member name="T:Newtonsoft.Json.Linq.MergeArrayHandling">
|
<member name="T:Newtonsoft.Json.Linq.MergeArrayHandling">
|
||||||
<summary>
|
<summary>
|
||||||
Specifies how JSON arrays are merged together.
|
Specifies how JSON arrays are merged together.
|
||||||
@@ -1190,6 +1202,21 @@
|
|||||||
<member name="F:Newtonsoft.Json.Linq.MergeArrayHandling.Merge">
|
<member name="F:Newtonsoft.Json.Linq.MergeArrayHandling.Merge">
|
||||||
<summary>Merge array items together, matched by index.</summary>
|
<summary>Merge array items together, matched by index.</summary>
|
||||||
</member>
|
</member>
|
||||||
|
<member name="T:Newtonsoft.Json.Linq.MergeNullValueHandling">
|
||||||
|
<summary>
|
||||||
|
Specifies how null value properties are merged.
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="F:Newtonsoft.Json.Linq.MergeNullValueHandling.Ignore">
|
||||||
|
<summary>
|
||||||
|
The content's null value properties will be ignored during merging.
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="F:Newtonsoft.Json.Linq.MergeNullValueHandling.Merge">
|
||||||
|
<summary>
|
||||||
|
The content's null value properties will be merged.
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
<member name="T:Newtonsoft.Json.Linq.JRaw">
|
<member name="T:Newtonsoft.Json.Linq.JRaw">
|
||||||
<summary>
|
<summary>
|
||||||
Represents a raw JSON string.
|
Represents a raw JSON string.
|
||||||
@@ -3715,9 +3742,9 @@
|
|||||||
</member>
|
</member>
|
||||||
<member name="M:Newtonsoft.Json.Linq.JValue.CreateUndefined">
|
<member name="M:Newtonsoft.Json.Linq.JValue.CreateUndefined">
|
||||||
<summary>
|
<summary>
|
||||||
Creates a <see cref="T:Newtonsoft.Json.Linq.JValue"/> null value.
|
Creates a <see cref="T:Newtonsoft.Json.Linq.JValue"/> undefined value.
|
||||||
</summary>
|
</summary>
|
||||||
<returns>A <see cref="T:Newtonsoft.Json.Linq.JValue"/> null value.</returns>
|
<returns>A <see cref="T:Newtonsoft.Json.Linq.JValue"/> undefined value.</returns>
|
||||||
</member>
|
</member>
|
||||||
<member name="P:Newtonsoft.Json.Linq.JValue.Type">
|
<member name="P:Newtonsoft.Json.Linq.JValue.Type">
|
||||||
<summary>
|
<summary>
|
||||||
@@ -5896,7 +5923,7 @@
|
|||||||
</member>
|
</member>
|
||||||
<member name="F:Newtonsoft.Json.MemberSerialization.OptIn">
|
<member name="F:Newtonsoft.Json.MemberSerialization.OptIn">
|
||||||
<summary>
|
<summary>
|
||||||
Only members must be marked with <see cref="T:Newtonsoft.Json.JsonPropertyAttribute"/> or <see cref="T:System.Runtime.Serialization.DataMemberAttribute"/> are serialized.
|
Only members marked with <see cref="T:Newtonsoft.Json.JsonPropertyAttribute"/> or <see cref="T:System.Runtime.Serialization.DataMemberAttribute"/> are serialized.
|
||||||
This member serialization mode can also be set by marking the class with <see cref="T:System.Runtime.Serialization.DataContractAttribute"/>.
|
This member serialization mode can also be set by marking the class with <see cref="T:System.Runtime.Serialization.DataContractAttribute"/>.
|
||||||
</summary>
|
</summary>
|
||||||
</member>
|
</member>
|
||||||
BIN
packages/Newtonsoft.Json.8.0.3/lib/net45/Newtonsoft.Json.dll
vendored
Normal file
BIN
packages/Newtonsoft.Json.8.0.3/lib/net45/Newtonsoft.Json.dll
vendored
Normal file
Binary file not shown.
@@ -778,6 +778,12 @@
|
|||||||
Initializes a new instance of the <see cref="T:Newtonsoft.Json.Converters.StringEnumConverter"/> class.
|
Initializes a new instance of the <see cref="T:Newtonsoft.Json.Converters.StringEnumConverter"/> class.
|
||||||
</summary>
|
</summary>
|
||||||
</member>
|
</member>
|
||||||
|
<member name="M:Newtonsoft.Json.Converters.StringEnumConverter.#ctor(System.Boolean)">
|
||||||
|
<summary>
|
||||||
|
Initializes a new instance of the <see cref="T:Newtonsoft.Json.Converters.StringEnumConverter"/> class.
|
||||||
|
</summary>
|
||||||
|
<param name="camelCaseText"><c>true</c> if the written enum text will be camel case; otherwise, <c>false</c>.</param>
|
||||||
|
</member>
|
||||||
<member name="M:Newtonsoft.Json.Converters.StringEnumConverter.WriteJson(Newtonsoft.Json.JsonWriter,System.Object,Newtonsoft.Json.JsonSerializer)">
|
<member name="M:Newtonsoft.Json.Converters.StringEnumConverter.WriteJson(Newtonsoft.Json.JsonWriter,System.Object,Newtonsoft.Json.JsonSerializer)">
|
||||||
<summary>
|
<summary>
|
||||||
Writes the JSON representation of the object.
|
Writes the JSON representation of the object.
|
||||||
@@ -5094,6 +5100,12 @@
|
|||||||
</summary>
|
</summary>
|
||||||
<value>The method used when merging JSON arrays.</value>
|
<value>The method used when merging JSON arrays.</value>
|
||||||
</member>
|
</member>
|
||||||
|
<member name="P:Newtonsoft.Json.Linq.JsonMergeSettings.MergeNullValueHandling">
|
||||||
|
<summary>
|
||||||
|
Gets or sets how how null value properties are merged.
|
||||||
|
</summary>
|
||||||
|
<value>How null value properties are merged.</value>
|
||||||
|
</member>
|
||||||
<member name="T:Newtonsoft.Json.Linq.JProperty">
|
<member name="T:Newtonsoft.Json.Linq.JProperty">
|
||||||
<summary>
|
<summary>
|
||||||
Represents a JSON property.
|
Represents a JSON property.
|
||||||
@@ -6670,9 +6682,9 @@
|
|||||||
</member>
|
</member>
|
||||||
<member name="M:Newtonsoft.Json.Linq.JValue.CreateUndefined">
|
<member name="M:Newtonsoft.Json.Linq.JValue.CreateUndefined">
|
||||||
<summary>
|
<summary>
|
||||||
Creates a <see cref="T:Newtonsoft.Json.Linq.JValue"/> null value.
|
Creates a <see cref="T:Newtonsoft.Json.Linq.JValue"/> undefined value.
|
||||||
</summary>
|
</summary>
|
||||||
<returns>A <see cref="T:Newtonsoft.Json.Linq.JValue"/> null value.</returns>
|
<returns>A <see cref="T:Newtonsoft.Json.Linq.JValue"/> undefined value.</returns>
|
||||||
</member>
|
</member>
|
||||||
<member name="P:Newtonsoft.Json.Linq.JValue.Type">
|
<member name="P:Newtonsoft.Json.Linq.JValue.Type">
|
||||||
<summary>
|
<summary>
|
||||||
@@ -6821,6 +6833,21 @@
|
|||||||
<member name="F:Newtonsoft.Json.Linq.MergeArrayHandling.Merge">
|
<member name="F:Newtonsoft.Json.Linq.MergeArrayHandling.Merge">
|
||||||
<summary>Merge array items together, matched by index.</summary>
|
<summary>Merge array items together, matched by index.</summary>
|
||||||
</member>
|
</member>
|
||||||
|
<member name="T:Newtonsoft.Json.Linq.MergeNullValueHandling">
|
||||||
|
<summary>
|
||||||
|
Specifies how null value properties are merged.
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="F:Newtonsoft.Json.Linq.MergeNullValueHandling.Ignore">
|
||||||
|
<summary>
|
||||||
|
The content's null value properties will be ignored during merging.
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="F:Newtonsoft.Json.Linq.MergeNullValueHandling.Merge">
|
||||||
|
<summary>
|
||||||
|
The content's null value properties will be merged.
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
<member name="T:Newtonsoft.Json.MemberSerialization">
|
<member name="T:Newtonsoft.Json.MemberSerialization">
|
||||||
<summary>
|
<summary>
|
||||||
Specifies the member serialization options for the <see cref="T:Newtonsoft.Json.JsonSerializer"/>.
|
Specifies the member serialization options for the <see cref="T:Newtonsoft.Json.JsonSerializer"/>.
|
||||||
@@ -6834,7 +6861,7 @@
|
|||||||
</member>
|
</member>
|
||||||
<member name="F:Newtonsoft.Json.MemberSerialization.OptIn">
|
<member name="F:Newtonsoft.Json.MemberSerialization.OptIn">
|
||||||
<summary>
|
<summary>
|
||||||
Only members must be marked with <see cref="T:Newtonsoft.Json.JsonPropertyAttribute"/> or <see cref="T:System.Runtime.Serialization.DataMemberAttribute"/> are serialized.
|
Only members marked with <see cref="T:Newtonsoft.Json.JsonPropertyAttribute"/> or <see cref="T:System.Runtime.Serialization.DataMemberAttribute"/> are serialized.
|
||||||
This member serialization mode can also be set by marking the class with <see cref="T:System.Runtime.Serialization.DataContractAttribute"/>.
|
This member serialization mode can also be set by marking the class with <see cref="T:System.Runtime.Serialization.DataContractAttribute"/>.
|
||||||
</summary>
|
</summary>
|
||||||
</member>
|
</member>
|
||||||
BIN
packages/Newtonsoft.Json.8.0.3/lib/portable-net40+sl5+wp80+win8+wpa81/Newtonsoft.Json.dll
vendored
Normal file
BIN
packages/Newtonsoft.Json.8.0.3/lib/portable-net40+sl5+wp80+win8+wpa81/Newtonsoft.Json.dll
vendored
Normal file
Binary file not shown.
@@ -610,6 +610,12 @@
|
|||||||
Initializes a new instance of the <see cref="T:Newtonsoft.Json.Converters.StringEnumConverter"/> class.
|
Initializes a new instance of the <see cref="T:Newtonsoft.Json.Converters.StringEnumConverter"/> class.
|
||||||
</summary>
|
</summary>
|
||||||
</member>
|
</member>
|
||||||
|
<member name="M:Newtonsoft.Json.Converters.StringEnumConverter.#ctor(System.Boolean)">
|
||||||
|
<summary>
|
||||||
|
Initializes a new instance of the <see cref="T:Newtonsoft.Json.Converters.StringEnumConverter"/> class.
|
||||||
|
</summary>
|
||||||
|
<param name="camelCaseText"><c>true</c> if the written enum text will be camel case; otherwise, <c>false</c>.</param>
|
||||||
|
</member>
|
||||||
<member name="M:Newtonsoft.Json.Converters.StringEnumConverter.WriteJson(Newtonsoft.Json.JsonWriter,System.Object,Newtonsoft.Json.JsonSerializer)">
|
<member name="M:Newtonsoft.Json.Converters.StringEnumConverter.WriteJson(Newtonsoft.Json.JsonWriter,System.Object,Newtonsoft.Json.JsonSerializer)">
|
||||||
<summary>
|
<summary>
|
||||||
Writes the JSON representation of the object.
|
Writes the JSON representation of the object.
|
||||||
@@ -4588,6 +4594,12 @@
|
|||||||
</summary>
|
</summary>
|
||||||
<value>The method used when merging JSON arrays.</value>
|
<value>The method used when merging JSON arrays.</value>
|
||||||
</member>
|
</member>
|
||||||
|
<member name="P:Newtonsoft.Json.Linq.JsonMergeSettings.MergeNullValueHandling">
|
||||||
|
<summary>
|
||||||
|
Gets or sets how how null value properties are merged.
|
||||||
|
</summary>
|
||||||
|
<value>How null value properties are merged.</value>
|
||||||
|
</member>
|
||||||
<member name="T:Newtonsoft.Json.Linq.JToken">
|
<member name="T:Newtonsoft.Json.Linq.JToken">
|
||||||
<summary>
|
<summary>
|
||||||
Represents an abstract JSON token.
|
Represents an abstract JSON token.
|
||||||
@@ -5961,9 +5973,9 @@
|
|||||||
</member>
|
</member>
|
||||||
<member name="M:Newtonsoft.Json.Linq.JValue.CreateUndefined">
|
<member name="M:Newtonsoft.Json.Linq.JValue.CreateUndefined">
|
||||||
<summary>
|
<summary>
|
||||||
Creates a <see cref="T:Newtonsoft.Json.Linq.JValue"/> null value.
|
Creates a <see cref="T:Newtonsoft.Json.Linq.JValue"/> undefined value.
|
||||||
</summary>
|
</summary>
|
||||||
<returns>A <see cref="T:Newtonsoft.Json.Linq.JValue"/> null value.</returns>
|
<returns>A <see cref="T:Newtonsoft.Json.Linq.JValue"/> undefined value.</returns>
|
||||||
</member>
|
</member>
|
||||||
<member name="P:Newtonsoft.Json.Linq.JValue.Type">
|
<member name="P:Newtonsoft.Json.Linq.JValue.Type">
|
||||||
<summary>
|
<summary>
|
||||||
@@ -6086,6 +6098,21 @@
|
|||||||
<member name="F:Newtonsoft.Json.Linq.MergeArrayHandling.Merge">
|
<member name="F:Newtonsoft.Json.Linq.MergeArrayHandling.Merge">
|
||||||
<summary>Merge array items together, matched by index.</summary>
|
<summary>Merge array items together, matched by index.</summary>
|
||||||
</member>
|
</member>
|
||||||
|
<member name="T:Newtonsoft.Json.Linq.MergeNullValueHandling">
|
||||||
|
<summary>
|
||||||
|
Specifies how null value properties are merged.
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="F:Newtonsoft.Json.Linq.MergeNullValueHandling.Ignore">
|
||||||
|
<summary>
|
||||||
|
The content's null value properties will be ignored during merging.
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="F:Newtonsoft.Json.Linq.MergeNullValueHandling.Merge">
|
||||||
|
<summary>
|
||||||
|
The content's null value properties will be merged.
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
<member name="T:Newtonsoft.Json.MemberSerialization">
|
<member name="T:Newtonsoft.Json.MemberSerialization">
|
||||||
<summary>
|
<summary>
|
||||||
Specifies the member serialization options for the <see cref="T:Newtonsoft.Json.JsonSerializer"/>.
|
Specifies the member serialization options for the <see cref="T:Newtonsoft.Json.JsonSerializer"/>.
|
||||||
@@ -6099,7 +6126,7 @@
|
|||||||
</member>
|
</member>
|
||||||
<member name="F:Newtonsoft.Json.MemberSerialization.OptIn">
|
<member name="F:Newtonsoft.Json.MemberSerialization.OptIn">
|
||||||
<summary>
|
<summary>
|
||||||
Only members must be marked with <see cref="T:Newtonsoft.Json.JsonPropertyAttribute"/> or <see cref="T:System.Runtime.Serialization.DataMemberAttribute"/> are serialized.
|
Only members marked with <see cref="T:Newtonsoft.Json.JsonPropertyAttribute"/> or <see cref="T:System.Runtime.Serialization.DataMemberAttribute"/> are serialized.
|
||||||
This member serialization mode can also be set by marking the class with <see cref="T:System.Runtime.Serialization.DataContractAttribute"/>.
|
This member serialization mode can also be set by marking the class with <see cref="T:System.Runtime.Serialization.DataContractAttribute"/>.
|
||||||
</summary>
|
</summary>
|
||||||
</member>
|
</member>
|
||||||
BIN
packages/Newtonsoft.Json.8.0.3/lib/portable-net45+wp80+win8+wpa81+dnxcore50/Newtonsoft.Json.dll
vendored
Normal file
BIN
packages/Newtonsoft.Json.8.0.3/lib/portable-net45+wp80+win8+wpa81+dnxcore50/Newtonsoft.Json.dll
vendored
Normal file
Binary file not shown.
@@ -650,6 +650,12 @@
|
|||||||
Initializes a new instance of the <see cref="T:Newtonsoft.Json.Converters.StringEnumConverter"/> class.
|
Initializes a new instance of the <see cref="T:Newtonsoft.Json.Converters.StringEnumConverter"/> class.
|
||||||
</summary>
|
</summary>
|
||||||
</member>
|
</member>
|
||||||
|
<member name="M:Newtonsoft.Json.Converters.StringEnumConverter.#ctor(System.Boolean)">
|
||||||
|
<summary>
|
||||||
|
Initializes a new instance of the <see cref="T:Newtonsoft.Json.Converters.StringEnumConverter"/> class.
|
||||||
|
</summary>
|
||||||
|
<param name="camelCaseText"><c>true</c> if the written enum text will be camel case; otherwise, <c>false</c>.</param>
|
||||||
|
</member>
|
||||||
<member name="M:Newtonsoft.Json.Converters.StringEnumConverter.WriteJson(Newtonsoft.Json.JsonWriter,System.Object,Newtonsoft.Json.JsonSerializer)">
|
<member name="M:Newtonsoft.Json.Converters.StringEnumConverter.WriteJson(Newtonsoft.Json.JsonWriter,System.Object,Newtonsoft.Json.JsonSerializer)">
|
||||||
<summary>
|
<summary>
|
||||||
Writes the JSON representation of the object.
|
Writes the JSON representation of the object.
|
||||||
@@ -4858,6 +4864,12 @@
|
|||||||
</summary>
|
</summary>
|
||||||
<value>The method used when merging JSON arrays.</value>
|
<value>The method used when merging JSON arrays.</value>
|
||||||
</member>
|
</member>
|
||||||
|
<member name="P:Newtonsoft.Json.Linq.JsonMergeSettings.MergeNullValueHandling">
|
||||||
|
<summary>
|
||||||
|
Gets or sets how how null value properties are merged.
|
||||||
|
</summary>
|
||||||
|
<value>How null value properties are merged.</value>
|
||||||
|
</member>
|
||||||
<member name="T:Newtonsoft.Json.Linq.JToken">
|
<member name="T:Newtonsoft.Json.Linq.JToken">
|
||||||
<summary>
|
<summary>
|
||||||
Represents an abstract JSON token.
|
Represents an abstract JSON token.
|
||||||
@@ -6249,9 +6261,9 @@
|
|||||||
</member>
|
</member>
|
||||||
<member name="M:Newtonsoft.Json.Linq.JValue.CreateUndefined">
|
<member name="M:Newtonsoft.Json.Linq.JValue.CreateUndefined">
|
||||||
<summary>
|
<summary>
|
||||||
Creates a <see cref="T:Newtonsoft.Json.Linq.JValue"/> null value.
|
Creates a <see cref="T:Newtonsoft.Json.Linq.JValue"/> undefined value.
|
||||||
</summary>
|
</summary>
|
||||||
<returns>A <see cref="T:Newtonsoft.Json.Linq.JValue"/> null value.</returns>
|
<returns>A <see cref="T:Newtonsoft.Json.Linq.JValue"/> undefined value.</returns>
|
||||||
</member>
|
</member>
|
||||||
<member name="P:Newtonsoft.Json.Linq.JValue.Type">
|
<member name="P:Newtonsoft.Json.Linq.JValue.Type">
|
||||||
<summary>
|
<summary>
|
||||||
@@ -6383,6 +6395,21 @@
|
|||||||
<member name="F:Newtonsoft.Json.Linq.MergeArrayHandling.Merge">
|
<member name="F:Newtonsoft.Json.Linq.MergeArrayHandling.Merge">
|
||||||
<summary>Merge array items together, matched by index.</summary>
|
<summary>Merge array items together, matched by index.</summary>
|
||||||
</member>
|
</member>
|
||||||
|
<member name="T:Newtonsoft.Json.Linq.MergeNullValueHandling">
|
||||||
|
<summary>
|
||||||
|
Specifies how null value properties are merged.
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="F:Newtonsoft.Json.Linq.MergeNullValueHandling.Ignore">
|
||||||
|
<summary>
|
||||||
|
The content's null value properties will be ignored during merging.
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="F:Newtonsoft.Json.Linq.MergeNullValueHandling.Merge">
|
||||||
|
<summary>
|
||||||
|
The content's null value properties will be merged.
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
<member name="T:Newtonsoft.Json.MemberSerialization">
|
<member name="T:Newtonsoft.Json.MemberSerialization">
|
||||||
<summary>
|
<summary>
|
||||||
Specifies the member serialization options for the <see cref="T:Newtonsoft.Json.JsonSerializer"/>.
|
Specifies the member serialization options for the <see cref="T:Newtonsoft.Json.JsonSerializer"/>.
|
||||||
@@ -6396,7 +6423,7 @@
|
|||||||
</member>
|
</member>
|
||||||
<member name="F:Newtonsoft.Json.MemberSerialization.OptIn">
|
<member name="F:Newtonsoft.Json.MemberSerialization.OptIn">
|
||||||
<summary>
|
<summary>
|
||||||
Only members must be marked with <see cref="T:Newtonsoft.Json.JsonPropertyAttribute"/> or <see cref="T:System.Runtime.Serialization.DataMemberAttribute"/> are serialized.
|
Only members marked with <see cref="T:Newtonsoft.Json.JsonPropertyAttribute"/> or <see cref="T:System.Runtime.Serialization.DataMemberAttribute"/> are serialized.
|
||||||
This member serialization mode can also be set by marking the class with <see cref="T:System.Runtime.Serialization.DataContractAttribute"/>.
|
This member serialization mode can also be set by marking the class with <see cref="T:System.Runtime.Serialization.DataContractAttribute"/>.
|
||||||
</summary>
|
</summary>
|
||||||
</member>
|
</member>
|
||||||
28
run.sh
Executable file
28
run.sh
Executable file
@@ -0,0 +1,28 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
set -eu
|
||||||
|
|
||||||
|
BUILD="Release"
|
||||||
|
|
||||||
|
MONO_ARGS=("--llvm" "--server" "-O=all")
|
||||||
|
|
||||||
|
PRINT_USAGE() {
|
||||||
|
echo "Usage: $0 [debug/release]"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
for ARG in "$@"; do
|
||||||
|
case "$ARG" in
|
||||||
|
release|Release) BUILD="Release" ;;
|
||||||
|
debug|Debug) BUILD="Debug" ;;
|
||||||
|
*) PRINT_USAGE
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
BINARY="ArchiSteamFarm/bin/$BUILD/ArchiSteamFarm.exe"
|
||||||
|
|
||||||
|
if [[ ! -f "$BINARY" ]]; then
|
||||||
|
echo "ERROR: $BINARY could not be found!"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
mono "${MONO_ARGS[@]}" "$BINARY"
|
||||||
Binary file not shown.
BIN
tools/ILRepack/BamlParser.dll
Normal file
BIN
tools/ILRepack/BamlParser.dll
Normal file
Binary file not shown.
BIN
tools/ILRepack/Fasterflect.dll
Normal file
BIN
tools/ILRepack/Fasterflect.dll
Normal file
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user