mirror of
https://github.com/JustArchiNET/ArchiSteamFarm.git
synced 2025-12-16 14:30:31 +00:00
Compare commits
222 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
85dea3ab70 | ||
|
|
aa9d78af95 | ||
|
|
550effd7c1 | ||
|
|
548146cb65 | ||
|
|
4ca39da1f2 | ||
|
|
f406034c63 | ||
|
|
2b5b38aa07 | ||
|
|
b8dbddd6f4 | ||
|
|
8ce70889d7 | ||
|
|
93d235c1b2 | ||
|
|
73af6b369a | ||
|
|
2d91a1ed26 | ||
|
|
7af0027c66 | ||
|
|
2ce54d9d0a | ||
|
|
88d722c14b | ||
|
|
5c46069c67 | ||
|
|
c2a1c160e0 | ||
|
|
ff971f7615 | ||
|
|
cdcaa9b06c | ||
|
|
9403985b14 | ||
|
|
a0215d2ac4 | ||
|
|
2ef99461d6 | ||
|
|
8e91031510 | ||
|
|
254cd3843e | ||
|
|
450fc579f7 | ||
|
|
98f9e716d2 | ||
|
|
86c8aa9b74 | ||
|
|
33e0675177 | ||
|
|
f840f28657 | ||
|
|
64eb4a51b6 | ||
|
|
97affa7b54 | ||
|
|
65f1d790da | ||
|
|
0107185f2a | ||
|
|
b8e98f58ac | ||
|
|
be9217f493 | ||
|
|
b60b864aca | ||
|
|
4c64141462 | ||
|
|
4b50596709 | ||
|
|
622f060575 | ||
|
|
20038e8c86 | ||
|
|
b8faca2517 | ||
|
|
6f93139a18 | ||
|
|
50b5c7b87f | ||
|
|
b60448ef4c | ||
|
|
fad08a1fa9 | ||
|
|
a180c100c6 | ||
|
|
9d97ca16e8 | ||
|
|
e833415718 | ||
|
|
6bb296a674 | ||
|
|
f1e5874868 | ||
|
|
38e2088d09 | ||
|
|
8447e07aa0 | ||
|
|
fbe4e4bc6d | ||
|
|
f1213607ce | ||
|
|
de832c530b | ||
|
|
0c872b17e2 | ||
|
|
5fcbb85b4c | ||
|
|
3cdc93d373 | ||
|
|
36e99d9139 | ||
|
|
7bee2d468b | ||
|
|
8630cc40c8 | ||
|
|
3683195a0e | ||
|
|
7f5b946645 | ||
|
|
fdb194fe67 | ||
|
|
9063b9206b | ||
|
|
8d300894e5 | ||
|
|
3a0d3c444e | ||
|
|
8118fe0690 | ||
|
|
344c2ad23d | ||
|
|
d1a6613541 | ||
|
|
3dc88c65aa | ||
|
|
46384829c9 | ||
|
|
415ee8cc57 | ||
|
|
351d45e049 | ||
|
|
f81bbc60c5 | ||
|
|
eb6e93a172 | ||
|
|
e17c3ecf2a | ||
|
|
048b0fb538 | ||
|
|
ac7ecb6bb4 | ||
|
|
fcaf038dac | ||
|
|
f3da5d6afc | ||
|
|
84f33fcef4 | ||
|
|
22f0d423a3 | ||
|
|
f1d7609796 | ||
|
|
77386ecae5 | ||
|
|
4e86d21ef8 | ||
|
|
044fc87691 | ||
|
|
79fad62a4d | ||
|
|
6622d3b147 | ||
|
|
6b6d5429ad | ||
|
|
d59d0a8415 | ||
|
|
e3100d3938 | ||
|
|
42c020e552 | ||
|
|
554273833b | ||
|
|
093a29df62 | ||
|
|
31aa6b2e4a | ||
|
|
9f7ecdf054 | ||
|
|
7c4c74bf84 | ||
|
|
b8f03abd8b | ||
|
|
47f846540b | ||
|
|
bc14713079 | ||
|
|
770a8fee66 | ||
|
|
1df9af08e6 | ||
|
|
27464f6120 | ||
|
|
dfd45c6e25 | ||
|
|
adc1759cee | ||
|
|
88369ec71a | ||
|
|
a5d8ae53dd | ||
|
|
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 |
12
.travis.yml
Normal file
12
.travis.yml
Normal file
@@ -0,0 +1,12 @@
|
||||
language: csharp
|
||||
solution: ArchiSteamFarm.sln
|
||||
|
||||
git:
|
||||
depth: 10
|
||||
|
||||
mono:
|
||||
- weekly
|
||||
- latest
|
||||
|
||||
notifications:
|
||||
email: false
|
||||
@@ -12,6 +12,11 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ConfigGenerator", "ConfigGe
|
||||
{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
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
@@ -30,6 +35,10 @@ Global
|
||||
{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
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
||||
@@ -26,12 +26,24 @@ using SteamKit2;
|
||||
using SteamKit2.Internal;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace ArchiSteamFarm {
|
||||
internal sealed class ArchiHandler : ClientMsgHandler {
|
||||
private readonly Bot Bot;
|
||||
|
||||
internal ArchiHandler(Bot bot) {
|
||||
if (bot == null) {
|
||||
throw new ArgumentNullException(nameof(bot));
|
||||
}
|
||||
|
||||
Bot = bot;
|
||||
}
|
||||
|
||||
/*
|
||||
____ _ _ _ _
|
||||
/ ___| __ _ | || || |__ __ _ ___ | | __ ___
|
||||
@@ -42,69 +54,73 @@ namespace ArchiSteamFarm {
|
||||
*/
|
||||
|
||||
internal sealed class NotificationsCallback : CallbackMsg {
|
||||
internal sealed class Notification {
|
||||
internal enum ENotificationType : uint {
|
||||
Unknown = 0,
|
||||
Trading = 1,
|
||||
// Only custom below, different than ones available as user_notification_type
|
||||
Items = 514
|
||||
}
|
||||
|
||||
internal readonly ENotificationType NotificationType;
|
||||
|
||||
internal Notification(ENotificationType notificationType) {
|
||||
NotificationType = notificationType;
|
||||
}
|
||||
internal enum ENotification : byte {
|
||||
[SuppressMessage("ReSharper", "UnusedMember.Global")]
|
||||
Unknown = 0,
|
||||
Trading = 1,
|
||||
// Only custom below, different than ones available as user_notification_type
|
||||
Items = 255
|
||||
}
|
||||
|
||||
internal readonly List<Notification> Notifications;
|
||||
internal readonly HashSet<ENotification> Notifications;
|
||||
|
||||
internal NotificationsCallback(JobID jobID, CMsgClientUserNotifications msg) {
|
||||
JobID = jobID;
|
||||
|
||||
if (msg == null || msg.notifications == null) {
|
||||
return;
|
||||
if ((jobID == null) || (msg == null)) {
|
||||
throw new ArgumentNullException(nameof(jobID) + " || " + nameof(msg));
|
||||
}
|
||||
|
||||
Notifications = new List<Notification>(msg.notifications.Count);
|
||||
foreach (var notification in msg.notifications) {
|
||||
Notifications.Add(new Notification((Notification.ENotificationType) notification.user_notification_type));
|
||||
JobID = jobID;
|
||||
|
||||
Notifications = new HashSet<ENotification>();
|
||||
foreach (CMsgClientUserNotifications.Notification notification in msg.notifications) {
|
||||
Notifications.Add((ENotification) notification.user_notification_type);
|
||||
}
|
||||
}
|
||||
|
||||
internal NotificationsCallback(JobID jobID, CMsgClientItemAnnouncements msg) {
|
||||
JobID = jobID;
|
||||
|
||||
if (msg == null) {
|
||||
return;
|
||||
if ((jobID == null) || (msg == null)) {
|
||||
throw new ArgumentNullException(nameof(jobID) + " || " + nameof(msg));
|
||||
}
|
||||
|
||||
JobID = jobID;
|
||||
|
||||
if (msg.count_new_items > 0) {
|
||||
Notifications = new List<Notification>(1) {
|
||||
new Notification(Notification.ENotificationType.Items)
|
||||
Notifications = new HashSet<ENotification> {
|
||||
ENotification.Items
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal sealed class OfflineMessageCallback : CallbackMsg {
|
||||
internal readonly uint OfflineMessages;
|
||||
internal readonly List<uint> Users;
|
||||
internal readonly uint OfflineMessagesCount;
|
||||
|
||||
internal OfflineMessageCallback(JobID jobID, CMsgClientOfflineMessageNotification msg) {
|
||||
JobID = jobID;
|
||||
|
||||
if (msg == null) {
|
||||
return;
|
||||
if ((jobID == null) || (msg == null)) {
|
||||
throw new ArgumentNullException(nameof(jobID) + " || " + nameof(msg));
|
||||
}
|
||||
|
||||
OfflineMessages = msg.offline_messages;
|
||||
Users = msg.friends_with_offline_messages;
|
||||
JobID = jobID;
|
||||
OfflineMessagesCount = msg.offline_messages;
|
||||
}
|
||||
}
|
||||
|
||||
internal sealed class PlayingSessionStateCallback : CallbackMsg {
|
||||
internal readonly bool PlayingBlocked;
|
||||
|
||||
internal PlayingSessionStateCallback(JobID jobID, CMsgClientPlayingSessionState msg) {
|
||||
if ((jobID == null) || (msg == null)) {
|
||||
throw new ArgumentNullException(nameof(jobID) + " || " + nameof(msg));
|
||||
}
|
||||
|
||||
JobID = jobID;
|
||||
PlayingBlocked = msg.playing_blocked;
|
||||
}
|
||||
}
|
||||
|
||||
internal sealed class PurchaseResponseCallback : CallbackMsg {
|
||||
internal enum EPurchaseResult : int {
|
||||
internal enum EPurchaseResult : sbyte {
|
||||
[SuppressMessage("ReSharper", "UnusedMember.Global")]
|
||||
Unknown = -1,
|
||||
OK = 0,
|
||||
AlreadyOwned = 9,
|
||||
@@ -115,39 +131,36 @@ namespace ArchiSteamFarm {
|
||||
OnCooldown = 53
|
||||
}
|
||||
|
||||
internal readonly EResult Result;
|
||||
internal readonly EPurchaseResult PurchaseResult;
|
||||
internal readonly KeyValue ReceiptInfo;
|
||||
internal readonly Dictionary<uint, string> Items;
|
||||
|
||||
internal PurchaseResponseCallback(JobID jobID, CMsgClientPurchaseResponse msg) {
|
||||
JobID = jobID;
|
||||
|
||||
if (msg == null) {
|
||||
return;
|
||||
if ((jobID == null) || (msg == null)) {
|
||||
throw new ArgumentNullException(nameof(jobID) + " || " + nameof(msg));
|
||||
}
|
||||
|
||||
Result = (EResult) msg.eresult;
|
||||
JobID = jobID;
|
||||
PurchaseResult = (EPurchaseResult) msg.purchase_result_details;
|
||||
|
||||
if (msg.purchase_receipt_info == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
ReceiptInfo = new KeyValue();
|
||||
KeyValue receiptInfo = new KeyValue();
|
||||
using (MemoryStream ms = new MemoryStream(msg.purchase_receipt_info)) {
|
||||
if (!ReceiptInfo.TryReadAsBinary(ms)) {
|
||||
if (!receiptInfo.TryReadAsBinary(ms)) {
|
||||
Logging.LogNullError(nameof(ms));
|
||||
return;
|
||||
}
|
||||
|
||||
List<KeyValue> lineItems = ReceiptInfo["lineitems"].Children;
|
||||
List<KeyValue> lineItems = receiptInfo["lineitems"].Children;
|
||||
Items = new Dictionary<uint, string>(lineItems.Count);
|
||||
|
||||
foreach (KeyValue lineItem in lineItems) {
|
||||
uint appID = (uint) lineItem["PackageID"].AsUnsignedLong();
|
||||
string gameName = lineItem["ItemDescription"].AsString();
|
||||
gameName = WebUtility.UrlDecode(gameName); // Apparently steam expects client to decode sent HTML
|
||||
Items.Add(appID, gameName);
|
||||
string gameName = lineItem["ItemDescription"].Value;
|
||||
gameName = WebUtility.HtmlDecode(gameName); // Apparently steam expects client to decode sent HTML
|
||||
Items[appID] = gameName;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -162,83 +175,47 @@ namespace ArchiSteamFarm {
|
||||
|
||||
*/
|
||||
|
||||
internal void AcceptClanInvite(ulong clanID) {
|
||||
if (clanID == 0 || !Client.IsConnected) {
|
||||
return;
|
||||
}
|
||||
|
||||
var request = new ClientMsg<CMsgClientClanInviteAction>((int) EMsg.ClientAcknowledgeClanInvite);
|
||||
request.Body.GroupID = clanID;
|
||||
request.Body.AcceptInvite = true;
|
||||
|
||||
Client.Send(request);
|
||||
}
|
||||
|
||||
internal void DeclineClanInvite(ulong clanID) {
|
||||
if (clanID == 0 || !Client.IsConnected) {
|
||||
return;
|
||||
}
|
||||
|
||||
var request = new ClientMsg<CMsgClientClanInviteAction>((int) EMsg.ClientAcknowledgeClanInvite);
|
||||
request.Body.GroupID = clanID;
|
||||
request.Body.AcceptInvite = false;
|
||||
|
||||
Client.Send(request);
|
||||
}
|
||||
|
||||
internal void PlayGame(string gameName) {
|
||||
if (!Client.IsConnected) {
|
||||
return;
|
||||
}
|
||||
|
||||
var request = new ClientMsgProtobuf<CMsgClientGamesPlayed>(EMsg.ClientGamesPlayed);
|
||||
|
||||
var gamePlayed = new CMsgClientGamesPlayed.GamePlayed();
|
||||
ClientMsgProtobuf<CMsgClientGamesPlayed> request = new ClientMsgProtobuf<CMsgClientGamesPlayed>(EMsg.ClientGamesPlayed);
|
||||
if (!string.IsNullOrEmpty(gameName)) {
|
||||
gamePlayed.game_id = new GameID() {
|
||||
AppType = GameID.GameType.Shortcut,
|
||||
ModID = uint.MaxValue
|
||||
};
|
||||
gamePlayed.game_extra_info = gameName;
|
||||
}
|
||||
|
||||
request.Body.games_played.Add(gamePlayed);
|
||||
|
||||
Client.Send(request);
|
||||
}
|
||||
|
||||
internal void PlayGames(params uint[] gameIDs) {
|
||||
if (!Client.IsConnected) {
|
||||
return;
|
||||
}
|
||||
|
||||
var request = new ClientMsgProtobuf<CMsgClientGamesPlayed>(EMsg.ClientGamesPlayed);
|
||||
foreach (uint gameID in gameIDs) {
|
||||
if (gameID == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
request.Body.games_played.Add(new CMsgClientGamesPlayed.GamePlayed {
|
||||
game_id = new GameID(gameID),
|
||||
game_extra_info = gameName,
|
||||
game_id = new GameID {
|
||||
AppType = GameID.GameType.Shortcut,
|
||||
ModID = uint.MaxValue
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Client.Send(request);
|
||||
}
|
||||
|
||||
internal void PlayGames(ICollection<uint> gameIDs) {
|
||||
if (gameIDs == null || !Client.IsConnected) {
|
||||
internal void PlayGames(uint gameID) {
|
||||
if (!Client.IsConnected) {
|
||||
return;
|
||||
}
|
||||
|
||||
var request = new ClientMsgProtobuf<CMsgClientGamesPlayed>(EMsg.ClientGamesPlayed);
|
||||
foreach (uint gameID in gameIDs) {
|
||||
if (gameID == 0) {
|
||||
continue;
|
||||
}
|
||||
PlayGames(new HashSet<uint> { gameID });
|
||||
}
|
||||
|
||||
internal void PlayGames(ICollection<uint> gameIDs) {
|
||||
if (gameIDs == null) {
|
||||
Logging.LogNullError(nameof(gameIDs), Bot.BotName);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!Client.IsConnected) {
|
||||
return;
|
||||
}
|
||||
|
||||
ClientMsgProtobuf<CMsgClientGamesPlayed> request = new ClientMsgProtobuf<CMsgClientGamesPlayed>(EMsg.ClientGamesPlayed);
|
||||
foreach (uint gameID in gameIDs.Where(gameID => gameID != 0)) {
|
||||
request.Body.games_played.Add(new CMsgClientGamesPlayed.GamePlayed {
|
||||
game_id = new GameID(gameID),
|
||||
game_id = new GameID(gameID)
|
||||
});
|
||||
}
|
||||
|
||||
@@ -246,21 +223,27 @@ namespace ArchiSteamFarm {
|
||||
}
|
||||
|
||||
internal async Task<PurchaseResponseCallback> RedeemKey(string key) {
|
||||
if (string.IsNullOrEmpty(key) || !Client.IsConnected) {
|
||||
if (string.IsNullOrEmpty(key)) {
|
||||
Logging.LogNullError(nameof(key), Bot.BotName);
|
||||
return null;
|
||||
}
|
||||
|
||||
var request = new ClientMsgProtobuf<CMsgClientRegisterKey>(EMsg.ClientRegisterKey) {
|
||||
if (!Client.IsConnected) {
|
||||
return null;
|
||||
}
|
||||
|
||||
ClientMsgProtobuf<CMsgClientRegisterKey> request = new ClientMsgProtobuf<CMsgClientRegisterKey>(EMsg.ClientRegisterKey) {
|
||||
SourceJobID = Client.GetNextJobID()
|
||||
};
|
||||
|
||||
request.Body.key = key;
|
||||
|
||||
Client.Send(request);
|
||||
|
||||
try {
|
||||
return await new AsyncJob<PurchaseResponseCallback>(Client, request.SourceJobID);
|
||||
} catch (Exception e) {
|
||||
Logging.LogGenericException(e);
|
||||
Logging.LogGenericException(e, Bot.BotName);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -273,8 +256,11 @@ namespace ArchiSteamFarm {
|
||||
|
||||
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;
|
||||
ClientMsgProtobuf<CMsgClientLogon> logon = new ClientMsgProtobuf<CMsgClientLogon>(EMsg.ClientLogon);
|
||||
if (details.LoginID != null) {
|
||||
logon.Body.obfustucated_private_ip = details.LoginID.Value;
|
||||
}
|
||||
|
||||
logon.ProtoHeader.client_sessionid = 0;
|
||||
logon.ProtoHeader.steamid = steamID.ConvertToUInt64();
|
||||
logon.Body.account_name = details.Username;
|
||||
@@ -306,6 +292,7 @@ namespace ArchiSteamFarm {
|
||||
|
||||
public override void HandleMsg(IPacketMsg packetMsg) {
|
||||
if (packetMsg == null) {
|
||||
Logging.LogNullError(nameof(packetMsg), Bot.BotName);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -316,6 +303,9 @@ namespace ArchiSteamFarm {
|
||||
case EMsg.ClientItemAnnouncements:
|
||||
HandleItemAnnouncements(packetMsg);
|
||||
break;
|
||||
case EMsg.ClientPlayingSessionState:
|
||||
HandlePlayingSessionState(packetMsg);
|
||||
break;
|
||||
case EMsg.ClientPurchaseResponse:
|
||||
HandlePurchaseResponse(packetMsg);
|
||||
break;
|
||||
@@ -327,37 +317,51 @@ namespace ArchiSteamFarm {
|
||||
|
||||
private void HandleFSOfflineMessageNotification(IPacketMsg packetMsg) {
|
||||
if (packetMsg == null) {
|
||||
Logging.LogNullError(nameof(packetMsg), Bot.BotName);
|
||||
return;
|
||||
}
|
||||
|
||||
var response = new ClientMsgProtobuf<CMsgClientOfflineMessageNotification>(packetMsg);
|
||||
ClientMsgProtobuf<CMsgClientOfflineMessageNotification> response = new ClientMsgProtobuf<CMsgClientOfflineMessageNotification>(packetMsg);
|
||||
Client.PostCallback(new OfflineMessageCallback(packetMsg.TargetJobID, response.Body));
|
||||
}
|
||||
|
||||
private void HandleItemAnnouncements(IPacketMsg packetMsg) {
|
||||
if (packetMsg == null) {
|
||||
Logging.LogNullError(nameof(packetMsg), Bot.BotName);
|
||||
return;
|
||||
}
|
||||
|
||||
var response = new ClientMsgProtobuf<CMsgClientItemAnnouncements>(packetMsg);
|
||||
ClientMsgProtobuf<CMsgClientItemAnnouncements> response = new ClientMsgProtobuf<CMsgClientItemAnnouncements>(packetMsg);
|
||||
Client.PostCallback(new NotificationsCallback(packetMsg.TargetJobID, response.Body));
|
||||
}
|
||||
|
||||
private void HandlePlayingSessionState(IPacketMsg packetMsg) {
|
||||
if (packetMsg == null) {
|
||||
Logging.LogNullError(nameof(packetMsg), Bot.BotName);
|
||||
return;
|
||||
}
|
||||
|
||||
ClientMsgProtobuf<CMsgClientPlayingSessionState> response = new ClientMsgProtobuf<CMsgClientPlayingSessionState>(packetMsg);
|
||||
Client.PostCallback(new PlayingSessionStateCallback(packetMsg.TargetJobID, response.Body));
|
||||
}
|
||||
|
||||
private void HandlePurchaseResponse(IPacketMsg packetMsg) {
|
||||
if (packetMsg == null) {
|
||||
Logging.LogNullError(nameof(packetMsg), Bot.BotName);
|
||||
return;
|
||||
}
|
||||
|
||||
var response = new ClientMsgProtobuf<CMsgClientPurchaseResponse>(packetMsg);
|
||||
ClientMsgProtobuf<CMsgClientPurchaseResponse> response = new ClientMsgProtobuf<CMsgClientPurchaseResponse>(packetMsg);
|
||||
Client.PostCallback(new PurchaseResponseCallback(packetMsg.TargetJobID, response.Body));
|
||||
}
|
||||
|
||||
private void HandleUserNotifications(IPacketMsg packetMsg) {
|
||||
if (packetMsg == null) {
|
||||
Logging.LogNullError(nameof(packetMsg), Bot.BotName);
|
||||
return;
|
||||
}
|
||||
|
||||
var response = new ClientMsgProtobuf<CMsgClientUserNotifications>(packetMsg);
|
||||
ClientMsgProtobuf<CMsgClientUserNotifications> response = new ClientMsgProtobuf<CMsgClientUserNotifications>(packetMsg);
|
||||
Client.PostCallback(new NotificationsCallback(packetMsg.TargetJobID, response.Body));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -75,8 +75,8 @@
|
||||
<HintPath>..\packages\HtmlAgilityPack.1.4.9\lib\Net45\HtmlAgilityPack.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<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>
|
||||
<Reference Include="Newtonsoft.Json, Version=9.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Newtonsoft.Json.9.0.1-beta1\lib\net45\Newtonsoft.Json.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<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.Core" />
|
||||
<Reference Include="System.ServiceModel" />
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Net.Http" />
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
@@ -102,10 +99,11 @@
|
||||
<Compile Include="ArchiWebHandler.cs" />
|
||||
<Compile Include="Bot.cs" />
|
||||
<Compile Include="BotConfig.cs" />
|
||||
<Compile Include="ConcurrentEnumerator.cs" />
|
||||
<Compile Include="ConcurrentHashSet.cs" />
|
||||
<Compile Include="GlobalDatabase.cs" />
|
||||
<Compile Include="BotDatabase.cs" />
|
||||
<Compile Include="CardsFarmer.cs" />
|
||||
<Compile Include="CMsgs\CMsgClientClanInviteAction.cs" />
|
||||
<Compile Include="Debugging.cs" />
|
||||
<Compile Include="GlobalConfig.cs" />
|
||||
<Compile Include="JSON\GitHub.cs" />
|
||||
@@ -160,19 +158,19 @@
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<PostBuildEvent Condition=" '$(OS)' != 'Unix' AND '$(ConfigurationName)' == 'Release' ">
|
||||
mkdir "$(SolutionDir)out" "$(SolutionDir)out\config"
|
||||
mkdir "$(SolutionDir)out\config"
|
||||
copy "$(TargetDir)config\ASF.json" "$(SolutionDir)out\config"
|
||||
copy "$(TargetDir)config\example.json" "$(SolutionDir)out\config"
|
||||
copy "$(TargetDir)config\minimal.json" "$(SolutionDir)out\config"
|
||||
"$(SolutionDir)tools\ILRepack.exe" /ndebug /internalize /parallel /targetplatform:v4 /wildcards /out:"$(SolutionDir)out\ASF.exe" "$(TargetDir)$(TargetName).exe" "$(TargetDir)*.dll"
|
||||
"$(SolutionDir)tools\ILRepack\ILRepack.exe" /ndebug /internalize /parallel /targetplatform:v4 /wildcards /out:"$(SolutionDir)out\ASF.exe" "$(TargetDir)$(TargetName).exe" "$(TargetDir)*.dll"
|
||||
del "$(SolutionDir)out\ASF.exe.config"
|
||||
</PostBuildEvent>
|
||||
<PostBuildEvent Condition=" '$(OS)' == 'Unix' AND '$(ConfigurationName)' == 'Release' ">
|
||||
mkdir -p "$(SolutionDir)out" "$(SolutionDir)out/config"
|
||||
mkdir -p "$(SolutionDir)out/config"
|
||||
cp "$(TargetDir)config/ASF.json" "$(SolutionDir)out/config"
|
||||
cp "$(TargetDir)config/example.json" "$(SolutionDir)out/config"
|
||||
cp "$(TargetDir)config/minimal.json" "$(SolutionDir)out/config"
|
||||
mono -O=all "$(SolutionDir)tools/ILRepack.exe" /ndebug /internalize /parallel /targetplatform:v4 /wildcards /out:"$(SolutionDir)out/ASF.exe" "$(TargetDir)$(TargetName).exe" "$(TargetDir)*.dll"
|
||||
mono --llvm --server -O=all "$(SolutionDir)tools/ILRepack/ILRepack.exe" /ndebug /internalize /parallel /targetplatform:v4 /wildcards /out:"$(SolutionDir)out/ASF.exe" "$(TargetDir)$(TargetName).exe" "$(TargetDir)*.dll"
|
||||
rm "$(SolutionDir)out/ASF.exe.config"
|
||||
</PostBuildEvent>
|
||||
</PropertyGroup>
|
||||
|
||||
@@ -27,46 +27,108 @@ using HtmlAgilityPack;
|
||||
using SteamKit2;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Xml;
|
||||
using System.Threading;
|
||||
using ArchiSteamFarm.JSON;
|
||||
|
||||
namespace ArchiSteamFarm {
|
||||
internal sealed class ArchiWebHandler {
|
||||
private const string SteamCommunity = "steamcommunity.com";
|
||||
private const string SteamCommunityHost = "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 = 30 * 1000;
|
||||
private static string SteamCommunityURL = "https://" + SteamCommunityHost;
|
||||
private static int Timeout = GlobalConfig.DefaultHttpTimeout * 1000;
|
||||
|
||||
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() {
|
||||
Timeout = Program.GlobalConfig.HttpTimeout * 1000;
|
||||
SteamCommunityURL = (Program.GlobalConfig.ForceHttp ? "http://" : "https://") + SteamCommunity;
|
||||
SteamCommunityURL = (Program.GlobalConfig.ForceHttp ? "http://" : "https://") + SteamCommunityHost;
|
||||
}
|
||||
|
||||
private static uint GetAppIDFromMarketHashName(string hashName) {
|
||||
if (string.IsNullOrEmpty(hashName)) {
|
||||
Logging.LogNullError(nameof(hashName));
|
||||
return 0;
|
||||
}
|
||||
|
||||
int index = hashName.IndexOf('-');
|
||||
if (index < 1) {
|
||||
Logging.LogNullError(nameof(index));
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint appID;
|
||||
if (uint.TryParse(hashName.Substring(0, index), out appID)) {
|
||||
return appID;
|
||||
}
|
||||
|
||||
Logging.LogNullError(nameof(appID));
|
||||
return 0;
|
||||
}
|
||||
|
||||
private static Steam.Item.EType GetItemType(string name) {
|
||||
if (string.IsNullOrEmpty(name)) {
|
||||
Logging.LogNullError(nameof(name));
|
||||
return Steam.Item.EType.Unknown;
|
||||
}
|
||||
|
||||
switch (name) {
|
||||
case "Booster Pack":
|
||||
return Steam.Item.EType.BoosterPack;
|
||||
case "Coupon":
|
||||
return Steam.Item.EType.Coupon;
|
||||
case "Gift":
|
||||
return Steam.Item.EType.Gift;
|
||||
case "Steam Gems":
|
||||
return Steam.Item.EType.SteamGems;
|
||||
default:
|
||||
if (name.EndsWith("Emoticon", StringComparison.Ordinal)) {
|
||||
return Steam.Item.EType.Emoticon;
|
||||
}
|
||||
|
||||
if (name.EndsWith("Foil Trading Card", StringComparison.Ordinal)) {
|
||||
return Steam.Item.EType.FoilTradingCard;
|
||||
}
|
||||
|
||||
if (name.EndsWith("Profile Background", StringComparison.Ordinal)) {
|
||||
return Steam.Item.EType.ProfileBackground;
|
||||
}
|
||||
|
||||
return name.EndsWith("Trading Card", StringComparison.Ordinal) ? Steam.Item.EType.TradingCard : Steam.Item.EType.Unknown;
|
||||
}
|
||||
}
|
||||
|
||||
internal ArchiWebHandler(Bot bot) {
|
||||
if (bot == null) {
|
||||
return;
|
||||
throw new ArgumentNullException(nameof(bot));
|
||||
}
|
||||
|
||||
Bot = bot;
|
||||
|
||||
WebBrowser = new WebBrowser(bot.BotName);
|
||||
}
|
||||
|
||||
internal async Task<bool> Init(SteamClient steamClient, string webAPIUserNonce, string parentalPin) {
|
||||
if (steamClient == null || steamClient.SteamID == null || string.IsNullOrEmpty(webAPIUserNonce)) {
|
||||
internal bool Init(SteamClient steamClient, string webAPIUserNonce, string parentalPin) {
|
||||
if ((steamClient == null) || string.IsNullOrEmpty(webAPIUserNonce)) {
|
||||
Logging.LogNullError(nameof(steamClient) + " || " + nameof(webAPIUserNonce), Bot.BotName);
|
||||
return false;
|
||||
}
|
||||
|
||||
SteamID = steamClient.SteamID;
|
||||
ulong steamID = steamClient.SteamID;
|
||||
if (steamID == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
string sessionID = Convert.ToBase64String(Encoding.UTF8.GetBytes(SteamID.ToString()));
|
||||
string sessionID = Convert.ToBase64String(Encoding.UTF8.GetBytes(steamID.ToString()));
|
||||
|
||||
// Generate an AES session key
|
||||
byte[] sessionKey = CryptoHelper.GenerateRandomBlock(32);
|
||||
@@ -93,7 +155,7 @@ namespace ArchiSteamFarm {
|
||||
|
||||
try {
|
||||
authResult = iSteamUserAuth.AuthenticateUser(
|
||||
steamid: SteamID,
|
||||
steamid: steamID,
|
||||
sessionkey: Encoding.ASCII.GetString(WebUtility.UrlEncodeToBytes(cryptedSessionKey, 0, cryptedSessionKey.Length)),
|
||||
encrypted_loginkey: Encoding.ASCII.GetString(WebUtility.UrlEncodeToBytes(cryptedLoginKey, 0, cryptedLoginKey.Length)),
|
||||
method: WebRequestMethods.Http.Post,
|
||||
@@ -106,74 +168,91 @@ namespace ArchiSteamFarm {
|
||||
}
|
||||
|
||||
if (authResult == null) {
|
||||
Logging.LogNullError(nameof(authResult), Bot.BotName);
|
||||
return false;
|
||||
}
|
||||
|
||||
Logging.LogGenericInfo("Success!", Bot.BotName);
|
||||
|
||||
string steamLogin = authResult["token"].AsString();
|
||||
string steamLoginSecure = authResult["tokensecure"].AsString();
|
||||
WebBrowser.CookieContainer.Add(new Cookie("sessionid", sessionID, "/", "." + SteamCommunityHost));
|
||||
|
||||
Cookie["sessionid"] = sessionID;
|
||||
Cookie["steamLogin"] = steamLogin;
|
||||
Cookie["steamLoginSecure"] = steamLoginSecure;
|
||||
string steamLogin = authResult["token"].Value;
|
||||
WebBrowser.CookieContainer.Add(new Cookie("steamLogin", steamLogin, "/", "." + SteamCommunityHost));
|
||||
|
||||
// The below is used for display purposes only
|
||||
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}";
|
||||
string steamLoginSecure = authResult["tokensecure"].Value;
|
||||
WebBrowser.CookieContainer.Add(new Cookie("steamLoginSecure", steamLoginSecure, "/", "." + SteamCommunityHost));
|
||||
|
||||
await UnlockParentalAccount(parentalPin).ConfigureAwait(false);
|
||||
return true;
|
||||
}
|
||||
|
||||
internal async Task<bool?> IsLoggedIn() {
|
||||
if (SteamID == 0) {
|
||||
if (!UnlockParentalAccount(parentalPin).Result) {
|
||||
return false;
|
||||
}
|
||||
|
||||
HtmlDocument htmlDocument = null;
|
||||
for (byte i = 0; i < WebBrowser.MaxRetries && htmlDocument == null; i++) {
|
||||
htmlDocument = await WebBrowser.UrlGetToHtmlDocument(SteamCommunityURL + "/my/profile", Cookie).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
if (htmlDocument == null) {
|
||||
Logging.LogGenericWTF("Request failed even after " + WebBrowser.MaxRetries + " tries", Bot.BotName);
|
||||
return null;
|
||||
}
|
||||
|
||||
HtmlNode htmlNode = htmlDocument.DocumentNode.SelectSingleNode("//span[@id='account_pulldown']");
|
||||
return htmlNode != null;
|
||||
LastSessionRefreshCheck = DateTime.Now;
|
||||
return true;
|
||||
}
|
||||
|
||||
internal async Task<bool> ReconnectIfNeeded() {
|
||||
bool? isLoggedIn = await IsLoggedIn().ConfigureAwait(false);
|
||||
if (isLoggedIn.HasValue && !isLoggedIn.Value) {
|
||||
Logging.LogGenericInfo("Reconnecting because our sessionID expired!", Bot.BotName);
|
||||
Bot.RestartIfRunning().Forget();
|
||||
return true;
|
||||
internal async Task<bool> AcceptGift(ulong gid) {
|
||||
if (gid == 0) {
|
||||
Logging.LogNullError(nameof(gid), Bot.BotName);
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
if (!await RefreshSessionIfNeeded().ConfigureAwait(false)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
string sessionID = WebBrowser.CookieContainer.GetCookieValue(SteamCommunityURL, "sessionid");
|
||||
if (string.IsNullOrEmpty(sessionID)) {
|
||||
Logging.LogNullError(nameof(sessionID), Bot.BotName);
|
||||
return false;
|
||||
}
|
||||
|
||||
string request = SteamCommunityURL + "/gifts/" + gid + "/acceptunpack";
|
||||
Dictionary<string, string> data = new Dictionary<string, string>(1) {
|
||||
{ "sessionid", sessionID }
|
||||
};
|
||||
|
||||
return await WebBrowser.UrlPostRetry(request, data).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
internal async Task<bool> JoinGroup(ulong groupID) {
|
||||
if (groupID == 0) {
|
||||
Logging.LogNullError(nameof(groupID), Bot.BotName);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!await RefreshSessionIfNeeded().ConfigureAwait(false)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
string sessionID = WebBrowser.CookieContainer.GetCookieValue(SteamCommunityURL, "sessionid");
|
||||
if (string.IsNullOrEmpty(sessionID)) {
|
||||
Logging.LogNullError(nameof(sessionID), Bot.BotName);
|
||||
return false;
|
||||
}
|
||||
|
||||
string request = SteamCommunityURL + "/gid/" + groupID;
|
||||
Dictionary<string, string> data = new Dictionary<string, string>(2) {
|
||||
{ "sessionID", sessionID },
|
||||
{ "action", "join" }
|
||||
};
|
||||
|
||||
return await WebBrowser.UrlPostRetry(request, data).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
internal async Task<Dictionary<uint, string>> GetOwnedGames() {
|
||||
if (SteamID == 0) {
|
||||
if (!await RefreshSessionIfNeeded().ConfigureAwait(false)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
string request = SteamCommunityURL + "/profiles/" + SteamID + "/games/?xml=1";
|
||||
|
||||
XmlDocument response = null;
|
||||
for (byte i = 0; i < WebBrowser.MaxRetries && response == null; i++) {
|
||||
response = await WebBrowser.UrlGetToXML(request, Cookie).ConfigureAwait(false);
|
||||
}
|
||||
string request = SteamCommunityURL + "/my/games/?xml=1";
|
||||
|
||||
XmlDocument response = await WebBrowser.UrlGetToXMLRetry(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) {
|
||||
if ((xmlNodeList == null) || (xmlNodeList.Count == 0)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -181,16 +260,19 @@ namespace ArchiSteamFarm {
|
||||
foreach (XmlNode xmlNode in xmlNodeList) {
|
||||
XmlNode appNode = xmlNode.SelectSingleNode("appID");
|
||||
if (appNode == null) {
|
||||
Logging.LogNullError(nameof(appNode), Bot.BotName);
|
||||
continue;
|
||||
}
|
||||
|
||||
uint appID;
|
||||
if (!uint.TryParse(appNode.InnerText, out appID)) {
|
||||
Logging.LogNullError(nameof(appID), Bot.BotName);
|
||||
continue;
|
||||
}
|
||||
|
||||
XmlNode nameNode = xmlNode.SelectSingleNode("name");
|
||||
if (nameNode == null) {
|
||||
Logging.LogNullError(nameof(nameNode), Bot.BotName);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -200,8 +282,55 @@ namespace ArchiSteamFarm {
|
||||
return result;
|
||||
}
|
||||
|
||||
internal List<Steam.TradeOffer> GetTradeOffers() {
|
||||
internal Dictionary<uint, string> GetOwnedGames(ulong steamID) {
|
||||
if ((steamID == 0) || string.IsNullOrEmpty(Bot.BotConfig.SteamApiKey)) {
|
||||
// TODO: Correct this when Mono 4.4+ will be a latest stable one | https://bugzilla.xamarin.com/show_bug.cgi?id=39455
|
||||
Logging.LogNullError("steamID || SteamApiKey", Bot.BotName);
|
||||
//Logging.LogNullError(nameof(steamID) + " || " + nameof(Bot.BotConfig.SteamApiKey), Bot.BotName);
|
||||
return null;
|
||||
}
|
||||
|
||||
KeyValue response = null;
|
||||
using (dynamic iPlayerService = WebAPI.GetInterface("IPlayerService", Bot.BotConfig.SteamApiKey)) {
|
||||
iPlayerService.Timeout = Timeout;
|
||||
|
||||
for (byte i = 0; (i < WebBrowser.MaxRetries) && (response == null); i++) {
|
||||
try {
|
||||
response = iPlayerService.GetOwnedGames(
|
||||
steamid: steamID,
|
||||
include_appinfo: 1,
|
||||
secure: !Program.GlobalConfig.ForceHttp
|
||||
);
|
||||
} catch (Exception e) {
|
||||
Logging.LogGenericException(e, Bot.BotName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (response == null) {
|
||||
Logging.LogGenericWTF("Request failed even after " + WebBrowser.MaxRetries + " tries");
|
||||
return null;
|
||||
}
|
||||
|
||||
Dictionary<uint, string> result = new Dictionary<uint, string>(response["games"].Children.Count);
|
||||
foreach (KeyValue game in response["games"].Children) {
|
||||
uint appID = (uint) game["appid"].AsUnsignedLong();
|
||||
if (appID == 0) {
|
||||
Logging.LogNullError(nameof(appID));
|
||||
continue;
|
||||
}
|
||||
|
||||
result[appID] = game["name"].Value;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
internal HashSet<Steam.TradeOffer> GetTradeOffers() {
|
||||
if (string.IsNullOrEmpty(Bot.BotConfig.SteamApiKey)) {
|
||||
// TODO: Correct this when Mono 4.4+ will be a latest stable one | https://bugzilla.xamarin.com/show_bug.cgi?id=39455
|
||||
Logging.LogNullError("SteamApiKey", Bot.BotName);
|
||||
//Logging.LogNullError(nameof(Bot.BotConfig.SteamApiKey), Bot.BotName);
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -209,11 +338,12 @@ namespace ArchiSteamFarm {
|
||||
using (dynamic iEconService = WebAPI.GetInterface("IEconService", Bot.BotConfig.SteamApiKey)) {
|
||||
iEconService.Timeout = Timeout;
|
||||
|
||||
for (byte i = 0; i < WebBrowser.MaxRetries && response == null; i++) {
|
||||
for (byte i = 0; (i < WebBrowser.MaxRetries) && (response == null); i++) {
|
||||
try {
|
||||
response = iEconService.GetTradeOffers(
|
||||
get_received_offers: 1,
|
||||
active_only: 1,
|
||||
get_descriptions: 1,
|
||||
secure: !Program.GlobalConfig.ForceHttp
|
||||
);
|
||||
} catch (Exception e) {
|
||||
@@ -227,212 +357,267 @@ namespace ArchiSteamFarm {
|
||||
return null;
|
||||
}
|
||||
|
||||
List<Steam.TradeOffer> result = new List<Steam.TradeOffer>();
|
||||
Dictionary<ulong, Tuple<uint, Steam.Item.EType>> descriptions = new Dictionary<ulong, Tuple<uint, Steam.Item.EType>>();
|
||||
foreach (KeyValue description in response["descriptions"].Children) {
|
||||
ulong classID = description["classid"].AsUnsignedLong();
|
||||
if (classID == 0) {
|
||||
Logging.LogNullError(nameof(classID), Bot.BotName);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (descriptions.ContainsKey(classID)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
uint appID = 0;
|
||||
Steam.Item.EType type = Steam.Item.EType.Unknown;
|
||||
|
||||
string hashName = description["market_hash_name"].Value;
|
||||
if (!string.IsNullOrEmpty(hashName)) {
|
||||
appID = GetAppIDFromMarketHashName(hashName);
|
||||
}
|
||||
|
||||
string descriptionType = description["type"].Value;
|
||||
if (!string.IsNullOrEmpty(descriptionType)) {
|
||||
type = GetItemType(descriptionType);
|
||||
}
|
||||
|
||||
descriptions[classID] = new Tuple<uint, Steam.Item.EType>(appID, type);
|
||||
}
|
||||
|
||||
HashSet<Steam.TradeOffer> result = new HashSet<Steam.TradeOffer>();
|
||||
foreach (KeyValue trade in response["trade_offers_received"].Children) {
|
||||
Steam.TradeOffer tradeOffer = new Steam.TradeOffer {
|
||||
tradeofferid = trade["tradeofferid"].AsString(),
|
||||
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<Steam.TradeOffer.ETradeOfferState>()
|
||||
TradeOfferID = trade["tradeofferid"].AsUnsignedLong(),
|
||||
OtherSteamID3 = (uint) trade["accountid_other"].AsUnsignedLong(),
|
||||
State = trade["trade_offer_state"].AsEnum<Steam.TradeOffer.ETradeOfferState>()
|
||||
};
|
||||
|
||||
foreach (KeyValue item in trade["items_to_give"].Children) {
|
||||
tradeOffer.items_to_give.Add(new Steam.Item {
|
||||
appid = item["appid"].AsString(),
|
||||
contextid = item["contextid"].AsString(),
|
||||
assetid = item["assetid"].AsString(),
|
||||
classid = item["classid"].AsString(),
|
||||
instanceid = item["instanceid"].AsString(),
|
||||
amount = item["amount"].AsString(),
|
||||
});
|
||||
Steam.Item steamItem = new Steam.Item {
|
||||
AppID = (uint) item["appid"].AsUnsignedLong(),
|
||||
ContextID = item["contextid"].AsUnsignedLong(),
|
||||
AssetID = item["assetid"].AsUnsignedLong(),
|
||||
ClassID = item["classid"].AsUnsignedLong(),
|
||||
InstanceID = item["instanceid"].AsUnsignedLong(),
|
||||
Amount = (uint) item["amount"].AsUnsignedLong()
|
||||
};
|
||||
|
||||
Tuple<uint, Steam.Item.EType> description;
|
||||
if (descriptions.TryGetValue(steamItem.ClassID, out description)) {
|
||||
steamItem.RealAppID = description.Item1;
|
||||
steamItem.Type = description.Item2;
|
||||
}
|
||||
|
||||
tradeOffer.ItemsToGive.Add(steamItem);
|
||||
}
|
||||
|
||||
foreach (KeyValue item in trade["items_to_receive"].Children) {
|
||||
tradeOffer.items_to_receive.Add(new Steam.Item {
|
||||
appid = item["appid"].AsString(),
|
||||
contextid = item["contextid"].AsString(),
|
||||
assetid = item["assetid"].AsString(),
|
||||
classid = item["classid"].AsString(),
|
||||
instanceid = item["instanceid"].AsString(),
|
||||
amount = item["amount"].AsString(),
|
||||
});
|
||||
Steam.Item steamItem = new Steam.Item {
|
||||
AppID = (uint) item["appid"].AsUnsignedLong(),
|
||||
ContextID = item["contextid"].AsUnsignedLong(),
|
||||
AssetID = item["assetid"].AsUnsignedLong(),
|
||||
ClassID = item["classid"].AsUnsignedLong(),
|
||||
InstanceID = item["instanceid"].AsUnsignedLong(),
|
||||
Amount = (uint) item["amount"].AsUnsignedLong()
|
||||
};
|
||||
|
||||
Tuple<uint, Steam.Item.EType> description;
|
||||
if (descriptions.TryGetValue(steamItem.ClassID, out description)) {
|
||||
steamItem.RealAppID = description.Item1;
|
||||
steamItem.Type = description.Item2;
|
||||
}
|
||||
|
||||
tradeOffer.ItemsToReceive.Add(steamItem);
|
||||
}
|
||||
|
||||
result.Add(tradeOffer);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
internal async Task<bool> JoinClan(ulong clanID) {
|
||||
if (clanID == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
string sessionID;
|
||||
if (!Cookie.TryGetValue("sessionid", out sessionID)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
string request = SteamCommunityURL + "/gid/" + clanID;
|
||||
|
||||
Dictionary<string, string> data = new Dictionary<string, string>(2) {
|
||||
{"sessionID", sessionID},
|
||||
{"action", "join"}
|
||||
};
|
||||
|
||||
HttpResponseMessage response = null;
|
||||
for (byte i = 0; i < WebBrowser.MaxRetries && response == null; i++) {
|
||||
response = await WebBrowser.UrlPost(request, data, Cookie).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
if (response == null) {
|
||||
Logging.LogGenericWTF("Request failed even after " + WebBrowser.MaxRetries + " tries", Bot.BotName);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
internal async Task<bool> AcceptTradeOffer(ulong tradeID) {
|
||||
if (tradeID == 0) {
|
||||
Logging.LogNullError(nameof(tradeID), Bot.BotName);
|
||||
return false;
|
||||
}
|
||||
|
||||
string sessionID;
|
||||
if (!Cookie.TryGetValue("sessionid", out sessionID)) {
|
||||
if (!await RefreshSessionIfNeeded().ConfigureAwait(false)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
string sessionID = WebBrowser.CookieContainer.GetCookieValue(SteamCommunityURL, "sessionid");
|
||||
if (string.IsNullOrEmpty(sessionID)) {
|
||||
Logging.LogNullError(nameof(sessionID), Bot.BotName);
|
||||
return false;
|
||||
}
|
||||
|
||||
string referer = SteamCommunityURL + "/tradeoffer/" + tradeID;
|
||||
string request = referer + "/accept";
|
||||
|
||||
Dictionary<string, string> data = new Dictionary<string, string>(3) {
|
||||
{"sessionid", sessionID},
|
||||
{"serverid", "1"},
|
||||
{"tradeofferid", tradeID.ToString()}
|
||||
{ "sessionid", sessionID },
|
||||
{ "serverid", "1" },
|
||||
{ "tradeofferid", tradeID.ToString() }
|
||||
};
|
||||
|
||||
HttpResponseMessage response = null;
|
||||
for (byte i = 0; i < WebBrowser.MaxRetries && response == null; i++) {
|
||||
response = await WebBrowser.UrlPost(request, data, Cookie, referer).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
if (response == null) {
|
||||
Logging.LogGenericWTF("Request failed even after " + WebBrowser.MaxRetries + " tries", Bot.BotName);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
return await WebBrowser.UrlPostRetry(request, data, referer).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
internal bool DeclineTradeOffer(ulong tradeID) {
|
||||
if (tradeID == 0 || string.IsNullOrEmpty(Bot.BotConfig.SteamApiKey)) {
|
||||
return false;
|
||||
internal async Task<HashSet<Steam.Item>> GetMyTradableInventory() {
|
||||
if (!await RefreshSessionIfNeeded().ConfigureAwait(false)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
KeyValue response = null;
|
||||
using (dynamic iEconService = WebAPI.GetInterface("IEconService", Bot.BotConfig.SteamApiKey)) {
|
||||
iEconService.Timeout = Timeout;
|
||||
HashSet<Steam.Item> result = new HashSet<Steam.Item>();
|
||||
|
||||
for (byte i = 0; i < WebBrowser.MaxRetries && response == null; i++) {
|
||||
try {
|
||||
response = iEconService.DeclineTradeOffer(
|
||||
tradeofferid: tradeID.ToString(),
|
||||
method: WebRequestMethods.Http.Post,
|
||||
secure: !Program.GlobalConfig.ForceHttp
|
||||
);
|
||||
} catch (Exception e) {
|
||||
Logging.LogGenericException(e, Bot.BotName);
|
||||
ushort nextPage = 0;
|
||||
while (true) {
|
||||
string request = SteamCommunityURL + "/my/inventory/json/" + Steam.Item.SteamAppID + "/" + Steam.Item.SteamContextID + "?trading=1&start=" + nextPage;
|
||||
|
||||
JObject jObject = await WebBrowser.UrlGetToJObjectRetry(request).ConfigureAwait(false);
|
||||
if (jObject == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
IEnumerable<JToken> descriptions = jObject.SelectTokens("$.rgDescriptions.*");
|
||||
if (descriptions == null) {
|
||||
return null; // OK, empty inventory
|
||||
}
|
||||
|
||||
Dictionary<ulong, Tuple<uint, Steam.Item.EType>> descriptionMap = new Dictionary<ulong, Tuple<uint, Steam.Item.EType>>();
|
||||
foreach (JToken description in descriptions) {
|
||||
string classIDString = description["classid"].ToString();
|
||||
if (string.IsNullOrEmpty(classIDString)) {
|
||||
Logging.LogNullError(nameof(classIDString), Bot.BotName);
|
||||
continue;
|
||||
}
|
||||
|
||||
ulong classID;
|
||||
if (!ulong.TryParse(classIDString, out classID) || (classID == 0)) {
|
||||
Logging.LogNullError(nameof(classID), Bot.BotName);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (descriptionMap.ContainsKey(classID)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
uint appID = 0;
|
||||
Steam.Item.EType type = Steam.Item.EType.Unknown;
|
||||
|
||||
string hashName = description["market_hash_name"].ToString();
|
||||
if (!string.IsNullOrEmpty(hashName)) {
|
||||
appID = GetAppIDFromMarketHashName(hashName);
|
||||
}
|
||||
|
||||
string descriptionType = description["type"].ToString();
|
||||
if (!string.IsNullOrEmpty(descriptionType)) {
|
||||
type = GetItemType(descriptionType);
|
||||
}
|
||||
|
||||
descriptionMap[classID] = new Tuple<uint, Steam.Item.EType>(appID, type);
|
||||
}
|
||||
}
|
||||
|
||||
if (response == null) {
|
||||
Logging.LogGenericWTF("Request failed even after " + WebBrowser.MaxRetries + " tries", Bot.BotName);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
internal async Task<List<Steam.Item>> GetMyTradableInventory() {
|
||||
JObject jObject = null;
|
||||
for (byte i = 0; i < WebBrowser.MaxRetries && jObject == null; i++) {
|
||||
jObject = await WebBrowser.UrlGetToJObject(SteamCommunityURL + "/my/inventory/json/753/6?trading=1", Cookie).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
if (jObject == null) {
|
||||
Logging.LogGenericWTF("Request failed even after " + WebBrowser.MaxRetries + " tries", Bot.BotName);
|
||||
return null;
|
||||
}
|
||||
|
||||
IEnumerable<JToken> jTokens = jObject.SelectTokens("$.rgInventory.*");
|
||||
if (jTokens == null) {
|
||||
Logging.LogNullError("jTokens", Bot.BotName);
|
||||
return null;
|
||||
}
|
||||
|
||||
List<Steam.Item> result = new List<Steam.Item>();
|
||||
foreach (JToken jToken in jTokens) {
|
||||
try {
|
||||
result.Add(JsonConvert.DeserializeObject<Steam.Item>(jToken.ToString()));
|
||||
} catch (Exception e) {
|
||||
Logging.LogGenericException(e, Bot.BotName);
|
||||
IEnumerable<JToken> items = jObject.SelectTokens("$.rgInventory.*");
|
||||
if (items == null) {
|
||||
Logging.LogNullError(nameof(items), Bot.BotName);
|
||||
return null;
|
||||
}
|
||||
|
||||
foreach (JToken item in items) {
|
||||
|
||||
Steam.Item steamItem;
|
||||
|
||||
try {
|
||||
steamItem = JsonConvert.DeserializeObject<Steam.Item>(item.ToString());
|
||||
} catch (JsonException e) {
|
||||
Logging.LogGenericException(e, Bot.BotName);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (steamItem == null) {
|
||||
Logging.LogNullError(nameof(steamItem), Bot.BotName);
|
||||
continue;
|
||||
}
|
||||
|
||||
Tuple<uint, Steam.Item.EType> description;
|
||||
if (descriptionMap.TryGetValue(steamItem.ClassID, out description)) {
|
||||
steamItem.RealAppID = description.Item1;
|
||||
steamItem.Type = description.Item2;
|
||||
}
|
||||
|
||||
result.Add(steamItem);
|
||||
}
|
||||
|
||||
bool more;
|
||||
if (!bool.TryParse(jObject["more"].ToString(), out more) || !more) {
|
||||
break; // OK, last page
|
||||
}
|
||||
|
||||
if (ushort.TryParse(jObject["more_start"].ToString(), out nextPage)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Logging.LogNullError(nameof(nextPage), Bot.BotName);
|
||||
break;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
internal async Task<bool> SendTradeOffer(List<Steam.Item> inventory, ulong partnerID, string token = null) {
|
||||
if (inventory == null || inventory.Count == 0 || partnerID == 0) {
|
||||
internal async Task<bool> SendTradeOffer(HashSet<Steam.Item> inventory, ulong partnerID, string token = null) {
|
||||
if ((inventory == null) || (inventory.Count == 0) || (partnerID == 0)) {
|
||||
Logging.LogNullError(nameof(inventory) + " || " + nameof(inventory.Count) + " || " + nameof(partnerID), Bot.BotName);
|
||||
return false;
|
||||
}
|
||||
|
||||
string sessionID;
|
||||
if (!Cookie.TryGetValue("sessionid", out sessionID)) {
|
||||
if (!await RefreshSessionIfNeeded().ConfigureAwait(false)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
List<Steam.TradeOfferRequest> trades = new List<Steam.TradeOfferRequest>(1 + inventory.Count / Trading.MaxItemsPerTrade);
|
||||
string sessionID = WebBrowser.CookieContainer.GetCookieValue(SteamCommunityURL, "sessionid");
|
||||
if (string.IsNullOrEmpty(sessionID)) {
|
||||
Logging.LogNullError(nameof(sessionID), Bot.BotName);
|
||||
return false;
|
||||
}
|
||||
|
||||
Steam.TradeOfferRequest singleTrade = null;
|
||||
for (ushort i = 0; i < inventory.Count; i++) {
|
||||
if (i % Trading.MaxItemsPerTrade == 0) {
|
||||
Steam.TradeOfferRequest singleTrade = new Steam.TradeOfferRequest();
|
||||
HashSet<Steam.TradeOfferRequest> trades = new HashSet<Steam.TradeOfferRequest> { singleTrade };
|
||||
|
||||
byte itemID = 0;
|
||||
foreach (Steam.Item item in inventory) {
|
||||
if (itemID >= Trading.MaxItemsPerTrade) {
|
||||
if (trades.Count >= Trading.MaxTradesPerAccount) {
|
||||
break;
|
||||
}
|
||||
|
||||
singleTrade = new Steam.TradeOfferRequest();
|
||||
trades.Add(singleTrade);
|
||||
itemID = 0;
|
||||
}
|
||||
|
||||
Steam.Item item = inventory[i];
|
||||
singleTrade.me.assets.Add(new Steam.Item() {
|
||||
appid = "753",
|
||||
contextid = "6",
|
||||
amount = item.amount,
|
||||
assetid = item.id
|
||||
singleTrade.ItemsToGive.Assets.Add(new Steam.Item {
|
||||
AppID = Steam.Item.SteamAppID,
|
||||
ContextID = Steam.Item.SteamContextID,
|
||||
Amount = item.Amount,
|
||||
AssetID = item.AssetID
|
||||
});
|
||||
|
||||
itemID++;
|
||||
}
|
||||
|
||||
string referer = SteamCommunityURL + "/tradeoffer/new";
|
||||
string request = referer + "/send";
|
||||
|
||||
foreach (Steam.TradeOfferRequest trade in trades) {
|
||||
Dictionary<string, string> data = new Dictionary<string, string>(6) {
|
||||
{"sessionid", sessionID},
|
||||
{"serverid", "1"},
|
||||
{"partner", partnerID.ToString()},
|
||||
{"tradeoffermessage", "Sent by ASF"},
|
||||
{"json_tradeoffer", JsonConvert.SerializeObject(trade)},
|
||||
{"trade_offer_create_params", string.IsNullOrEmpty(token) ? "" : $"{{\"trade_offer_access_token\":\"{token}\"}}"}
|
||||
};
|
||||
|
||||
HttpResponseMessage response = null;
|
||||
for (byte i = 0; i < WebBrowser.MaxRetries && response == null; i++) {
|
||||
response = await WebBrowser.UrlPost(request, data, Cookie, referer).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
if (response == null) {
|
||||
Logging.LogGenericWTF("Request failed even after " + WebBrowser.MaxRetries + " tries", Bot.BotName);
|
||||
foreach (Dictionary<string, string> data in trades.Select(trade => new Dictionary<string, string>(6) {
|
||||
{ "sessionid", sessionID },
|
||||
{ "serverid", "1" },
|
||||
{ "partner", partnerID.ToString() },
|
||||
{ "tradeoffermessage", "Sent by ASF" },
|
||||
{ "json_tradeoffer", JsonConvert.SerializeObject(trade) },
|
||||
{ "trade_offer_create_params", string.IsNullOrEmpty(token) ? "" : $"{{\"trade_offer_access_token\":\"{token}\"}}" }
|
||||
})) {
|
||||
if (!await WebBrowser.UrlPostRetry(request, data, referer).ConfigureAwait(false)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -441,106 +626,110 @@ namespace ArchiSteamFarm {
|
||||
}
|
||||
|
||||
internal async Task<HtmlDocument> GetBadgePage(byte page) {
|
||||
if (page == 0 || SteamID == 0) {
|
||||
if (page == 0) {
|
||||
Logging.LogNullError(nameof(page), Bot.BotName);
|
||||
return null;
|
||||
}
|
||||
|
||||
HtmlDocument htmlDocument = null;
|
||||
for (byte i = 0; i < WebBrowser.MaxRetries && htmlDocument == null; i++) {
|
||||
htmlDocument = await WebBrowser.UrlGetToHtmlDocument(SteamCommunityURL + "/profiles/" + SteamID + "/badges?l=english&p=" + page, Cookie).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
if (htmlDocument == null) {
|
||||
Logging.LogGenericWTF("Request failed even after " + WebBrowser.MaxRetries + " tries", Bot.BotName);
|
||||
if (!await RefreshSessionIfNeeded().ConfigureAwait(false)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return htmlDocument;
|
||||
string request = SteamCommunityURL + "/my/badges?p=" + page;
|
||||
|
||||
return await WebBrowser.UrlGetToHtmlDocumentRetry(request).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
internal async Task<HtmlDocument> GetGameCardsPage(ulong appID) {
|
||||
if (appID == 0 || SteamID == 0) {
|
||||
if (appID == 0) {
|
||||
Logging.LogNullError(nameof(appID), Bot.BotName);
|
||||
return null;
|
||||
}
|
||||
|
||||
HtmlDocument htmlDocument = null;
|
||||
for (byte i = 0; i < WebBrowser.MaxRetries && htmlDocument == null; i++) {
|
||||
htmlDocument = await WebBrowser.UrlGetToHtmlDocument(SteamCommunityURL + "/profiles/" + SteamID + "/gamecards/" + appID + "?l=english", Cookie).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
if (htmlDocument == null) {
|
||||
Logging.LogGenericWTF("Request failed even after " + WebBrowser.MaxRetries + " tries", Bot.BotName);
|
||||
if (!await RefreshSessionIfNeeded().ConfigureAwait(false)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return htmlDocument;
|
||||
string request = SteamCommunityURL + "/my/gamecards/" + appID;
|
||||
|
||||
return await WebBrowser.UrlGetToHtmlDocumentRetry(request).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
internal async Task<bool> MarkInventory() {
|
||||
if (SteamID == 0) {
|
||||
if (!await RefreshSessionIfNeeded().ConfigureAwait(false)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
HttpResponseMessage response = null;
|
||||
for (byte i = 0; i < WebBrowser.MaxRetries && response == null; i++) {
|
||||
response = await WebBrowser.UrlGet(SteamCommunityURL + "/profiles/" + SteamID + "/inventory", Cookie).ConfigureAwait(false);
|
||||
}
|
||||
string request = SteamCommunityURL + "/my/inventory";
|
||||
|
||||
if (response == null) {
|
||||
Logging.LogGenericWTF("Request failed even after " + WebBrowser.MaxRetries + " tries", Bot.BotName);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
return await WebBrowser.UrlHeadRetry(request).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
private async Task UnlockParentalAccount(string parentalPin) {
|
||||
if (string.IsNullOrEmpty(parentalPin) || parentalPin.Equals("0")) {
|
||||
return;
|
||||
private async Task<bool?> IsLoggedIn() {
|
||||
// It would make sense to use /my/profile here, but it dismisses notifications related to profile comments
|
||||
// So instead, we'll use some less intrusive link, such as /my/videos
|
||||
string request = SteamCommunityURL + "/my/videos";
|
||||
|
||||
Uri uri = await WebBrowser.UrlHeadToUriRetry(request).ConfigureAwait(false);
|
||||
if (uri == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return !uri.AbsolutePath.StartsWith("/login", StringComparison.Ordinal);
|
||||
}
|
||||
|
||||
private async Task<bool> RefreshSessionIfNeeded() {
|
||||
if (DateTime.Now.Subtract(LastSessionRefreshCheck).TotalSeconds < MinSessionTTL) {
|
||||
return true;
|
||||
}
|
||||
|
||||
await SessionSemaphore.WaitAsync().ConfigureAwait(false);
|
||||
|
||||
if (DateTime.Now.Subtract(LastSessionRefreshCheck).TotalSeconds < MinSessionTTL) {
|
||||
SessionSemaphore.Release();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool result;
|
||||
|
||||
bool? isLoggedIn = await IsLoggedIn().ConfigureAwait(false);
|
||||
if (isLoggedIn.GetValueOrDefault(true)) {
|
||||
result = true;
|
||||
LastSessionRefreshCheck = DateTime.Now;
|
||||
} else {
|
||||
Logging.LogGenericInfo("Refreshing our session!", Bot.BotName);
|
||||
result = await Bot.RefreshSession().ConfigureAwait(false);
|
||||
}
|
||||
|
||||
SessionSemaphore.Release();
|
||||
return result;
|
||||
}
|
||||
|
||||
private async Task<bool> UnlockParentalAccount(string parentalPin) {
|
||||
if (string.IsNullOrEmpty(parentalPin)) {
|
||||
Logging.LogNullError(nameof(parentalPin), Bot.BotName);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (parentalPin.Equals("0")) {
|
||||
return true;
|
||||
}
|
||||
|
||||
Logging.LogGenericInfo("Unlocking parental account...", Bot.BotName);
|
||||
|
||||
string request = SteamCommunityURL + "/parental/ajaxunlock";
|
||||
Dictionary<string, string> data = new Dictionary<string, string>(1) {
|
||||
{ "pin", parentalPin }
|
||||
};
|
||||
|
||||
string referer = SteamCommunityURL;
|
||||
string request = referer + "/parental/ajaxunlock";
|
||||
|
||||
HttpResponseMessage response = null;
|
||||
for (byte i = 0; i < WebBrowser.MaxRetries && response == null; i++) {
|
||||
response = await WebBrowser.UrlPost(request, data, Cookie, referer).ConfigureAwait(false);
|
||||
bool result = await WebBrowser.UrlPostRetry(request, data, SteamCommunityURL).ConfigureAwait(false);
|
||||
if (!result) {
|
||||
Logging.LogGenericInfo("Failed!", Bot.BotName);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (response == null) {
|
||||
Logging.LogGenericWTF("Request failed even after " + WebBrowser.MaxRetries + " tries", Bot.BotName);
|
||||
return;
|
||||
}
|
||||
|
||||
IEnumerable<string> setCookieValues;
|
||||
if (!response.Headers.TryGetValues("Set-Cookie", out setCookieValues)) {
|
||||
Logging.LogNullError("setCookieValues", Bot.BotName);
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (string setCookieValue in setCookieValues) {
|
||||
if (!setCookieValue.Contains("steamparental=")) {
|
||||
continue;
|
||||
}
|
||||
|
||||
string setCookie = setCookieValue.Substring(setCookieValue.IndexOf("steamparental=", StringComparison.Ordinal) + 14);
|
||||
|
||||
int index = setCookie.IndexOf(';');
|
||||
if (index > 0) {
|
||||
setCookie = setCookie.Substring(0, index);
|
||||
}
|
||||
|
||||
Cookie["steamparental"] = setCookie;
|
||||
Logging.LogGenericInfo("Success!", Bot.BotName);
|
||||
return;
|
||||
}
|
||||
|
||||
Logging.LogGenericWarning("Failed to unlock parental account!", Bot.BotName);
|
||||
Logging.LogGenericInfo("Success!", Bot.BotName);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -26,9 +26,10 @@ using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Xml;
|
||||
|
||||
namespace ArchiSteamFarm {
|
||||
// ReSharper disable once ClassCannotBeInstantiated
|
||||
// ReSharper disable once ClassNeverInstantiated.Global
|
||||
internal sealed class BotConfig {
|
||||
[JsonProperty(Required = Required.DisallowNull)]
|
||||
internal bool Enabled { get; private set; } = false;
|
||||
@@ -37,10 +38,10 @@ namespace ArchiSteamFarm {
|
||||
internal bool StartOnLaunch { get; private set; } = true;
|
||||
|
||||
[JsonProperty]
|
||||
internal string SteamLogin { get; set; } = null;
|
||||
internal string SteamLogin { get; set; }
|
||||
|
||||
[JsonProperty]
|
||||
internal string SteamPassword { get; set; } = null;
|
||||
internal string SteamPassword { get; set; }
|
||||
|
||||
[JsonProperty]
|
||||
internal string SteamParentalPIN { get; set; } = "0";
|
||||
@@ -66,6 +67,12 @@ namespace ArchiSteamFarm {
|
||||
[JsonProperty(Required = Required.DisallowNull)]
|
||||
internal bool HandleOfflineMessages { get; private set; } = false;
|
||||
|
||||
[JsonProperty(Required = Required.DisallowNull)]
|
||||
internal bool AcceptGifts { get; private set; } = false;
|
||||
|
||||
[JsonProperty(Required = Required.DisallowNull)]
|
||||
internal bool SteamTradeMatcher { get; private set; } = false;
|
||||
|
||||
[JsonProperty(Required = Required.DisallowNull)]
|
||||
internal bool ForwardKeysToOtherBots { get; private set; } = false;
|
||||
|
||||
@@ -94,17 +101,23 @@ namespace ArchiSteamFarm {
|
||||
internal string CustomGamePlayedWhileIdle { get; private set; } = null;
|
||||
|
||||
[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 };
|
||||
|
||||
|
||||
internal static BotConfig Load(string path) {
|
||||
if (!File.Exists(path)) {
|
||||
internal static BotConfig Load(string filePath) {
|
||||
if (string.IsNullOrEmpty(filePath)) {
|
||||
Logging.LogNullError(nameof(filePath));
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!File.Exists(filePath)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
BotConfig botConfig;
|
||||
|
||||
try {
|
||||
botConfig = JsonConvert.DeserializeObject<BotConfig>(File.ReadAllText(path));
|
||||
botConfig = JsonConvert.DeserializeObject<BotConfig>(File.ReadAllText(filePath));
|
||||
} catch (Exception e) {
|
||||
Logging.LogGenericException(e);
|
||||
return null;
|
||||
@@ -113,146 +126,7 @@ namespace ArchiSteamFarm {
|
||||
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":
|
||||
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
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
using Newtonsoft.Json;
|
||||
using SteamAuth;
|
||||
using System;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.IO;
|
||||
|
||||
namespace ArchiSteamFarm {
|
||||
@@ -66,11 +67,17 @@ namespace ArchiSteamFarm {
|
||||
private string FilePath;
|
||||
|
||||
internal static BotDatabase Load(string filePath) {
|
||||
if (string.IsNullOrEmpty(filePath)) {
|
||||
Logging.LogNullError(nameof(filePath));
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!File.Exists(filePath)) {
|
||||
return new BotDatabase(filePath);
|
||||
}
|
||||
|
||||
BotDatabase botDatabase;
|
||||
|
||||
try {
|
||||
botDatabase = JsonConvert.DeserializeObject<BotDatabase>(File.ReadAllText(filePath));
|
||||
} catch (Exception e) {
|
||||
@@ -78,17 +85,27 @@ namespace ArchiSteamFarm {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (botDatabase == null) {
|
||||
Logging.LogNullError(nameof(botDatabase));
|
||||
return null;
|
||||
}
|
||||
|
||||
botDatabase.FilePath = filePath;
|
||||
return botDatabase;
|
||||
}
|
||||
|
||||
// This constructor is used when creating new database
|
||||
private BotDatabase(string filePath) {
|
||||
if (string.IsNullOrEmpty(filePath)) {
|
||||
throw new ArgumentNullException(nameof(filePath));
|
||||
}
|
||||
|
||||
FilePath = filePath;
|
||||
Save();
|
||||
}
|
||||
|
||||
// This constructor is used only by deserializer
|
||||
[SuppressMessage("ReSharper", "UnusedMember.Local")]
|
||||
private BotDatabase() { }
|
||||
|
||||
internal void Save() {
|
||||
|
||||
@@ -35,23 +35,25 @@ using System.Threading.Tasks;
|
||||
namespace ArchiSteamFarm {
|
||||
internal sealed class CardsFarmer {
|
||||
internal readonly ConcurrentDictionary<uint, float> GamesToFarm = new ConcurrentDictionary<uint, float>();
|
||||
internal readonly HashSet<uint> CurrentGamesFarming = new HashSet<uint>();
|
||||
internal readonly ConcurrentHashSet<uint> CurrentGamesFarming = new ConcurrentHashSet<uint>();
|
||||
|
||||
private readonly ManualResetEvent FarmResetEvent = new ManualResetEvent(false);
|
||||
private readonly SemaphoreSlim Semaphore = new SemaphoreSlim(1);
|
||||
private readonly ManualResetEventSlim FarmResetEvent = new ManualResetEventSlim(false);
|
||||
private readonly SemaphoreSlim FarmingSemaphore = new SemaphoreSlim(1);
|
||||
private readonly Bot Bot;
|
||||
private readonly Timer Timer;
|
||||
|
||||
private volatile bool ManualMode, NowFarming;
|
||||
internal bool ManualMode { get; private set; }
|
||||
|
||||
private bool NowFarming;
|
||||
|
||||
internal CardsFarmer(Bot bot) {
|
||||
if (bot == null) {
|
||||
return;
|
||||
throw new ArgumentNullException(nameof(bot));
|
||||
}
|
||||
|
||||
Bot = bot;
|
||||
|
||||
if (Program.GlobalConfig.IdleFarmingPeriod > 0) {
|
||||
if ((Timer == null) && (Program.GlobalConfig.IdleFarmingPeriod > 0)) {
|
||||
Timer = new Timer(
|
||||
async e => await CheckGamesForFarming().ConfigureAwait(false),
|
||||
null,
|
||||
@@ -61,9 +63,9 @@ namespace ArchiSteamFarm {
|
||||
}
|
||||
}
|
||||
|
||||
internal async Task<bool> SwitchToManualMode(bool manualMode) {
|
||||
internal async Task SwitchToManualMode(bool manualMode) {
|
||||
if (ManualMode == manualMode) {
|
||||
return false;
|
||||
return;
|
||||
}
|
||||
|
||||
ManualMode = manualMode;
|
||||
@@ -75,88 +77,84 @@ namespace ArchiSteamFarm {
|
||||
Logging.LogGenericInfo("Now running in Automatic Farming mode", Bot.BotName);
|
||||
StartFarming().Forget();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
internal async Task StartFarming() {
|
||||
if (NowFarming || ManualMode) {
|
||||
if (NowFarming || ManualMode || Bot.PlayingBlocked) {
|
||||
return;
|
||||
}
|
||||
|
||||
await Semaphore.WaitAsync().ConfigureAwait(false);
|
||||
await FarmingSemaphore.WaitAsync().ConfigureAwait(false);
|
||||
|
||||
if (NowFarming || ManualMode) {
|
||||
Semaphore.Release(); // We have nothing to do, don't forget to release semaphore
|
||||
if (NowFarming || ManualMode || Bot.PlayingBlocked) {
|
||||
FarmingSemaphore.Release(); // We have nothing to do, don't forget to release semaphore
|
||||
return;
|
||||
}
|
||||
|
||||
if (!await IsAnythingToFarm().ConfigureAwait(false)) {
|
||||
Semaphore.Release(); // We have nothing to do, don't forget to release semaphore
|
||||
FarmingSemaphore.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;
|
||||
}
|
||||
|
||||
Logging.LogGenericInfo("We have a total of " + GamesToFarm.Count + " games to farm on this account...", Bot.BotName);
|
||||
|
||||
// This is the last moment for final check if we can farm
|
||||
if (Bot.PlayingBlocked) {
|
||||
Logging.LogGenericInfo("But account is currently occupied, so farming is stopped!");
|
||||
FarmingSemaphore.Release(); // We have nothing to do, don't forget to release semaphore
|
||||
return;
|
||||
}
|
||||
|
||||
NowFarming = true;
|
||||
Semaphore.Release(); // From this point we allow other calls to shut us down
|
||||
FarmingSemaphore.Release(); // From this point we allow other calls to shut us down
|
||||
|
||||
bool farmedSomething = false;
|
||||
|
||||
// Now the algorithm used for farming depends on whether account is restricted or not
|
||||
if (Bot.BotConfig.CardDropsRestricted) { // If we have restricted card drops, we use complex algorithm
|
||||
Logging.LogGenericInfo("Chosen farming algorithm: Complex", Bot.BotName);
|
||||
while (GamesToFarm.Count > 0) {
|
||||
HashSet<uint> gamesToFarmSolo = GetGamesToFarmSolo(GamesToFarm);
|
||||
if (gamesToFarmSolo.Count > 0) {
|
||||
while (gamesToFarmSolo.Count > 0) {
|
||||
uint appID = gamesToFarmSolo.First();
|
||||
if (await FarmSolo(appID).ConfigureAwait(false)) {
|
||||
farmedSomething = true;
|
||||
Logging.LogGenericInfo("Done farming: " + appID, Bot.BotName);
|
||||
gamesToFarmSolo.Remove(appID);
|
||||
gamesToFarmSolo.TrimExcess();
|
||||
do {
|
||||
// Now the algorithm used for farming depends on whether account is restricted or not
|
||||
if (Bot.BotConfig.CardDropsRestricted) { // If we have restricted card drops, we use complex algorithm
|
||||
Logging.LogGenericInfo("Chosen farming algorithm: Complex", Bot.BotName);
|
||||
while (GamesToFarm.Count > 0) {
|
||||
HashSet<uint> gamesToFarmSolo = GetGamesToFarmSolo(GamesToFarm);
|
||||
if (gamesToFarmSolo.Count > 0) {
|
||||
while (gamesToFarmSolo.Count > 0) {
|
||||
uint appID = gamesToFarmSolo.First();
|
||||
if (await FarmSolo(appID).ConfigureAwait(false)) {
|
||||
gamesToFarmSolo.Remove(appID);
|
||||
gamesToFarmSolo.TrimExcess();
|
||||
} else {
|
||||
NowFarming = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (FarmMultiple()) {
|
||||
Logging.LogGenericInfo("Done farming: " + string.Join(", ", GamesToFarm.Keys), Bot.BotName);
|
||||
} else {
|
||||
NowFarming = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (FarmMultiple(GamesToFarm)) {
|
||||
Logging.LogGenericInfo("Done farming: " + string.Join(", ", GamesToFarm.Keys), Bot.BotName);
|
||||
} else {
|
||||
NowFarming = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else { // If we have unrestricted card drops, we use simple algorithm
|
||||
Logging.LogGenericInfo("Chosen farming algorithm: Simple", Bot.BotName);
|
||||
while (GamesToFarm.Count > 0) {
|
||||
uint appID = GetAnyGameToFarm(GamesToFarm);
|
||||
if (await FarmSolo(appID).ConfigureAwait(false)) {
|
||||
farmedSomething = true;
|
||||
Logging.LogGenericInfo("Done farming: " + appID, Bot.BotName);
|
||||
} else {
|
||||
} 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)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
NowFarming = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
} while (await IsAnythingToFarm().ConfigureAwait(false));
|
||||
|
||||
CurrentGamesFarming.Clear();
|
||||
CurrentGamesFarming.TrimExcess();
|
||||
CurrentGamesFarming.ClearAndTrim();
|
||||
NowFarming = false;
|
||||
|
||||
// We finished our queue for now, make sure that everything is indeed farmed before proceeding further
|
||||
// Some games could be added in the meantime
|
||||
if (await IsAnythingToFarm().ConfigureAwait(false)) {
|
||||
StartFarming().Forget();
|
||||
return;
|
||||
}
|
||||
|
||||
Logging.LogGenericInfo("Farming finished!", Bot.BotName);
|
||||
await Bot.OnFarmingFinished(farmedSomething).ConfigureAwait(false);
|
||||
await Bot.OnFarmingFinished(true).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
internal async Task StopFarming() {
|
||||
@@ -164,10 +162,10 @@ namespace ArchiSteamFarm {
|
||||
return;
|
||||
}
|
||||
|
||||
await Semaphore.WaitAsync().ConfigureAwait(false);
|
||||
await FarmingSemaphore.WaitAsync().ConfigureAwait(false);
|
||||
|
||||
if (!NowFarming) {
|
||||
Semaphore.Release();
|
||||
FarmingSemaphore.Release();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -175,7 +173,7 @@ namespace ArchiSteamFarm {
|
||||
FarmResetEvent.Set();
|
||||
|
||||
Logging.LogGenericInfo("Waiting for reaction...", Bot.BotName);
|
||||
for (byte i = 0; i < Program.GlobalConfig.HttpTimeout && NowFarming; i++) {
|
||||
for (byte i = 0; (i < Program.GlobalConfig.HttpTimeout) && NowFarming; i++) {
|
||||
await Utilities.SleepAsync(1000).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
@@ -185,7 +183,7 @@ namespace ArchiSteamFarm {
|
||||
|
||||
FarmResetEvent.Reset();
|
||||
Logging.LogGenericInfo("Farming stopped!", Bot.BotName);
|
||||
Semaphore.Release();
|
||||
FarmingSemaphore.Release();
|
||||
}
|
||||
|
||||
internal async Task RestartFarming() {
|
||||
@@ -195,36 +193,19 @@ namespace ArchiSteamFarm {
|
||||
|
||||
private static HashSet<uint> GetGamesToFarmSolo(ConcurrentDictionary<uint, float> gamesToFarm) {
|
||||
if (gamesToFarm == null) {
|
||||
Logging.LogNullError(nameof(gamesToFarm));
|
||||
return null;
|
||||
}
|
||||
|
||||
HashSet<uint> result = new HashSet<uint>();
|
||||
foreach (KeyValuePair<uint, float> keyValue in gamesToFarm) {
|
||||
if (keyValue.Value >= 2) {
|
||||
result.Add(keyValue.Key);
|
||||
}
|
||||
foreach (KeyValuePair<uint, float> keyValue in gamesToFarm.Where(keyValue => keyValue.Value >= 2)) {
|
||||
result.Add(keyValue.Key);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private static uint GetAnyGameToFarm(ConcurrentDictionary<uint, float> gamesToFarm) {
|
||||
if (gamesToFarm == null) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return gamesToFarm.Keys.FirstOrDefault();
|
||||
}
|
||||
|
||||
private async Task<bool> IsAnythingToFarm() {
|
||||
if (NowFarming) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (await Bot.ArchiWebHandler.ReconnectIfNeeded().ConfigureAwait(false)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Logging.LogGenericInfo("Checking badges...", Bot.BotName);
|
||||
|
||||
// Find the number of badge pages
|
||||
@@ -237,43 +218,45 @@ namespace ArchiSteamFarm {
|
||||
|
||||
byte maxPages = 1;
|
||||
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];
|
||||
if (!byte.TryParse(htmlNode.InnerText, out maxPages)) {
|
||||
maxPages = 1; // Should never happen
|
||||
string lastPage = htmlNode.InnerText;
|
||||
if (!string.IsNullOrEmpty(lastPage)) {
|
||||
if (!byte.TryParse(lastPage, out maxPages)) {
|
||||
maxPages = 1; // Should never happen
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GamesToFarm.Clear();
|
||||
|
||||
// Find APPIDs we need to farm
|
||||
CheckPage(htmlDocument);
|
||||
|
||||
if (maxPages <= 1) {
|
||||
return GamesToFarm.Count > 0;
|
||||
}
|
||||
|
||||
Logging.LogGenericInfo("Checking other pages...", Bot.BotName);
|
||||
|
||||
List<Task> tasks = new List<Task>(maxPages - 1);
|
||||
for (byte page = 1; page <= maxPages; page++) {
|
||||
if (page == 1) {
|
||||
CheckPage(htmlDocument); // Because we fetched page number 1 already
|
||||
} else {
|
||||
byte currentPage = page; // We need a copy of variable being passed when in for loops
|
||||
tasks.Add(CheckPage(currentPage));
|
||||
}
|
||||
for (byte page = 2; page <= maxPages; page++) {
|
||||
byte currentPage = page; // We need a copy of variable being passed when in for loops, as loop will proceed before task is launched
|
||||
tasks.Add(CheckPage(currentPage));
|
||||
}
|
||||
|
||||
await Task.WhenAll(tasks).ConfigureAwait(false);
|
||||
|
||||
if (GamesToFarm.Count == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
return GamesToFarm.Count > 0;
|
||||
}
|
||||
|
||||
private void CheckPage(HtmlDocument htmlDocument) {
|
||||
if (htmlDocument == null) {
|
||||
Logging.LogNullError(nameof(htmlDocument), Bot.BotName);
|
||||
return;
|
||||
}
|
||||
|
||||
HtmlNodeCollection htmlNodes = htmlDocument.DocumentNode.SelectNodes("//div[@class='badge_title_stats']");
|
||||
if (htmlNodes == null) {
|
||||
Logging.LogNullError(nameof(htmlNodes), Bot.BotName);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -285,13 +268,27 @@ namespace ArchiSteamFarm {
|
||||
|
||||
string steamLink = farmingNode.GetAttributeValue("href", null);
|
||||
if (string.IsNullOrEmpty(steamLink)) {
|
||||
Logging.LogNullError("steamLink", Bot.BotName);
|
||||
Logging.LogNullError(nameof(steamLink), Bot.BotName);
|
||||
continue;
|
||||
}
|
||||
|
||||
uint appID = (uint) Utilities.OnlyNumbers(steamLink);
|
||||
if (appID == 0) {
|
||||
Logging.LogNullError("appID", Bot.BotName);
|
||||
int index = steamLink.LastIndexOf('/');
|
||||
if (index < 0) {
|
||||
Logging.LogNullError(nameof(index), Bot.BotName);
|
||||
continue;
|
||||
}
|
||||
|
||||
index++;
|
||||
if (steamLink.Length <= index) {
|
||||
Logging.LogNullError(nameof(steamLink.Length), Bot.BotName);
|
||||
continue;
|
||||
}
|
||||
|
||||
steamLink = steamLink.Substring(index);
|
||||
|
||||
uint appID;
|
||||
if (!uint.TryParse(steamLink, out appID) || (appID == 0)) {
|
||||
Logging.LogNullError(nameof(appID), Bot.BotName);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -301,23 +298,24 @@ namespace ArchiSteamFarm {
|
||||
|
||||
HtmlNode timeNode = htmlNode.SelectSingleNode(".//div[@class='badge_title_stats_playtime']");
|
||||
if (timeNode == null) {
|
||||
Logging.LogNullError("timeNode", Bot.BotName);
|
||||
return;
|
||||
Logging.LogNullError(nameof(timeNode), Bot.BotName);
|
||||
continue;
|
||||
}
|
||||
|
||||
string hoursString = timeNode.InnerText;
|
||||
if (string.IsNullOrEmpty(hoursString)) {
|
||||
Logging.LogNullError("hoursString", Bot.BotName);
|
||||
return;
|
||||
Logging.LogNullError(nameof(hoursString), Bot.BotName);
|
||||
continue;
|
||||
}
|
||||
|
||||
hoursString = Regex.Match(hoursString, @"[0-9\.,]+").Value;
|
||||
float hours = 0;
|
||||
|
||||
float hours;
|
||||
if (string.IsNullOrEmpty(hoursString)) {
|
||||
hours = 0;
|
||||
} else {
|
||||
hours = float.Parse(hoursString, CultureInfo.InvariantCulture);
|
||||
Match match = Regex.Match(hoursString, @"[0-9\.,]+");
|
||||
if (match.Success) {
|
||||
if (!float.TryParse(match.Value, NumberStyles.Number, CultureInfo.InvariantCulture, out hours)) {
|
||||
Logging.LogNullError(nameof(hours), Bot.BotName);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
GamesToFarm[appID] = hours;
|
||||
@@ -326,6 +324,7 @@ namespace ArchiSteamFarm {
|
||||
|
||||
private async Task CheckPage(byte page) {
|
||||
if (page == 0) {
|
||||
Logging.LogNullError(nameof(page), Bot.BotName);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -347,6 +346,7 @@ namespace ArchiSteamFarm {
|
||||
|
||||
private async Task<bool?> ShouldFarm(uint appID) {
|
||||
if (appID == 0) {
|
||||
Logging.LogNullError(nameof(appID), Bot.BotName);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -356,65 +356,69 @@ namespace ArchiSteamFarm {
|
||||
}
|
||||
|
||||
HtmlNode htmlNode = htmlDocument.DocumentNode.SelectSingleNode("//span[@class='progress_info_bold']");
|
||||
if (htmlNode == null) {
|
||||
await Bot.ArchiWebHandler.ReconnectIfNeeded().ConfigureAwait(false);
|
||||
return null;
|
||||
if (htmlNode != null) {
|
||||
return !htmlNode.InnerText.Contains("No card drops");
|
||||
}
|
||||
|
||||
return !htmlNode.InnerText.Contains("No card drops");
|
||||
Logging.LogNullError(nameof(htmlNode), Bot.BotName);
|
||||
return null;
|
||||
}
|
||||
|
||||
private bool FarmMultiple(ConcurrentDictionary<uint, float> appIDs) {
|
||||
if (appIDs.Count == 0) {
|
||||
private bool FarmMultiple() {
|
||||
if (GamesToFarm.Count == 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
float maxHour = 0;
|
||||
foreach (float hour in appIDs.Values) {
|
||||
if (hour > maxHour) {
|
||||
maxHour = hour;
|
||||
foreach (KeyValuePair<uint, float> game in GamesToFarm) {
|
||||
CurrentGamesFarming.Add(game.Key);
|
||||
if (game.Value > maxHour) {
|
||||
maxHour = game.Value;
|
||||
}
|
||||
}
|
||||
|
||||
foreach (uint appID in appIDs.Keys) {
|
||||
CurrentGamesFarming.Add(appID);
|
||||
if (maxHour >= 2) {
|
||||
CurrentGamesFarming.ClearAndTrim();
|
||||
return true;
|
||||
}
|
||||
|
||||
Logging.LogGenericInfo("Now farming: " + string.Join(", ", appIDs.Keys), Bot.BotName);
|
||||
if (FarmHours(maxHour, appIDs.Keys)) {
|
||||
CurrentGamesFarming.Clear();
|
||||
CurrentGamesFarming.TrimExcess();
|
||||
return true;
|
||||
} else {
|
||||
CurrentGamesFarming.Clear();
|
||||
CurrentGamesFarming.TrimExcess();
|
||||
return false;
|
||||
}
|
||||
Logging.LogGenericInfo("Now farming: " + string.Join(", ", CurrentGamesFarming), Bot.BotName);
|
||||
|
||||
bool result = FarmHours(maxHour, CurrentGamesFarming);
|
||||
CurrentGamesFarming.ClearAndTrim();
|
||||
return result;
|
||||
}
|
||||
|
||||
private async Task<bool> FarmSolo(uint appID) {
|
||||
if (appID == 0) {
|
||||
Logging.LogNullError(nameof(appID), Bot.BotName);
|
||||
return true;
|
||||
}
|
||||
|
||||
CurrentGamesFarming.Add(appID);
|
||||
|
||||
Logging.LogGenericInfo("Now farming: " + appID, Bot.BotName);
|
||||
if (await Farm(appID).ConfigureAwait(false)) {
|
||||
CurrentGamesFarming.Clear();
|
||||
CurrentGamesFarming.TrimExcess();
|
||||
float ignored;
|
||||
GamesToFarm.TryRemove(appID, out ignored);
|
||||
return true;
|
||||
} else {
|
||||
CurrentGamesFarming.Clear();
|
||||
CurrentGamesFarming.TrimExcess();
|
||||
|
||||
bool result = await Farm(appID).ConfigureAwait(false);
|
||||
CurrentGamesFarming.ClearAndTrim();
|
||||
|
||||
if (!result) {
|
||||
return false;
|
||||
}
|
||||
|
||||
float hours;
|
||||
if (!GamesToFarm.TryRemove(appID, out hours)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
TimeSpan timeSpan = TimeSpan.FromHours(hours);
|
||||
Logging.LogGenericInfo("Done farming: " + appID + " after " + timeSpan.ToString(@"hh\:mm") + " hours of playtime!", Bot.BotName);
|
||||
return true;
|
||||
}
|
||||
|
||||
private async Task<bool> Farm(uint appID) {
|
||||
if (appID == 0) {
|
||||
Logging.LogNullError(nameof(appID), Bot.BotName);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -423,22 +427,27 @@ namespace ArchiSteamFarm {
|
||||
bool success = true;
|
||||
|
||||
bool? keepFarming = await ShouldFarm(appID).ConfigureAwait(false);
|
||||
for (ushort farmingTime = 0; farmingTime <= 60 * Program.GlobalConfig.MaxFarmingTime && keepFarming.GetValueOrDefault(true); farmingTime += Program.GlobalConfig.FarmingDelay) {
|
||||
if (FarmResetEvent.WaitOne(60 * 1000 * Program.GlobalConfig.FarmingDelay)) {
|
||||
for (ushort farmingTime = 0; (farmingTime <= 60 * Program.GlobalConfig.MaxFarmingTime) && keepFarming.GetValueOrDefault(true); farmingTime += Program.GlobalConfig.FarmingDelay) {
|
||||
if (FarmResetEvent.Wait(60 * 1000 * Program.GlobalConfig.FarmingDelay)) {
|
||||
success = false;
|
||||
break;
|
||||
}
|
||||
|
||||
// Don't forget to update our GamesToFarm hours
|
||||
float timePlayed = Program.GlobalConfig.FarmingDelay / 60.0F;
|
||||
GamesToFarm[appID] += timePlayed;
|
||||
|
||||
keepFarming = await ShouldFarm(appID).ConfigureAwait(false);
|
||||
Logging.LogGenericInfo("Still farming: " + appID, Bot.BotName);
|
||||
}
|
||||
|
||||
Bot.ResetGamesPlayed();
|
||||
Logging.LogGenericInfo("Stopped farming: " + appID, Bot.BotName);
|
||||
return success;
|
||||
}
|
||||
|
||||
private bool FarmHours(float maxHour, ICollection<uint> appIDs) {
|
||||
if (maxHour < 0 || appIDs == null || appIDs.Count == 0) {
|
||||
private bool FarmHours(float maxHour, ConcurrentHashSet<uint> appIDs) {
|
||||
if ((maxHour < 0) || (appIDs == null) || (appIDs.Count == 0)) {
|
||||
Logging.LogNullError(nameof(maxHour) + " || " + nameof(appIDs) + " || " + nameof(appIDs.Count), Bot.BotName);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -450,26 +459,21 @@ namespace ArchiSteamFarm {
|
||||
|
||||
bool success = true;
|
||||
while (maxHour < 2) {
|
||||
Logging.LogGenericInfo("Still farming: " + string.Join(", ", appIDs), Bot.BotName);
|
||||
if (FarmResetEvent.WaitOne(60 * 1000 * Program.GlobalConfig.FarmingDelay)) {
|
||||
if (FarmResetEvent.Wait(60 * 1000 * Program.GlobalConfig.FarmingDelay)) {
|
||||
success = false;
|
||||
break;
|
||||
}
|
||||
|
||||
// Don't forget to update our GamesToFarm hours
|
||||
float timePlayed = Program.GlobalConfig.FarmingDelay / 60.0F;
|
||||
foreach (KeyValuePair<uint, float> gameToFarm in GamesToFarm) {
|
||||
if (!appIDs.Contains(gameToFarm.Key)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
GamesToFarm[gameToFarm.Key] = gameToFarm.Value + timePlayed;
|
||||
foreach (uint appID in appIDs) {
|
||||
GamesToFarm[appID] += timePlayed;
|
||||
}
|
||||
|
||||
maxHour += timePlayed;
|
||||
Logging.LogGenericInfo("Still farming: " + string.Join(", ", appIDs), Bot.BotName);
|
||||
}
|
||||
|
||||
Bot.ResetGamesPlayed();
|
||||
Logging.LogGenericInfo("Stopped farming: " + string.Join(", ", appIDs), Bot.BotName);
|
||||
return success;
|
||||
}
|
||||
|
||||
@@ -22,45 +22,37 @@
|
||||
|
||||
*/
|
||||
|
||||
using SteamKit2;
|
||||
using SteamKit2.Internal;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
|
||||
namespace ArchiSteamFarm {
|
||||
internal sealed class CMsgClientClanInviteAction : ISteamSerializableMessage {
|
||||
internal ulong GroupID { get; set; } = 0;
|
||||
internal bool AcceptInvite { get; set; } = true;
|
||||
internal sealed class ConcurrentEnumerator<T> : IEnumerator<T> {
|
||||
public T Current => Enumerator.Current;
|
||||
|
||||
EMsg ISteamSerializableMessage.GetEMsg() {
|
||||
return EMsg.ClientAcknowledgeClanInvite;
|
||||
object IEnumerator.Current => Current;
|
||||
|
||||
private readonly IEnumerator<T> Enumerator;
|
||||
private readonly ReaderWriterLockSlim Lock;
|
||||
|
||||
internal ConcurrentEnumerator(ICollection<T> collection, ReaderWriterLockSlim @lock) {
|
||||
if ((collection == null) || (@lock == null)) {
|
||||
throw new ArgumentNullException(nameof(collection) + " || " + nameof(@lock));
|
||||
}
|
||||
|
||||
@lock.EnterReadLock();
|
||||
|
||||
Lock = @lock;
|
||||
Enumerator = collection.GetEnumerator();
|
||||
}
|
||||
|
||||
void ISteamSerializable.Serialize(Stream stream) {
|
||||
if (stream == null) {
|
||||
return;
|
||||
}
|
||||
public bool MoveNext() => Enumerator.MoveNext();
|
||||
public void Reset() => Enumerator.Reset();
|
||||
|
||||
try {
|
||||
BinaryWriter binaryWriter = new BinaryWriter(stream);
|
||||
binaryWriter.Write(GroupID);
|
||||
binaryWriter.Write(AcceptInvite);
|
||||
} catch (Exception e) {
|
||||
Logging.LogGenericException(e);
|
||||
}
|
||||
}
|
||||
|
||||
void ISteamSerializable.Deserialize(Stream stream) {
|
||||
if (stream == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
BinaryReader binaryReader = new BinaryReader(stream);
|
||||
GroupID = binaryReader.ReadUInt64();
|
||||
AcceptInvite = binaryReader.ReadBoolean();
|
||||
} catch (Exception e) {
|
||||
Logging.LogGenericException(e);
|
||||
public void Dispose() {
|
||||
if (Lock != null) {
|
||||
Lock.ExitReadLock();
|
||||
}
|
||||
}
|
||||
}
|
||||
123
ArchiSteamFarm/ConcurrentHashSet.cs
Normal file
123
ArchiSteamFarm/ConcurrentHashSet.cs
Normal file
@@ -0,0 +1,123 @@
|
||||
/*
|
||||
_ _ _ ____ _ _____
|
||||
/ \ _ __ ___ | |__ (_)/ ___| | |_ ___ __ _ _ __ ___ | ___|__ _ _ __ _ __ ___
|
||||
/ _ \ | '__|/ __|| '_ \ | |\___ \ | __|/ _ \ / _` || '_ ` _ \ | |_ / _` || '__|| '_ ` _ \
|
||||
/ ___ \ | | | (__ | | | || | ___) || |_| __/| (_| || | | | | || _|| (_| || | | | | | | |
|
||||
/_/ \_\|_| \___||_| |_||_||____/ \__|\___| \__,_||_| |_| |_||_| \__,_||_| |_| |_| |_|
|
||||
|
||||
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.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Threading;
|
||||
|
||||
namespace ArchiSteamFarm {
|
||||
internal sealed class ConcurrentHashSet<T> : ICollection<T>, IDisposable {
|
||||
private readonly HashSet<T> HashSet = new HashSet<T>();
|
||||
private readonly ReaderWriterLockSlim Lock = new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion);
|
||||
|
||||
public bool IsReadOnly => false;
|
||||
public IEnumerator<T> GetEnumerator() => new ConcurrentEnumerator<T>(HashSet, Lock);
|
||||
|
||||
public int Count {
|
||||
get {
|
||||
Lock.EnterReadLock();
|
||||
|
||||
try {
|
||||
return HashSet.Count;
|
||||
} finally {
|
||||
Lock.ExitReadLock();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[SuppressMessage("ReSharper", "UnusedMethodReturnValue.Global")]
|
||||
public bool Add(T item) {
|
||||
Lock.EnterWriteLock();
|
||||
|
||||
try {
|
||||
return HashSet.Add(item);
|
||||
} finally {
|
||||
Lock.ExitWriteLock();
|
||||
}
|
||||
}
|
||||
|
||||
public void Clear() {
|
||||
Lock.EnterWriteLock();
|
||||
|
||||
try {
|
||||
HashSet.Clear();
|
||||
} finally {
|
||||
Lock.ExitWriteLock();
|
||||
}
|
||||
}
|
||||
|
||||
public void ClearAndTrim() {
|
||||
Lock.EnterWriteLock();
|
||||
|
||||
try {
|
||||
HashSet.Clear();
|
||||
HashSet.TrimExcess();
|
||||
} finally {
|
||||
Lock.ExitWriteLock();
|
||||
}
|
||||
}
|
||||
|
||||
public bool Contains(T item) {
|
||||
Lock.EnterReadLock();
|
||||
|
||||
try {
|
||||
return HashSet.Contains(item);
|
||||
} finally {
|
||||
Lock.ExitReadLock();
|
||||
}
|
||||
}
|
||||
|
||||
public bool Remove(T item) {
|
||||
Lock.EnterWriteLock();
|
||||
|
||||
try {
|
||||
return HashSet.Remove(item);
|
||||
} finally {
|
||||
Lock.ExitWriteLock();
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose() {
|
||||
if (Lock != null) {
|
||||
Lock.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
public void CopyTo(T[] array, int arrayIndex) {
|
||||
Lock.EnterReadLock();
|
||||
|
||||
try {
|
||||
HashSet.CopyTo(array, arrayIndex);
|
||||
} finally {
|
||||
Lock.ExitReadLock();
|
||||
}
|
||||
}
|
||||
|
||||
void ICollection<T>.Add(T item) => Add(item);
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
|
||||
}
|
||||
}
|
||||
@@ -24,26 +24,27 @@
|
||||
|
||||
using SteamKit2;
|
||||
using System;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.IO;
|
||||
|
||||
namespace ArchiSteamFarm {
|
||||
internal static class Debugging {
|
||||
#if DEBUG
|
||||
[SuppressMessage("ReSharper", "ConvertToConstant.Global")]
|
||||
internal static readonly bool IsDebugBuild = true;
|
||||
#else
|
||||
[SuppressMessage("ReSharper", "ConvertToConstant.Global")]
|
||||
internal static readonly bool IsDebugBuild = false;
|
||||
#endif
|
||||
|
||||
internal static bool IsReleaseBuild => !IsDebugBuild;
|
||||
|
||||
internal static bool NetHookAlreadyInitialized { get; set; } = false;
|
||||
internal static bool NetHookAlreadyInitialized { get; set; }
|
||||
|
||||
internal sealed class DebugListener : IDebugListener {
|
||||
private readonly string FilePath;
|
||||
|
||||
internal DebugListener(string filePath) {
|
||||
if (string.IsNullOrEmpty(filePath)) {
|
||||
return;
|
||||
throw new ArgumentNullException(nameof(filePath));
|
||||
}
|
||||
|
||||
FilePath = filePath;
|
||||
|
||||
@@ -25,46 +25,59 @@
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.IO;
|
||||
using System.Net.Sockets;
|
||||
|
||||
namespace ArchiSteamFarm {
|
||||
[SuppressMessage("ReSharper", "ClassCannotBeInstantiated"), SuppressMessage("ReSharper", "ClassNeverInstantiated.Global")]
|
||||
internal sealed class GlobalConfig {
|
||||
[SuppressMessage("ReSharper", "UnusedMember.Global")]
|
||||
internal enum EUpdateChannel : byte {
|
||||
Unknown,
|
||||
Stable,
|
||||
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
|
||||
internal static readonly HashSet<uint> GlobalBlacklist = new HashSet<uint> { 267420, 303700, 335590, 368020, 425280 };
|
||||
|
||||
[JsonProperty(Required = Required.DisallowNull)]
|
||||
internal bool Debug { get; private set; } = false;
|
||||
|
||||
[JsonProperty(Required = Required.DisallowNull)]
|
||||
internal bool Headless { get; private set; } = false;
|
||||
|
||||
[JsonProperty(Required = Required.DisallowNull)]
|
||||
internal bool AutoUpdates { get; private set; } = true;
|
||||
|
||||
[JsonProperty(Required = Required.DisallowNull)]
|
||||
internal bool AutoRestart { get; private set; } = true;
|
||||
|
||||
[JsonProperty(Required = Required.DisallowNull)]
|
||||
internal EUpdateChannel UpdateChannel { get; private set; } = EUpdateChannel.Stable;
|
||||
|
||||
[JsonProperty(Required = Required.DisallowNull)]
|
||||
internal ProtocolType SteamProtocol { get; private set; } = ProtocolType.Tcp;
|
||||
internal ProtocolType SteamProtocol { get; private set; } = DefaultSteamProtocol;
|
||||
|
||||
[JsonProperty(Required = Required.DisallowNull)]
|
||||
internal ulong SteamOwnerID { get; private set; } = 0;
|
||||
|
||||
[JsonProperty(Required = Required.DisallowNull)]
|
||||
internal byte MaxFarmingTime { get; private set; } = 10;
|
||||
internal byte MaxFarmingTime { get; private set; } = DefaultMaxFarmingTime;
|
||||
|
||||
[JsonProperty(Required = Required.DisallowNull)]
|
||||
internal byte IdleFarmingPeriod { get; private set; } = 3;
|
||||
|
||||
[JsonProperty(Required = Required.DisallowNull)]
|
||||
internal byte FarmingDelay { get; private set; } = 5;
|
||||
|
||||
[JsonProperty(Required = Required.DisallowNull)]
|
||||
internal byte AccountPlayingDelay { get; private set; } = 5;
|
||||
internal byte FarmingDelay { get; private set; } = DefaultFarmingDelay;
|
||||
|
||||
[JsonProperty(Required = Required.DisallowNull)]
|
||||
internal byte LoginLimiterDelay { get; private set; } = 7;
|
||||
@@ -76,13 +89,13 @@ namespace ArchiSteamFarm {
|
||||
internal bool ForceHttp { get; private set; } = false;
|
||||
|
||||
[JsonProperty(Required = Required.DisallowNull)]
|
||||
internal byte HttpTimeout { get; private set; } = 60;
|
||||
internal byte HttpTimeout { get; private set; } = DefaultHttpTimeout;
|
||||
|
||||
[JsonProperty]
|
||||
internal string WCFHostname { get; set; } = "localhost";
|
||||
|
||||
[JsonProperty(Required = Required.DisallowNull)]
|
||||
internal string WCFHostname { get; private set; } = "localhost";
|
||||
|
||||
[JsonProperty(Required = Required.DisallowNull)]
|
||||
internal ushort WCFPort { get; private set; } = 1242;
|
||||
internal ushort WCFPort { get; private set; } = DefaultWCFPort;
|
||||
|
||||
[JsonProperty(Required = Required.DisallowNull)]
|
||||
internal bool LogToFile { get; private set; } = true;
|
||||
@@ -97,13 +110,18 @@ namespace ArchiSteamFarm {
|
||||
[JsonProperty(Required = Required.DisallowNull)]
|
||||
internal HashSet<uint> Blacklist { get; private set; } = new HashSet<uint>(GlobalBlacklist);
|
||||
|
||||
internal static GlobalConfig Load() {
|
||||
string filePath = Path.Combine(Program.ConfigDirectory, Program.GlobalConfigFile);
|
||||
internal static GlobalConfig Load(string filePath) {
|
||||
if (string.IsNullOrEmpty(filePath)) {
|
||||
Logging.LogNullError(nameof(filePath));
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!File.Exists(filePath)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
GlobalConfig globalConfig;
|
||||
|
||||
try {
|
||||
globalConfig = JsonConvert.DeserializeObject<GlobalConfig>(File.ReadAllText(filePath));
|
||||
} catch (Exception e) {
|
||||
@@ -111,18 +129,47 @@ namespace ArchiSteamFarm {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (globalConfig == null) {
|
||||
Logging.LogNullError(nameof(globalConfig));
|
||||
return null;
|
||||
}
|
||||
|
||||
// SK2 supports only TCP and UDP steam protocols
|
||||
// Make sure that user can't screw this up
|
||||
// Ensure that user can't screw this up
|
||||
switch (globalConfig.SteamProtocol) {
|
||||
case ProtocolType.Tcp:
|
||||
case ProtocolType.Udp:
|
||||
break;
|
||||
default:
|
||||
Logging.LogGenericWarning("Configured SteamProtocol is invalid: " + globalConfig.SteamProtocol + ", default TCP protocol will be used instead");
|
||||
globalConfig.SteamProtocol = ProtocolType.Tcp;
|
||||
Logging.LogGenericWarning("Configured SteamProtocol is invalid: " + globalConfig.SteamProtocol + ". Value of " + DefaultSteamProtocol + " will be used instead");
|
||||
globalConfig.SteamProtocol = DefaultSteamProtocol;
|
||||
break;
|
||||
}
|
||||
|
||||
// User might not know what he's doing
|
||||
// Ensure that he can't screw core ASF variables
|
||||
if (globalConfig.MaxFarmingTime == 0) {
|
||||
Logging.LogGenericWarning("Configured MaxFarmingTime is invalid: " + globalConfig.MaxFarmingTime + ". Value of " + DefaultMaxFarmingTime + " will be used instead");
|
||||
globalConfig.MaxFarmingTime = DefaultMaxFarmingTime;
|
||||
}
|
||||
|
||||
if (globalConfig.FarmingDelay == 0) {
|
||||
Logging.LogGenericWarning("Configured FarmingDelay is invalid: " + globalConfig.FarmingDelay + ". Value of " + DefaultFarmingDelay + " will be used instead");
|
||||
globalConfig.FarmingDelay = DefaultFarmingDelay;
|
||||
}
|
||||
|
||||
if (globalConfig.HttpTimeout == 0) {
|
||||
Logging.LogGenericWarning("Configured HttpTimeout is invalid: " + globalConfig.HttpTimeout + ". Value of " + DefaultHttpTimeout + " will be used instead");
|
||||
globalConfig.HttpTimeout = DefaultHttpTimeout;
|
||||
}
|
||||
|
||||
if (globalConfig.WCFPort != 0) {
|
||||
return globalConfig;
|
||||
}
|
||||
|
||||
Logging.LogGenericWarning("Configured WCFPort is invalid: " + globalConfig.WCFPort + ". Value of " + DefaultWCFPort + " will be used instead");
|
||||
globalConfig.WCFPort = DefaultWCFPort;
|
||||
|
||||
return globalConfig;
|
||||
}
|
||||
|
||||
|
||||
@@ -24,12 +24,11 @@
|
||||
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.IO;
|
||||
|
||||
namespace ArchiSteamFarm {
|
||||
internal sealed class GlobalDatabase {
|
||||
private static readonly string FilePath = Path.Combine(Program.ConfigDirectory, Program.GlobalDatabaseFile);
|
||||
|
||||
internal uint CellID {
|
||||
get {
|
||||
return _CellID;
|
||||
@@ -45,25 +44,50 @@ namespace ArchiSteamFarm {
|
||||
}
|
||||
|
||||
[JsonProperty(Required = Required.DisallowNull)]
|
||||
private uint _CellID = 0;
|
||||
private uint _CellID;
|
||||
|
||||
internal static GlobalDatabase Load() {
|
||||
if (!File.Exists(FilePath)) {
|
||||
return new GlobalDatabase();
|
||||
private string FilePath;
|
||||
|
||||
internal static GlobalDatabase Load(string filePath) {
|
||||
if (string.IsNullOrEmpty(filePath)) {
|
||||
Logging.LogNullError(nameof(filePath));
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!File.Exists(filePath)) {
|
||||
return new GlobalDatabase(filePath);
|
||||
}
|
||||
|
||||
GlobalDatabase globalDatabase;
|
||||
|
||||
try {
|
||||
globalDatabase = JsonConvert.DeserializeObject<GlobalDatabase>(File.ReadAllText(FilePath));
|
||||
globalDatabase = JsonConvert.DeserializeObject<GlobalDatabase>(File.ReadAllText(filePath));
|
||||
} catch (Exception e) {
|
||||
Logging.LogGenericException(e);
|
||||
return null;
|
||||
}
|
||||
|
||||
if (globalDatabase == null) {
|
||||
Logging.LogNullError(nameof(globalDatabase));
|
||||
return null;
|
||||
}
|
||||
|
||||
globalDatabase.FilePath = filePath;
|
||||
return globalDatabase;
|
||||
}
|
||||
|
||||
// This constructor is used when creating new database
|
||||
private GlobalDatabase(string filePath) {
|
||||
if (string.IsNullOrEmpty(filePath)) {
|
||||
throw new ArgumentNullException(nameof(filePath));
|
||||
}
|
||||
|
||||
FilePath = filePath;
|
||||
Save();
|
||||
}
|
||||
|
||||
// This constructor is used only by deserializer
|
||||
[SuppressMessage("ReSharper", "UnusedMember.Local")]
|
||||
private GlobalDatabase() { }
|
||||
|
||||
private void Save() {
|
||||
|
||||
@@ -22,20 +22,22 @@
|
||||
|
||||
*/
|
||||
|
||||
using Newtonsoft.Json;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace ArchiSteamFarm {
|
||||
namespace ArchiSteamFarm.JSON {
|
||||
internal static class GitHub {
|
||||
internal sealed class Asset {
|
||||
[JsonProperty(PropertyName = "name", Required = Required.Always)]
|
||||
internal string Name { get; private set; }
|
||||
|
||||
[JsonProperty(PropertyName = "browser_download_url", Required = Required.Always)]
|
||||
internal string DownloadURL { get; private set; }
|
||||
}
|
||||
|
||||
[SuppressMessage("ReSharper", "ClassNeverInstantiated.Global"), SuppressMessage("ReSharper", "UnusedAutoPropertyAccessor.Local")]
|
||||
internal sealed class ReleaseResponse {
|
||||
internal sealed class Asset {
|
||||
[JsonProperty(PropertyName = "name", Required = Required.Always)]
|
||||
internal string Name { get; private set; }
|
||||
|
||||
[JsonProperty(PropertyName = "browser_download_url", Required = Required.Always)]
|
||||
internal string DownloadURL { get; private set; }
|
||||
}
|
||||
|
||||
[JsonProperty(PropertyName = "tag_name", Required = Required.Always)]
|
||||
internal string Tag { get; private set; }
|
||||
|
||||
|
||||
@@ -22,46 +22,176 @@
|
||||
|
||||
*/
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Linq;
|
||||
using Newtonsoft.Json;
|
||||
using SteamKit2;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace ArchiSteamFarm {
|
||||
namespace ArchiSteamFarm.JSON {
|
||||
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; }
|
||||
internal sealed class Item { // REF: https://developer.valvesoftware.com/wiki/Steam_Web_API/IEconService#CEcon_Asset
|
||||
internal const ushort SteamAppID = 753;
|
||||
internal const byte SteamContextID = 6;
|
||||
|
||||
[JsonProperty(Required = Required.DisallowNull)]
|
||||
internal string contextid { get; set; }
|
||||
internal enum EType : byte {
|
||||
Unknown,
|
||||
|
||||
[JsonProperty(Required = Required.DisallowNull)]
|
||||
internal string assetid { get; set; }
|
||||
BoosterPack,
|
||||
Coupon,
|
||||
Gift,
|
||||
SteamGems,
|
||||
|
||||
[JsonProperty(Required = Required.DisallowNull)]
|
||||
internal string id {
|
||||
get { return assetid; }
|
||||
set { assetid = value; }
|
||||
Emoticon,
|
||||
FoilTradingCard,
|
||||
ProfileBackground,
|
||||
TradingCard
|
||||
}
|
||||
|
||||
[JsonProperty(Required = Required.AllowNull)]
|
||||
internal string classid { get; set; }
|
||||
internal uint AppID { get; set; }
|
||||
|
||||
[JsonProperty(Required = Required.AllowNull)]
|
||||
internal string instanceid { get; set; }
|
||||
[JsonProperty(PropertyName = "appid", Required = Required.DisallowNull), SuppressMessage("ReSharper", "UnusedMember.Local")]
|
||||
private string AppIDString {
|
||||
get {
|
||||
return AppID.ToString();
|
||||
}
|
||||
|
||||
[JsonProperty(Required = Required.Always)]
|
||||
internal string amount { get; set; }
|
||||
set {
|
||||
if (string.IsNullOrEmpty(value)) {
|
||||
return;
|
||||
}
|
||||
|
||||
uint result;
|
||||
if (!uint.TryParse(value, out result)) {
|
||||
return;
|
||||
}
|
||||
|
||||
AppID = result;
|
||||
}
|
||||
}
|
||||
|
||||
internal ulong ContextID { get; set; }
|
||||
|
||||
[JsonProperty(PropertyName = "contextid", Required = Required.DisallowNull), SuppressMessage("ReSharper", "UnusedMember.Local")]
|
||||
private string ContextIDString {
|
||||
get {
|
||||
return ContextID.ToString();
|
||||
}
|
||||
|
||||
set {
|
||||
if (string.IsNullOrEmpty(value)) {
|
||||
return;
|
||||
}
|
||||
|
||||
ulong result;
|
||||
if (!ulong.TryParse(value, out result)) {
|
||||
return;
|
||||
}
|
||||
|
||||
ContextID = result;
|
||||
}
|
||||
}
|
||||
|
||||
internal ulong AssetID { get; set; }
|
||||
|
||||
[JsonProperty(PropertyName = "assetid", Required = Required.DisallowNull)]
|
||||
private string AssetIDString {
|
||||
get {
|
||||
return AssetID.ToString();
|
||||
}
|
||||
|
||||
set {
|
||||
if (string.IsNullOrEmpty(value)) {
|
||||
return;
|
||||
}
|
||||
|
||||
ulong result;
|
||||
if (!ulong.TryParse(value, out result)) {
|
||||
return;
|
||||
}
|
||||
|
||||
AssetID = result;
|
||||
}
|
||||
}
|
||||
|
||||
[JsonProperty(PropertyName = "id", Required = Required.DisallowNull), SuppressMessage("ReSharper", "UnusedMember.Local")]
|
||||
private string ID {
|
||||
get { return AssetIDString; }
|
||||
set { AssetIDString = value; }
|
||||
}
|
||||
|
||||
internal ulong ClassID { get; set; }
|
||||
|
||||
[JsonProperty(PropertyName = "classid", Required = Required.DisallowNull), SuppressMessage("ReSharper", "UnusedMember.Local")]
|
||||
private string ClassIDString {
|
||||
get {
|
||||
return ClassID.ToString();
|
||||
}
|
||||
|
||||
set {
|
||||
if (string.IsNullOrEmpty(value)) {
|
||||
return;
|
||||
}
|
||||
|
||||
ulong result;
|
||||
if (!ulong.TryParse(value, out result)) {
|
||||
return;
|
||||
}
|
||||
|
||||
ClassID = result;
|
||||
}
|
||||
}
|
||||
|
||||
internal ulong InstanceID { get; set; }
|
||||
|
||||
[JsonProperty(PropertyName = "instanceid", Required = Required.DisallowNull), SuppressMessage("ReSharper", "UnusedMember.Local")]
|
||||
private string InstanceIDString {
|
||||
get {
|
||||
return InstanceID.ToString();
|
||||
}
|
||||
|
||||
set {
|
||||
if (string.IsNullOrEmpty(value)) {
|
||||
return;
|
||||
}
|
||||
|
||||
ulong result;
|
||||
if (!ulong.TryParse(value, out result)) {
|
||||
return;
|
||||
}
|
||||
|
||||
InstanceID = result;
|
||||
}
|
||||
}
|
||||
|
||||
internal uint Amount { get; set; }
|
||||
|
||||
[JsonProperty(PropertyName = "amount", Required = Required.Always), SuppressMessage("ReSharper", "UnusedMember.Local")]
|
||||
private string AmountString {
|
||||
get {
|
||||
return Amount.ToString();
|
||||
}
|
||||
|
||||
set {
|
||||
if (string.IsNullOrEmpty(value)) {
|
||||
return;
|
||||
}
|
||||
|
||||
uint result;
|
||||
if (!uint.TryParse(value, out result)) {
|
||||
return;
|
||||
}
|
||||
|
||||
Amount = result;
|
||||
}
|
||||
}
|
||||
|
||||
internal uint RealAppID { get; set; }
|
||||
internal EType Type { 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 sealed class TradeOffer { // REF: https://developer.valvesoftware.com/wiki/Steam_Web_API/IEconService#CEcon_TradeOffer
|
||||
[SuppressMessage("ReSharper", "UnusedMember.Global")]
|
||||
internal enum ETradeOfferState : byte {
|
||||
Unknown,
|
||||
Invalid,
|
||||
@@ -77,46 +207,119 @@ namespace ArchiSteamFarm {
|
||||
OnHold
|
||||
}
|
||||
|
||||
[JsonProperty(Required = Required.Always)]
|
||||
internal string tradeofferid { get; set; }
|
||||
internal ulong 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 {
|
||||
[JsonProperty(PropertyName = "tradeofferid", Required = Required.Always), SuppressMessage("ReSharper", "UnusedMember.Local")]
|
||||
private string TradeOfferIDString {
|
||||
get {
|
||||
if (_OtherSteamID64 == 0 && accountid_other != 0) {
|
||||
_OtherSteamID64 = new SteamID(accountid_other, EUniverse.Public, EAccountType.Individual).ConvertToUInt64();
|
||||
return TradeOfferID.ToString();
|
||||
}
|
||||
|
||||
set {
|
||||
if (string.IsNullOrEmpty(value)) {
|
||||
return;
|
||||
}
|
||||
|
||||
return _OtherSteamID64;
|
||||
ulong result;
|
||||
if (!ulong.TryParse(value, out result)) {
|
||||
return;
|
||||
}
|
||||
|
||||
TradeOfferID = result;
|
||||
}
|
||||
}
|
||||
|
||||
[JsonProperty(PropertyName = "accountid_other", Required = Required.Always)]
|
||||
internal uint OtherSteamID3 { private get; set; }
|
||||
|
||||
[JsonProperty(PropertyName = "trade_offer_state", Required = Required.Always)]
|
||||
internal ETradeOfferState State { get; set; }
|
||||
|
||||
[JsonProperty(PropertyName = "items_to_give", Required = Required.Always)]
|
||||
internal HashSet<Item> ItemsToGive { get; } = new HashSet<Item>();
|
||||
|
||||
[JsonProperty(PropertyName = "items_to_receive", Required = Required.Always)]
|
||||
internal HashSet<Item> ItemsToReceive { get; } = new HashSet<Item>();
|
||||
|
||||
// Extra
|
||||
internal ulong OtherSteamID64 => OtherSteamID3 == 0 ? 0 : new SteamID(OtherSteamID3, EUniverse.Public, EAccountType.Individual);
|
||||
|
||||
internal bool IsSteamCardsOnlyTradeForUs() => ItemsToGive.All(item => (item.AppID == Item.SteamAppID) && (item.ContextID == Item.SteamContextID) && ((item.Type == Item.EType.FoilTradingCard) || (item.Type == Item.EType.TradingCard)));
|
||||
|
||||
internal bool IsPotentiallyDupesTradeForUs() {
|
||||
Dictionary<uint, Dictionary<Item.EType, uint>> itemsToGivePerGame = new Dictionary<uint, Dictionary<Item.EType, uint>>();
|
||||
foreach (Item item in ItemsToGive) {
|
||||
Dictionary<Item.EType, uint> itemsPerType;
|
||||
if (!itemsToGivePerGame.TryGetValue(item.RealAppID, out itemsPerType)) {
|
||||
itemsPerType = new Dictionary<Item.EType, uint> { [item.Type] = item.Amount };
|
||||
itemsToGivePerGame[item.RealAppID] = itemsPerType;
|
||||
} else {
|
||||
uint amount;
|
||||
if (itemsPerType.TryGetValue(item.Type, out amount)) {
|
||||
itemsPerType[item.Type] = amount + item.Amount;
|
||||
} else {
|
||||
itemsPerType[item.Type] = item.Amount;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Dictionary<uint, Dictionary<Item.EType, uint>> itemsToReceivePerGame = new Dictionary<uint, Dictionary<Item.EType, uint>>();
|
||||
foreach (Item item in ItemsToReceive) {
|
||||
Dictionary<Item.EType, uint> itemsPerType;
|
||||
if (!itemsToReceivePerGame.TryGetValue(item.RealAppID, out itemsPerType)) {
|
||||
itemsPerType = new Dictionary<Item.EType, uint> { [item.Type] = item.Amount };
|
||||
itemsToReceivePerGame[item.RealAppID] = itemsPerType;
|
||||
} else {
|
||||
uint amount;
|
||||
if (itemsPerType.TryGetValue(item.Type, out amount)) {
|
||||
itemsPerType[item.Type] = amount + item.Amount;
|
||||
} else {
|
||||
itemsPerType[item.Type] = item.Amount;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure that amount of items to give is at least amount of items to receive (per game and per type)
|
||||
foreach (KeyValuePair<uint, Dictionary<Item.EType, uint>> itemsPerGame in itemsToGivePerGame) {
|
||||
Dictionary<Item.EType, uint> otherItemsPerType;
|
||||
if (!itemsToReceivePerGame.TryGetValue(itemsPerGame.Key, out otherItemsPerType)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
foreach (KeyValuePair<Item.EType, uint> itemsPerType in itemsPerGame.Value) {
|
||||
uint otherAmount;
|
||||
if (!otherItemsPerType.TryGetValue(itemsPerType.Key, out otherAmount)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (itemsPerType.Value > otherAmount) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
[SuppressMessage("ReSharper", "UnusedMember.Global")]
|
||||
internal sealed class TradeOfferRequest {
|
||||
[JsonProperty(Required = Required.Always)]
|
||||
internal bool newversion { get; } = true;
|
||||
internal sealed class ItemList {
|
||||
[JsonProperty(PropertyName = "assets", Required = Required.Always)]
|
||||
internal HashSet<Item> Assets { get; } = new HashSet<Item>();
|
||||
}
|
||||
|
||||
[JsonProperty(Required = Required.Always)]
|
||||
internal int version { get; } = 2;
|
||||
[JsonProperty(PropertyName = "newversion", Required = Required.Always)]
|
||||
internal bool NewVersion { get; } = true;
|
||||
|
||||
[JsonProperty(Required = Required.Always)]
|
||||
internal Steam.ItemList me { get; } = new Steam.ItemList();
|
||||
[JsonProperty(PropertyName = "version", Required = Required.Always)]
|
||||
internal byte Version { get; } = 2;
|
||||
|
||||
[JsonProperty(Required = Required.Always)]
|
||||
internal Steam.ItemList them { get; } = new Steam.ItemList();
|
||||
[JsonProperty(PropertyName = "me", Required = Required.Always)]
|
||||
internal ItemList ItemsToGive { get; } = new ItemList();
|
||||
|
||||
[JsonProperty(PropertyName = "them", Required = Required.Always)]
|
||||
internal ItemList ItemsToReceive { get; } = new ItemList();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.IO;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
@@ -31,78 +32,101 @@ namespace ArchiSteamFarm {
|
||||
internal static class Logging {
|
||||
private static readonly object FileLock = new object();
|
||||
|
||||
private static bool LogToFile = false;
|
||||
private static bool LogToFile;
|
||||
|
||||
internal static void Init() {
|
||||
LogToFile = Program.GlobalConfig.LogToFile;
|
||||
|
||||
if (LogToFile) {
|
||||
lock (FileLock) {
|
||||
try {
|
||||
File.Delete(Program.LogFile);
|
||||
} catch (Exception e) {
|
||||
LogGenericException(e);
|
||||
}
|
||||
if (!LogToFile) {
|
||||
return;
|
||||
}
|
||||
|
||||
lock (FileLock) {
|
||||
if (!LogToFile) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
File.Delete(Program.LogFile);
|
||||
} catch (Exception e) {
|
||||
LogToFile = false;
|
||||
LogGenericException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal static void LogGenericWTF(string message, string botName = "Main", [CallerMemberName] string previousMethodName = "") {
|
||||
internal static void LogGenericWTF(string message, string botName = "Main", [CallerMemberName] string previousMethodName = null) {
|
||||
if (string.IsNullOrEmpty(message)) {
|
||||
LogNullError(nameof(message), botName);
|
||||
return;
|
||||
}
|
||||
|
||||
Log("[!!] WTF: " + previousMethodName + "() <" + botName + "> " + message + ", WTF?");
|
||||
}
|
||||
|
||||
internal static void LogGenericError(string message, string botName = "Main", [CallerMemberName] string previousMethodName = "") {
|
||||
internal static void LogGenericError(string message, string botName = "Main", [CallerMemberName] string previousMethodName = null) {
|
||||
if (string.IsNullOrEmpty(message)) {
|
||||
LogNullError(nameof(message), botName);
|
||||
return;
|
||||
}
|
||||
|
||||
Log("[!!] ERROR: " + previousMethodName + "() <" + botName + "> " + message);
|
||||
}
|
||||
|
||||
internal static void LogGenericException(Exception exception, string botName = "Main", [CallerMemberName] string previousMethodName = "") {
|
||||
if (exception == null) {
|
||||
return;
|
||||
}
|
||||
internal static void LogGenericException(Exception exception, string botName = "Main", [CallerMemberName] string previousMethodName = null) {
|
||||
while (true) {
|
||||
if (exception == null) {
|
||||
LogNullError(nameof(exception), botName);
|
||||
return;
|
||||
}
|
||||
|
||||
Log("[!] EXCEPTION: " + previousMethodName + "() <" + botName + "> " + exception.Message);
|
||||
Log("[!] StackTrace:" + Environment.NewLine + exception.StackTrace);
|
||||
Log("[!] EXCEPTION: " + previousMethodName + "() <" + botName + "> " + exception.Message);
|
||||
Log("[!] StackTrace:" + Environment.NewLine + exception.StackTrace);
|
||||
|
||||
if (exception.InnerException != null) {
|
||||
LogGenericException(exception.InnerException, botName, previousMethodName);
|
||||
if (exception.InnerException != null) {
|
||||
exception = exception.InnerException;
|
||||
continue;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
internal static void LogGenericWarning(string message, string botName = "Main", [CallerMemberName] string previousMethodName = "") {
|
||||
internal static void LogGenericWarning(string message, string botName = "Main", [CallerMemberName] string previousMethodName = null) {
|
||||
if (string.IsNullOrEmpty(message)) {
|
||||
LogNullError(nameof(message), botName);
|
||||
return;
|
||||
}
|
||||
|
||||
Log("[!] WARNING: " + previousMethodName + "() <" + botName + "> " + message);
|
||||
}
|
||||
|
||||
internal static void LogGenericInfo(string message, string botName = "Main", [CallerMemberName] string previousMethodName = "") {
|
||||
internal static void LogGenericInfo(string message, string botName = "Main", [CallerMemberName] string previousMethodName = null) {
|
||||
if (string.IsNullOrEmpty(message)) {
|
||||
LogNullError(nameof(message), botName);
|
||||
return;
|
||||
}
|
||||
|
||||
Log("[*] INFO: " + previousMethodName + "() <" + botName + "> " + message);
|
||||
}
|
||||
|
||||
internal static void LogNullError(string nullObjectName, string botName = "Main", [CallerMemberName] string previousMethodName = "") {
|
||||
if (string.IsNullOrEmpty(nullObjectName)) {
|
||||
return;
|
||||
}
|
||||
[SuppressMessage("ReSharper", "ExplicitCallerInfoArgument")]
|
||||
internal static void LogNullError(string nullObjectName, string botName = "Main", [CallerMemberName] string previousMethodName = null) {
|
||||
while (true) {
|
||||
if (string.IsNullOrEmpty(nullObjectName)) {
|
||||
nullObjectName = nameof(nullObjectName);
|
||||
continue;
|
||||
}
|
||||
|
||||
LogGenericError(nullObjectName + " is null!", botName, previousMethodName);
|
||||
LogGenericError(nullObjectName + " is null!", botName, previousMethodName);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
[Conditional("DEBUG")]
|
||||
internal static void LogGenericDebug(string message, string botName = "Main", [CallerMemberName] string previousMethodName = "") {
|
||||
[Conditional("DEBUG"), SuppressMessage("ReSharper", "UnusedMember.Global")]
|
||||
internal static void LogGenericDebug(string message, string botName = "Main", [CallerMemberName] string previousMethodName = null) {
|
||||
if (string.IsNullOrEmpty(message)) {
|
||||
LogNullError(nameof(message), botName);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -111,6 +135,7 @@ namespace ArchiSteamFarm {
|
||||
|
||||
private static void Log(string message) {
|
||||
if (string.IsNullOrEmpty(message)) {
|
||||
LogNullError(nameof(message));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -120,17 +145,25 @@ namespace ArchiSteamFarm {
|
||||
if (!Program.ConsoleIsBusy) {
|
||||
try {
|
||||
Console.Write(loggedMessage);
|
||||
} catch { }
|
||||
} catch {
|
||||
// Ignored
|
||||
}
|
||||
}
|
||||
|
||||
if (LogToFile) {
|
||||
lock (FileLock) {
|
||||
try {
|
||||
File.AppendAllText(Program.LogFile, loggedMessage);
|
||||
} catch (Exception e) {
|
||||
LogToFile = false;
|
||||
LogGenericException(e);
|
||||
}
|
||||
if (!LogToFile) {
|
||||
return;
|
||||
}
|
||||
|
||||
lock (FileLock) {
|
||||
if (!LogToFile) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
File.AppendAllText(Program.LogFile, loggedMessage);
|
||||
} catch (Exception e) {
|
||||
LogToFile = false;
|
||||
LogGenericException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,11 +26,13 @@ using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using ArchiSteamFarm.JSON;
|
||||
|
||||
namespace ArchiSteamFarm {
|
||||
internal static class Program {
|
||||
@@ -45,52 +47,57 @@ namespace ArchiSteamFarm {
|
||||
SteamParentalPIN,
|
||||
RevocationCode,
|
||||
TwoFactorAuthentication,
|
||||
WCFHostname
|
||||
}
|
||||
|
||||
internal enum EMode : byte {
|
||||
private enum EMode : byte {
|
||||
[SuppressMessage("ReSharper", "UnusedMember.Local")]
|
||||
Unknown,
|
||||
Normal, // Standard most common usage
|
||||
Client, // WCF client only
|
||||
Server // Normal + WCF server
|
||||
}
|
||||
|
||||
internal const string ASF = "ASF";
|
||||
internal const string ConfigDirectory = "config";
|
||||
internal const string DebugDirectory = "debug";
|
||||
internal const string LogFile = "log.txt";
|
||||
internal const string GlobalConfigFile = ASF + ".json";
|
||||
internal const string GlobalDatabaseFile = ASF + ".db";
|
||||
internal const string GithubRepo = "JustArchi/ArchiSteamFarm";
|
||||
|
||||
private const string GithubReleaseURL = "https://api.github.com/repos/JustArchi/ArchiSteamFarm/releases"; // GitHub API is HTTPS only
|
||||
private const string ASF = "ASF";
|
||||
private const string GithubReleaseURL = "https://api.github.com/repos/" + GithubRepo + "/releases"; // GitHub API is HTTPS only
|
||||
private const string GlobalConfigFile = ASF + ".json";
|
||||
private const string GlobalDatabaseFile = ASF + ".db";
|
||||
|
||||
private static readonly Assembly Assembly = Assembly.GetExecutingAssembly();
|
||||
internal static readonly Version Version = Assembly.GetName().Version;
|
||||
internal static readonly Version Version = Assembly.GetEntryAssembly().GetName().Version;
|
||||
|
||||
private static readonly object ConsoleLock = new object();
|
||||
private static readonly SemaphoreSlim SteamSemaphore = new SemaphoreSlim(1);
|
||||
private static readonly ManualResetEvent ShutdownResetEvent = new ManualResetEvent(false);
|
||||
private static readonly string ExecutableFile = Assembly.Location;
|
||||
private static readonly ManualResetEventSlim ShutdownResetEvent = new ManualResetEventSlim(false);
|
||||
private static readonly string ExecutableFile = Assembly.GetEntryAssembly().Location;
|
||||
private static readonly string ExecutableName = Path.GetFileName(ExecutableFile);
|
||||
private static readonly string ExecutableDirectory = Path.GetDirectoryName(ExecutableFile);
|
||||
private static readonly WCF WCF = new WCF();
|
||||
|
||||
internal static GlobalConfig GlobalConfig { 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; }
|
||||
|
||||
private static Timer AutoUpdatesTimer;
|
||||
private static EMode Mode = EMode.Normal;
|
||||
private static WebBrowser WebBrowser;
|
||||
|
||||
internal static async Task CheckForUpdate() {
|
||||
internal static async Task CheckForUpdate(bool updateOverride = false) {
|
||||
string oldExeFile = ExecutableFile + ".old";
|
||||
|
||||
// We booted successfully so we can now remove old exe file
|
||||
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 {
|
||||
File.Delete(oldExeFile);
|
||||
} catch (Exception e) {
|
||||
Logging.LogGenericException(e);
|
||||
return;
|
||||
Logging.LogGenericError("Could not remove old ASF binary, please remove " + oldExeFile + " manually in order for update function to work!");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -103,12 +110,9 @@ namespace ArchiSteamFarm {
|
||||
releaseURL += "/latest";
|
||||
}
|
||||
|
||||
string response = null;
|
||||
Logging.LogGenericInfo("Checking new version...");
|
||||
for (byte i = 0; i < WebBrowser.MaxRetries && string.IsNullOrEmpty(response); i++) {
|
||||
response = await WebBrowser.UrlGetToContent(releaseURL).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
string response = await WebBrowser.UrlGetToContentRetry(releaseURL).ConfigureAwait(false);
|
||||
if (string.IsNullOrEmpty(response)) {
|
||||
Logging.LogGenericWarning("Could not check latest version!");
|
||||
return;
|
||||
@@ -131,7 +135,7 @@ namespace ArchiSteamFarm {
|
||||
return;
|
||||
}
|
||||
|
||||
if (releases == null || releases.Count == 0) {
|
||||
if ((releases == null) || (releases.Count == 0)) {
|
||||
Logging.LogGenericWarning("Could not check latest version!");
|
||||
return;
|
||||
}
|
||||
@@ -149,40 +153,41 @@ namespace ArchiSteamFarm {
|
||||
Logging.LogGenericInfo("Local version: " + Version + " | Remote version: " + newVersion);
|
||||
|
||||
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");
|
||||
AutoUpdatesTimer = new Timer(
|
||||
async e => await CheckForUpdate().ConfigureAwait(false),
|
||||
null,
|
||||
TimeSpan.FromDays(1), // Delay
|
||||
TimeSpan.FromDays(1) // Period
|
||||
);
|
||||
if ((AutoUpdatesTimer != null) || !GlobalConfig.AutoUpdates) {
|
||||
return;
|
||||
}
|
||||
|
||||
Logging.LogGenericInfo("ASF will automatically check for new versions every 24 hours");
|
||||
|
||||
AutoUpdatesTimer = new Timer(
|
||||
async e => await CheckForUpdate().ConfigureAwait(false),
|
||||
null,
|
||||
TimeSpan.FromDays(1), // Delay
|
||||
TimeSpan.FromDays(1) // Period
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (!GlobalConfig.AutoUpdates) {
|
||||
if (!updateOverride && !GlobalConfig.AutoUpdates) {
|
||||
Logging.LogGenericInfo("New version is available!");
|
||||
Logging.LogGenericInfo("Consider updating yourself!");
|
||||
await Utilities.SleepAsync(5000).ConfigureAwait(false);
|
||||
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
|
||||
if (releaseResponse.Assets == null) {
|
||||
Logging.LogGenericWarning("Could not proceed with update because that version doesn't include assets!");
|
||||
return;
|
||||
}
|
||||
|
||||
GitHub.Asset binaryAsset = null;
|
||||
foreach (var asset in releaseResponse.Assets) {
|
||||
if (string.IsNullOrEmpty(asset.Name) || !asset.Name.Equals(ExecutableName)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
binaryAsset = asset;
|
||||
break;
|
||||
}
|
||||
GitHub.ReleaseResponse.Asset binaryAsset = releaseResponse.Assets.FirstOrDefault(asset => !string.IsNullOrEmpty(asset.Name) && asset.Name.Equals(ExecutableName, StringComparison.OrdinalIgnoreCase));
|
||||
|
||||
if (binaryAsset == null) {
|
||||
Logging.LogGenericWarning("Could not proceed with update because there is no asset that relates to currently running binary!");
|
||||
@@ -194,21 +199,16 @@ namespace ArchiSteamFarm {
|
||||
return;
|
||||
}
|
||||
|
||||
Logging.LogGenericInfo("Downloading new version...");
|
||||
Stream newExe = await WebBrowser.UrlGetToStream(binaryAsset.DownloadURL).ConfigureAwait(false);
|
||||
if (newExe == null) {
|
||||
Logging.LogGenericWarning("Could not download new version!");
|
||||
byte[] result = await WebBrowser.UrlGetToBytesRetry(binaryAsset.DownloadURL).ConfigureAwait(false);
|
||||
if (result == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// We start deep update logic here
|
||||
string newExeFile = ExecutableFile + ".new";
|
||||
|
||||
// Firstly we create new exec
|
||||
try {
|
||||
using (FileStream fileStream = File.Open(newExeFile, FileMode.Create)) {
|
||||
await newExe.CopyToAsync(fileStream).ConfigureAwait(false);
|
||||
}
|
||||
File.WriteAllBytes(newExeFile, result);
|
||||
} catch (Exception e) {
|
||||
Logging.LogGenericException(e);
|
||||
return;
|
||||
@@ -222,7 +222,9 @@ namespace ArchiSteamFarm {
|
||||
try {
|
||||
// Cleanup
|
||||
File.Delete(newExeFile);
|
||||
} catch { }
|
||||
} catch {
|
||||
// Ignored
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -235,88 +237,105 @@ namespace ArchiSteamFarm {
|
||||
// Cleanup
|
||||
File.Move(oldExeFile, ExecutableFile);
|
||||
File.Delete(newExeFile);
|
||||
} catch { }
|
||||
} catch {
|
||||
// Ignored
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
Logging.LogGenericInfo("Update process is finished! ASF will now restart itself...");
|
||||
await Utilities.SleepAsync(5000);
|
||||
Logging.LogGenericInfo("Update process finished!");
|
||||
|
||||
Restart();
|
||||
if (GlobalConfig.AutoRestart) {
|
||||
Logging.LogGenericInfo("Restarting...");
|
||||
await Utilities.SleepAsync(5000).ConfigureAwait(false);
|
||||
Restart();
|
||||
} else {
|
||||
Logging.LogGenericInfo("Exiting...");
|
||||
await Utilities.SleepAsync(5000).ConfigureAwait(false);
|
||||
Exit();
|
||||
}
|
||||
}
|
||||
|
||||
internal static void Exit(int exitCode = 0) {
|
||||
WCF.StopServer();
|
||||
Environment.Exit(exitCode);
|
||||
}
|
||||
|
||||
internal static void Restart() {
|
||||
try {
|
||||
Process.Start(ExecutableFile, string.Join(" ", Environment.GetCommandLineArgs().Skip(1)));
|
||||
Environment.Exit(0);
|
||||
} catch (Exception e) {
|
||||
Logging.LogGenericException(e);
|
||||
}
|
||||
|
||||
Exit();
|
||||
}
|
||||
|
||||
internal static async Task LimitSteamRequestsAsync() {
|
||||
await SteamSemaphore.WaitAsync().ConfigureAwait(false);
|
||||
Task.Run(async () => {
|
||||
await Utilities.SleepAsync(GlobalConfig.LoginLimiterDelay * 1000).ConfigureAwait(false);
|
||||
SteamSemaphore.Release();
|
||||
}).Forget();
|
||||
}
|
||||
|
||||
internal static string GetUserInput(string botLogin, EUserInputType userInputType, string extraInformation = null) {
|
||||
internal static string GetUserInput(EUserInputType userInputType, string botName = "Main", 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;
|
||||
lock (ConsoleLock) {
|
||||
ConsoleIsBusy = true;
|
||||
switch (userInputType) {
|
||||
case EUserInputType.DeviceID:
|
||||
Console.Write("<" + botLogin + "> Please enter your Device ID (including \"android:\"): ");
|
||||
Console.Write("<" + botName + "> Please enter your Device ID (including \"android:\"): ");
|
||||
break;
|
||||
case EUserInputType.Login:
|
||||
Console.Write("<" + botLogin + "> Please enter your login: ");
|
||||
Console.Write("<" + botName + "> Please enter your login: ");
|
||||
break;
|
||||
case EUserInputType.Password:
|
||||
Console.Write("<" + botLogin + "> Please enter your password: ");
|
||||
Console.Write("<" + botName + "> Please enter your password: ");
|
||||
break;
|
||||
case EUserInputType.PhoneNumber:
|
||||
Console.Write("<" + botLogin + "> Please enter your full phone number (e.g. +1234567890): ");
|
||||
Console.Write("<" + botName + "> Please enter your full phone number (e.g. +1234567890): ");
|
||||
break;
|
||||
case EUserInputType.SMS:
|
||||
Console.Write("<" + botLogin + "> Please enter SMS code sent on your mobile: ");
|
||||
Console.Write("<" + botName + "> Please enter SMS code sent on your mobile: ");
|
||||
break;
|
||||
case EUserInputType.SteamGuard:
|
||||
Console.Write("<" + botLogin + "> Please enter the auth code sent to your email: ");
|
||||
Console.Write("<" + botName + "> Please enter the auth code sent to your email: ");
|
||||
break;
|
||||
case EUserInputType.SteamParentalPIN:
|
||||
Console.Write("<" + botLogin + "> Please enter steam parental PIN: ");
|
||||
Console.Write("<" + botName + "> Please enter steam parental PIN: ");
|
||||
break;
|
||||
case EUserInputType.RevocationCode:
|
||||
Console.WriteLine("<" + botLogin + "> PLEASE WRITE DOWN YOUR REVOCATION CODE: " + extraInformation);
|
||||
Console.WriteLine("<" + botLogin + "> THIS IS THE ONLY WAY TO NOT GET LOCKED OUT OF YOUR ACCOUNT!");
|
||||
Console.Write("<" + botLogin + "> Hit enter once ready...");
|
||||
Console.WriteLine("<" + botName + "> PLEASE WRITE DOWN YOUR REVOCATION CODE: " + extraInformation);
|
||||
Console.Write("<" + botName + "> Hit enter once ready...");
|
||||
break;
|
||||
case EUserInputType.TwoFactorAuthentication:
|
||||
Console.Write("<" + botLogin + "> Please enter your 2 factor auth code from your authenticator app: ");
|
||||
Console.Write("<" + botName + "> Please enter your 2 factor auth code from your authenticator app: ");
|
||||
break;
|
||||
case EUserInputType.WCFHostname:
|
||||
Console.Write("<" + botName + "> Please enter your WCF hostname: ");
|
||||
break;
|
||||
default:
|
||||
Console.Write("<" + botLogin + "> Please enter not documented yet value of \"" + userInputType + "\": ");
|
||||
Console.Write("<" + botName + "> Please enter not documented yet value of \"" + userInputType + "\": ");
|
||||
break;
|
||||
}
|
||||
|
||||
result = Console.ReadLine();
|
||||
Console.Clear(); // For security purposes
|
||||
|
||||
if (!Console.IsOutputRedirected) {
|
||||
Console.Clear(); // For security purposes
|
||||
}
|
||||
|
||||
ConsoleIsBusy = false;
|
||||
}
|
||||
|
||||
return string.IsNullOrEmpty(result) ? null : result.Trim();
|
||||
return !string.IsNullOrEmpty(result) ? result.Trim() : null;
|
||||
}
|
||||
|
||||
internal static void OnBotShutdown() {
|
||||
foreach (Bot bot in Bot.Bots.Values) {
|
||||
if (bot.KeepRunning) {
|
||||
return;
|
||||
}
|
||||
if (Bot.Bots.Values.Any(bot => bot.KeepRunning)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (WCF.IsServerRunning()) {
|
||||
@@ -329,28 +348,37 @@ namespace ArchiSteamFarm {
|
||||
}
|
||||
|
||||
private static void InitServices() {
|
||||
GlobalConfig = GlobalConfig.Load();
|
||||
GlobalConfig = GlobalConfig.Load(Path.Combine(ConfigDirectory, GlobalConfigFile));
|
||||
if (GlobalConfig == null) {
|
||||
Logging.LogGenericError("Global config could not be loaded, please make sure that ASF.json exists and is valid!");
|
||||
Thread.Sleep(5000);
|
||||
Environment.Exit(1);
|
||||
Exit(1);
|
||||
}
|
||||
|
||||
GlobalDatabase = GlobalDatabase.Load();
|
||||
GlobalDatabase = GlobalDatabase.Load(Path.Combine(ConfigDirectory, GlobalDatabaseFile));
|
||||
if (GlobalDatabase == null) {
|
||||
Logging.LogGenericError("Global database could not be loaded!");
|
||||
Thread.Sleep(5000);
|
||||
Environment.Exit(1);
|
||||
Exit(1);
|
||||
}
|
||||
|
||||
ArchiWebHandler.Init();
|
||||
WebBrowser.Init();
|
||||
WCF.Init();
|
||||
|
||||
WebBrowser = new WebBrowser("Main");
|
||||
}
|
||||
|
||||
private static void ParseArgs(string[] args) {
|
||||
private static void ParseArgs(IEnumerable<string> args) {
|
||||
if (args == null) {
|
||||
Logging.LogNullError(nameof(args));
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (string arg in args) {
|
||||
switch (arg) {
|
||||
case "":
|
||||
break;
|
||||
case "--client":
|
||||
Mode = EMode.Client;
|
||||
break;
|
||||
@@ -359,7 +387,7 @@ namespace ArchiSteamFarm {
|
||||
WCF.StartServer();
|
||||
break;
|
||||
default:
|
||||
if (arg.StartsWith("--")) {
|
||||
if (arg.StartsWith("--", StringComparison.Ordinal)) {
|
||||
Logging.LogGenericWarning("Unrecognized parameter: " + arg);
|
||||
continue;
|
||||
}
|
||||
@@ -384,7 +412,8 @@ namespace ArchiSteamFarm {
|
||||
}
|
||||
|
||||
private static void UnhandledExceptionHandler(object sender, UnhandledExceptionEventArgs args) {
|
||||
if (sender == null || args == null) {
|
||||
if ((sender == null) || (args == null) || (args.ExceptionObject == null)) {
|
||||
Logging.LogNullError(nameof(sender) + " || " + nameof(args) + " || " + nameof(args.ExceptionObject));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -392,14 +421,15 @@ namespace ArchiSteamFarm {
|
||||
}
|
||||
|
||||
private static void UnobservedTaskExceptionHandler(object sender, UnobservedTaskExceptionEventArgs args) {
|
||||
if (sender == null || args == null) {
|
||||
if ((sender == null) || (args == null) || (args.Exception == null)) {
|
||||
Logging.LogNullError(nameof(sender) + " || " + nameof(args) + " || " + nameof(args.Exception));
|
||||
return;
|
||||
}
|
||||
|
||||
Logging.LogGenericException(args.Exception);
|
||||
}
|
||||
|
||||
private static void Init(string[] args) {
|
||||
private static void Init(IEnumerable<string> args) {
|
||||
AppDomain.CurrentDomain.UnhandledException += UnhandledExceptionHandler;
|
||||
TaskScheduler.UnobservedTaskException += UnobservedTaskExceptionHandler;
|
||||
|
||||
@@ -411,7 +441,7 @@ namespace ArchiSteamFarm {
|
||||
if (Debugging.IsDebugBuild) {
|
||||
|
||||
// Common structure is bin/(x64/)Debug/ArchiSteamFarm.exe, so we allow up to 4 directories up
|
||||
for (var i = 0; i < 4; i++) {
|
||||
for (byte i = 0; i < 4; i++) {
|
||||
Directory.SetCurrentDirectory("..");
|
||||
if (Directory.Exists(ConfigDirectory)) {
|
||||
break;
|
||||
@@ -432,16 +462,18 @@ namespace ArchiSteamFarm {
|
||||
}
|
||||
Directory.CreateDirectory(DebugDirectory);
|
||||
|
||||
SteamKit2.DebugLog.AddListener(new Debugging.DebugListener(Path.Combine(Program.DebugDirectory, "debug.txt")));
|
||||
SteamKit2.DebugLog.AddListener(new Debugging.DebugListener(Path.Combine(DebugDirectory, "debug.txt")));
|
||||
SteamKit2.DebugLog.Enabled = true;
|
||||
}
|
||||
|
||||
// Parse args
|
||||
ParseArgs(args);
|
||||
if (args != null) {
|
||||
ParseArgs(args);
|
||||
}
|
||||
|
||||
// If we ran ASF as a client, we're done by now
|
||||
if (Mode == EMode.Client) {
|
||||
Environment.Exit(0);
|
||||
Exit();
|
||||
}
|
||||
|
||||
// From now on it's server mode
|
||||
@@ -450,7 +482,7 @@ namespace ArchiSteamFarm {
|
||||
if (!Directory.Exists(ConfigDirectory)) {
|
||||
Logging.LogGenericError("Config directory doesn't exist!");
|
||||
Thread.Sleep(5000);
|
||||
Environment.Exit(1);
|
||||
Exit(1);
|
||||
}
|
||||
|
||||
CheckForUpdate().Wait();
|
||||
@@ -460,8 +492,7 @@ namespace ArchiSteamFarm {
|
||||
|
||||
bool isRunning = false;
|
||||
|
||||
foreach (var configFile in Directory.EnumerateFiles(ConfigDirectory, "*.json")) {
|
||||
string botName = Path.GetFileNameWithoutExtension(configFile);
|
||||
foreach (string botName in Directory.EnumerateFiles(ConfigDirectory, "*.json").Select(Path.GetFileNameWithoutExtension)) {
|
||||
switch (botName) {
|
||||
case ASF:
|
||||
case "example":
|
||||
@@ -470,25 +501,14 @@ namespace ArchiSteamFarm {
|
||||
}
|
||||
|
||||
Bot bot = new Bot(botName);
|
||||
if (bot.BotConfig != null && bot.BotConfig.Enabled) {
|
||||
isRunning = true;
|
||||
} else {
|
||||
Logging.LogGenericInfo("Not starting this instance because it's disabled in config file", botName);
|
||||
if ((bot.BotConfig == null) || !bot.BotConfig.Enabled) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// 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 != null && bot.BotConfig.Enabled) {
|
||||
if (bot.BotConfig.StartOnLaunch) {
|
||||
isRunning = true;
|
||||
} else {
|
||||
Logging.LogGenericInfo("Not starting this instance because it's disabled in config file", botName);
|
||||
}
|
||||
}
|
||||
// CONVERSION END
|
||||
|
||||
// Check if we got any bots running
|
||||
if (!isRunning) {
|
||||
@@ -500,10 +520,10 @@ namespace ArchiSteamFarm {
|
||||
Init(args);
|
||||
|
||||
// Wait for signal to shutdown
|
||||
ShutdownResetEvent.WaitOne();
|
||||
ShutdownResetEvent.Wait();
|
||||
|
||||
// We got a signal to shutdown
|
||||
Environment.Exit(0);
|
||||
Exit();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// 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("ArchiSteamFarm")]
|
||||
@@ -10,12 +9,12 @@ using System.Runtime.InteropServices;
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("ArchiSteamFarm")]
|
||||
[assembly: AssemblyCopyright("Copyright © Łukasz Domeradzki 2015-2016")]
|
||||
[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
|
||||
// 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)]
|
||||
|
||||
@@ -25,12 +24,12 @@ using System.Runtime.InteropServices;
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// 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:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("2.0.1.7")]
|
||||
[assembly: AssemblyFileVersion("2.0.1.7")]
|
||||
[assembly: AssemblyVersion("2.0.5.0")]
|
||||
[assembly: AssemblyFileVersion("2.0.5.0")]
|
||||
|
||||
@@ -23,9 +23,12 @@
|
||||
*/
|
||||
|
||||
using SteamAuth;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using ArchiSteamFarm.JSON;
|
||||
|
||||
namespace ArchiSteamFarm {
|
||||
internal sealed class Trading {
|
||||
@@ -35,9 +38,9 @@ namespace ArchiSteamFarm {
|
||||
private static readonly SemaphoreSlim InventorySemaphore = new SemaphoreSlim(1);
|
||||
|
||||
private readonly Bot Bot;
|
||||
private readonly SemaphoreSlim Semaphore = new SemaphoreSlim(1);
|
||||
private readonly SemaphoreSlim TradesSemaphore = new SemaphoreSlim(1);
|
||||
|
||||
private volatile byte ParsingTasks = 0;
|
||||
private byte ParsingTasks;
|
||||
|
||||
internal static async Task LimitInventoryRequestsAsync() {
|
||||
await InventorySemaphore.WaitAsync().ConfigureAwait(false);
|
||||
@@ -49,59 +52,163 @@ namespace ArchiSteamFarm {
|
||||
|
||||
internal Trading(Bot bot) {
|
||||
if (bot == null) {
|
||||
return;
|
||||
throw new ArgumentNullException(nameof(bot));
|
||||
}
|
||||
|
||||
Bot = bot;
|
||||
}
|
||||
|
||||
internal async void CheckTrades() {
|
||||
if (ParsingTasks >= 2) {
|
||||
return;
|
||||
internal async Task CheckTrades() {
|
||||
lock (TradesSemaphore) {
|
||||
if (ParsingTasks >= 2) {
|
||||
return;
|
||||
}
|
||||
|
||||
ParsingTasks++;
|
||||
}
|
||||
|
||||
ParsingTasks++;
|
||||
await TradesSemaphore.WaitAsync().ConfigureAwait(false);
|
||||
|
||||
await Semaphore.WaitAsync().ConfigureAwait(false);
|
||||
await ParseActiveTrades().ConfigureAwait(false);
|
||||
Semaphore.Release();
|
||||
lock (TradesSemaphore) {
|
||||
ParsingTasks--;
|
||||
}
|
||||
|
||||
ParsingTasks--;
|
||||
TradesSemaphore.Release();
|
||||
}
|
||||
|
||||
private async Task ParseActiveTrades() {
|
||||
List<Steam.TradeOffer> tradeOffers = Bot.ArchiWebHandler.GetTradeOffers();
|
||||
if (tradeOffers == null) {
|
||||
HashSet<Steam.TradeOffer> tradeOffers = Bot.ArchiWebHandler.GetTradeOffers();
|
||||
if ((tradeOffers == null) || (tradeOffers.Count == 0)) {
|
||||
return;
|
||||
}
|
||||
|
||||
List<Task> tasks = new List<Task>();
|
||||
foreach (Steam.TradeOffer tradeOffer in tradeOffers) {
|
||||
if (tradeOffer.trade_offer_state == Steam.TradeOffer.ETradeOfferState.Active) {
|
||||
tasks.Add(Task.Run(async () => await ParseTrade(tradeOffer).ConfigureAwait(false)));
|
||||
}
|
||||
tradeOffers.RemoveWhere(tradeoffer => tradeoffer.State != Steam.TradeOffer.ETradeOfferState.Active);
|
||||
tradeOffers.TrimExcess();
|
||||
|
||||
if (tradeOffers.Count == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
await Task.WhenAll(tasks).ConfigureAwait(false);
|
||||
await Bot.AcceptConfirmations(Confirmation.ConfirmationType.Trade).ConfigureAwait(false);
|
||||
await tradeOffers.ForEachAsync(ParseTrade).ConfigureAwait(false);
|
||||
await Bot.AcceptConfirmations(true, Confirmation.ConfirmationType.Trade).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
private async Task ParseTrade(Steam.TradeOffer tradeOffer) {
|
||||
if (tradeOffer == null) {
|
||||
Logging.LogNullError(nameof(tradeOffer), Bot.BotName);
|
||||
return;
|
||||
}
|
||||
|
||||
ulong tradeID;
|
||||
if (!ulong.TryParse(tradeOffer.tradeofferid, out tradeID)) {
|
||||
if (tradeOffer.State != Steam.TradeOffer.ETradeOfferState.Active) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (tradeOffer.items_to_give.Count == 0 || tradeOffer.OtherSteamID64 == Bot.BotConfig.SteamMasterID) {
|
||||
Logging.LogGenericInfo("Accepting trade: " + tradeID, Bot.BotName);
|
||||
await Bot.ArchiWebHandler.AcceptTradeOffer(tradeID).ConfigureAwait(false);
|
||||
if (await ShouldAcceptTrade(tradeOffer).ConfigureAwait(false)) {
|
||||
Logging.LogGenericInfo("Accepting trade: " + tradeOffer.TradeOfferID, Bot.BotName);
|
||||
await Bot.ArchiWebHandler.AcceptTradeOffer(tradeOffer.TradeOfferID).ConfigureAwait(false);
|
||||
} else {
|
||||
Logging.LogGenericInfo("Ignoring trade: " + tradeID, Bot.BotName);
|
||||
Logging.LogGenericInfo("Ignoring trade: " + tradeOffer.TradeOfferID, Bot.BotName);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task<bool> ShouldAcceptTrade(Steam.TradeOffer tradeOffer) {
|
||||
if (tradeOffer == null) {
|
||||
Logging.LogNullError(nameof(tradeOffer), Bot.BotName);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Always accept trades when we're not losing anything
|
||||
if (tradeOffer.ItemsToGive.Count == 0) {
|
||||
// Unless it's steam fuckup and we're dealing with broken trade
|
||||
return tradeOffer.ItemsToReceive.Count > 0;
|
||||
}
|
||||
|
||||
// Always accept trades from SteamMasterID
|
||||
if ((tradeOffer.OtherSteamID64 != 0) && (tradeOffer.OtherSteamID64 == Bot.BotConfig.SteamMasterID)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// If we don't have SteamTradeMatcher enabled, this is the end for us
|
||||
if (!Bot.BotConfig.SteamTradeMatcher) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Decline trade if we're giving more count-wise
|
||||
if (tradeOffer.ItemsToGive.Count > tradeOffer.ItemsToReceive.Count) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Decline trade if we're losing anything but steam cards, or if it's non-dupes trade
|
||||
if (!tradeOffer.IsSteamCardsOnlyTradeForUs() || !tradeOffer.IsPotentiallyDupesTradeForUs()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// At this point we're sure that STM trade is valid
|
||||
// Now check if it's worth for us to do the trade
|
||||
HashSet<Steam.Item> inventory = await Bot.ArchiWebHandler.GetMyTradableInventory().ConfigureAwait(false);
|
||||
if ((inventory == null) || (inventory.Count == 0)) {
|
||||
return true; // OK, assume that this trade is valid, we can't check our EQ
|
||||
}
|
||||
|
||||
// Get appIDs we're interested in
|
||||
HashSet<uint> appIDs = new HashSet<uint>(tradeOffer.ItemsToGive.Select(item => item.RealAppID));
|
||||
|
||||
// Now remove from our inventory all items we're NOT interested in
|
||||
inventory.RemoveWhere(item => !appIDs.Contains(item.RealAppID));
|
||||
inventory.TrimExcess();
|
||||
|
||||
// If for some reason Valve is talking crap and we can't find mentioned items, assume OK
|
||||
if (inventory.Count == 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Now let's create a map which maps items to their amount in our EQ
|
||||
Dictionary<ulong, uint> amountMap = new Dictionary<ulong, uint>();
|
||||
foreach (Steam.Item item in inventory) {
|
||||
uint amount;
|
||||
if (amountMap.TryGetValue(item.ClassID, out amount)) {
|
||||
amountMap[item.ClassID] = amount + item.Amount;
|
||||
} else {
|
||||
amountMap[item.ClassID] = item.Amount;
|
||||
}
|
||||
}
|
||||
|
||||
// Calculate our value of items to give
|
||||
List<uint> amountsToGive = new List<uint>(tradeOffer.ItemsToGive.Count);
|
||||
foreach (ulong key in tradeOffer.ItemsToGive.Select(item => item.ClassID)) {
|
||||
uint amount;
|
||||
if (!amountMap.TryGetValue(key, out amount)) {
|
||||
amountsToGive.Add(0);
|
||||
continue;
|
||||
}
|
||||
|
||||
amountsToGive.Add(amount);
|
||||
}
|
||||
|
||||
// Sort it ascending
|
||||
amountsToGive.Sort();
|
||||
|
||||
// Calculate our value of items to receive
|
||||
List<uint> amountsToReceive = new List<uint>(tradeOffer.ItemsToReceive.Count);
|
||||
foreach (ulong key in tradeOffer.ItemsToReceive.Select(item => item.ClassID)) {
|
||||
uint amount;
|
||||
if (!amountMap.TryGetValue(key, out amount)) {
|
||||
amountsToReceive.Add(0);
|
||||
continue;
|
||||
}
|
||||
|
||||
amountsToReceive.Add(amount);
|
||||
}
|
||||
|
||||
// Sort it ascending
|
||||
amountsToReceive.Sort();
|
||||
|
||||
// Check actual difference
|
||||
int difference = amountsToGive.Select((t, i) => (int) (t - amountsToReceive[i])).Sum();
|
||||
|
||||
// Trade is worth for us if the difference is greater than 0
|
||||
return difference > 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,56 +22,53 @@
|
||||
|
||||
*/
|
||||
|
||||
using System.Text.RegularExpressions;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace ArchiSteamFarm {
|
||||
internal static class Utilities {
|
||||
[SuppressMessage("ReSharper", "UnusedParameter.Global")]
|
||||
internal static void Forget(this Task task) { }
|
||||
|
||||
internal static async Task SleepAsync(int miliseconds) {
|
||||
await Task.Delay(miliseconds).ConfigureAwait(false);
|
||||
internal static Task ForEachAsync<T>(this IEnumerable<T> sequence, Func<T, Task> action) {
|
||||
if (action != null) {
|
||||
return Task.WhenAll(sequence.Select(action));
|
||||
}
|
||||
|
||||
Logging.LogNullError(nameof(action));
|
||||
return Task.FromResult(true);
|
||||
}
|
||||
|
||||
internal static ulong OnlyNumbers(string inputString) {
|
||||
if (string.IsNullOrEmpty(inputString)) {
|
||||
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)) {
|
||||
internal static string GetCookieValue(this CookieContainer cookieContainer, string url, string name) {
|
||||
if (string.IsNullOrEmpty(url) || string.IsNullOrEmpty(name)) {
|
||||
Logging.LogNullError(nameof(url) + " || " + nameof(name));
|
||||
return null;
|
||||
}
|
||||
|
||||
return Regex.Replace(text, @"[^\d]", "");
|
||||
Uri uri;
|
||||
|
||||
try {
|
||||
uri = new Uri(url);
|
||||
} catch (UriFormatException e) {
|
||||
Logging.LogGenericException(e);
|
||||
return null;
|
||||
}
|
||||
|
||||
CookieCollection cookies = cookieContainer.GetCookies(uri);
|
||||
return cookies.Count == 0 ? null : (from Cookie cookie in cookies where cookie.Name.Equals(name) select cookie.Value).FirstOrDefault();
|
||||
}
|
||||
|
||||
internal static uint GetCharCountInString(string s, char c) {
|
||||
if (string.IsNullOrEmpty(s)) {
|
||||
return 0;
|
||||
internal static Task SleepAsync(int miliseconds) {
|
||||
if (miliseconds >= 0) {
|
||||
return Task.Delay(miliseconds);
|
||||
}
|
||||
|
||||
uint count = 0;
|
||||
foreach (char singleChar in s) {
|
||||
if (singleChar == c) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
Logging.LogNullError(nameof(miliseconds));
|
||||
return Task.FromResult(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,12 +42,17 @@ namespace ArchiSteamFarm {
|
||||
private Client Client;
|
||||
|
||||
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";
|
||||
}
|
||||
|
||||
internal bool IsServerRunning() {
|
||||
return ServiceHost != null;
|
||||
}
|
||||
internal bool IsServerRunning() => ServiceHost != null;
|
||||
|
||||
internal void StartServer() {
|
||||
if (ServiceHost != null) {
|
||||
@@ -82,6 +87,11 @@ namespace ArchiSteamFarm {
|
||||
}
|
||||
|
||||
internal string SendCommand(string input) {
|
||||
if (string.IsNullOrEmpty(input)) {
|
||||
Logging.LogNullError(nameof(input));
|
||||
return null;
|
||||
}
|
||||
|
||||
if (Client == null) {
|
||||
Client = new Client(new BasicHttpBinding(), new EndpointAddress(URL));
|
||||
}
|
||||
@@ -91,31 +101,20 @@ namespace ArchiSteamFarm {
|
||||
|
||||
public string HandleCommand(string input) {
|
||||
if (string.IsNullOrEmpty(input)) {
|
||||
Logging.LogNullError(nameof(input));
|
||||
return null;
|
||||
}
|
||||
|
||||
string[] args = input.Split(' ');
|
||||
|
||||
string botName;
|
||||
|
||||
if (args.Length > 1) { // If we have args[1] provided, use given botName
|
||||
botName = args[1];
|
||||
} else { // If not, just pick first one
|
||||
botName = Bot.Bots.Keys.FirstOrDefault();
|
||||
Bot bot = Bot.Bots.Values.FirstOrDefault();
|
||||
if (bot == null) {
|
||||
return "ERROR: No bots are enabled!";
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(botName)) {
|
||||
return "ERROR: Invalid botName: " + botName;
|
||||
if (Program.GlobalConfig.SteamOwnerID == 0) {
|
||||
return "Refusing to handle request because SteamOwnerID is not set!";
|
||||
}
|
||||
|
||||
Bot bot;
|
||||
if (!Bot.Bots.TryGetValue(botName, out bot)) {
|
||||
return "ERROR: Couldn't find any bot named: " + botName;
|
||||
}
|
||||
|
||||
Logging.LogGenericInfo("Received command: " + input);
|
||||
|
||||
string command = '!' + input;
|
||||
string command = "!" + input;
|
||||
string output = bot.Response(Program.GlobalConfig.SteamOwnerID, command).Result; // TODO: This should be asynchronous
|
||||
|
||||
Logging.LogGenericInfo("Answered to command: " + input + " with: " + output);
|
||||
@@ -127,6 +126,11 @@ namespace ArchiSteamFarm {
|
||||
internal Client(Binding binding, EndpointAddress address) : base(binding, address) { }
|
||||
|
||||
public string HandleCommand(string input) {
|
||||
if (string.IsNullOrEmpty(input)) {
|
||||
Logging.LogNullError(nameof(input));
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
return Channel.HandleCommand(input);
|
||||
} catch (Exception e) {
|
||||
|
||||
@@ -23,37 +23,30 @@
|
||||
*/
|
||||
|
||||
using HtmlAgilityPack;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Xml;
|
||||
|
||||
namespace ArchiSteamFarm {
|
||||
internal static class WebBrowser {
|
||||
internal sealed class WebBrowser {
|
||||
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 HttpClient HttpClient = new HttpClient(new HttpClientHandler {
|
||||
UseCookies = false
|
||||
}) {
|
||||
Timeout = TimeSpan.FromSeconds(60)
|
||||
};
|
||||
|
||||
internal readonly CookieContainer CookieContainer = new CookieContainer();
|
||||
|
||||
private readonly HttpClient HttpClient;
|
||||
private readonly string Identifier;
|
||||
|
||||
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
|
||||
ServicePointManager.DefaultConnectionLimit = MaxConnections;
|
||||
|
||||
@@ -63,84 +56,237 @@ namespace ArchiSteamFarm {
|
||||
// Don't use Expect100Continue, we're sure about our POSTs, save some TCP packets
|
||||
ServicePointManager.Expect100Continue = false;
|
||||
|
||||
// Reuse ports if possible
|
||||
// TODO: Mono doesn't support that feature yet
|
||||
#if !__MonoCS__
|
||||
// Reuse ports if possible (since .NET 4.6+)
|
||||
//ServicePointManager.ReusePort = true;
|
||||
#endif
|
||||
}
|
||||
|
||||
internal static async Task<HttpResponseMessage> UrlGet(string request, Dictionary<string, string> cookies = null, string referer = null) {
|
||||
if (string.IsNullOrEmpty(request)) {
|
||||
return null;
|
||||
internal WebBrowser(string identifier) {
|
||||
if (string.IsNullOrEmpty(identifier)) {
|
||||
throw new ArgumentNullException(nameof(identifier));
|
||||
}
|
||||
|
||||
return await UrlRequest(request, HttpMethod.Get, null, cookies, referer).ConfigureAwait(false);
|
||||
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 static async Task<HttpResponseMessage> UrlPost(string request, Dictionary<string, string> data = null, Dictionary<string, string> cookies = null, string referer = null) {
|
||||
internal async Task<bool> UrlHeadRetry(string request, string referer = null) {
|
||||
if (string.IsNullOrEmpty(request)) {
|
||||
return null;
|
||||
Logging.LogNullError(nameof(request));
|
||||
return false;
|
||||
}
|
||||
|
||||
return await UrlRequest(request, HttpMethod.Post, data, cookies, referer).ConfigureAwait(false);
|
||||
bool result = false;
|
||||
for (byte i = 0; (i < MaxRetries) && !result; i++) {
|
||||
result = await UrlHead(request, referer).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
if (result) {
|
||||
return true;
|
||||
}
|
||||
|
||||
Logging.LogGenericWTF("Request failed even after " + MaxRetries + " tries", Identifier);
|
||||
return false;
|
||||
}
|
||||
|
||||
internal static async Task<string> UrlGetToContent(string request, Dictionary<string, string> cookies = null, string referer = null) {
|
||||
internal async Task<Uri> UrlHeadToUriRetry(string request, string referer = null) {
|
||||
if (string.IsNullOrEmpty(request)) {
|
||||
Logging.LogNullError(nameof(request));
|
||||
return null;
|
||||
}
|
||||
|
||||
HttpResponseMessage httpResponse = await UrlGet(request, cookies, referer).ConfigureAwait(false);
|
||||
if (httpResponse == null) {
|
||||
return null;
|
||||
Uri result = null;
|
||||
for (byte i = 0; (i < MaxRetries) && (result == null); i++) {
|
||||
result = await UrlHeadToUri(request, referer).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
if (httpResponse.Content == null) {
|
||||
return null;
|
||||
if (result != null) {
|
||||
return result;
|
||||
}
|
||||
|
||||
return await httpResponse.Content.ReadAsStringAsync().ConfigureAwait(false);
|
||||
Logging.LogGenericWTF("Request failed even after " + MaxRetries + " tries", Identifier);
|
||||
return null;
|
||||
}
|
||||
|
||||
internal static async Task<Stream> UrlGetToStream(string request, Dictionary<string, string> cookies = null, string referer = null) {
|
||||
internal async Task<byte[]> UrlGetToBytesRetry(string request, string referer = null) {
|
||||
if (string.IsNullOrEmpty(request)) {
|
||||
Logging.LogNullError(nameof(request));
|
||||
return null;
|
||||
}
|
||||
|
||||
HttpResponseMessage httpResponse = await UrlGet(request, cookies, referer).ConfigureAwait(false);
|
||||
if (httpResponse == null) {
|
||||
return null;
|
||||
byte[] result = null;
|
||||
for (byte i = 0; (i < MaxRetries) && (result == null); i++) {
|
||||
result = await UrlGetToBytes(request, referer).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
if (httpResponse.Content == null) {
|
||||
return null;
|
||||
if (result != null) {
|
||||
return result;
|
||||
}
|
||||
|
||||
return await httpResponse.Content.ReadAsStreamAsync().ConfigureAwait(false);
|
||||
Logging.LogGenericWTF("Request failed even after " + MaxRetries + " tries", Identifier);
|
||||
return null;
|
||||
}
|
||||
|
||||
internal static async Task<HtmlDocument> UrlGetToHtmlDocument(string request, Dictionary<string, string> cookies = null, string referer = null) {
|
||||
internal async Task<string> UrlGetToContentRetry(string request, string referer = null) {
|
||||
if (string.IsNullOrEmpty(request)) {
|
||||
Logging.LogNullError(nameof(request));
|
||||
return null;
|
||||
}
|
||||
|
||||
string content = await UrlGetToContent(request, cookies, referer).ConfigureAwait(false);
|
||||
string result = null;
|
||||
for (byte i = 0; (i < MaxRetries) && string.IsNullOrEmpty(result); i++) {
|
||||
result = await UrlGetToContent(request, referer).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(result)) {
|
||||
return result;
|
||||
}
|
||||
|
||||
Logging.LogGenericWTF("Request failed even after " + MaxRetries + " tries", Identifier);
|
||||
return null;
|
||||
}
|
||||
|
||||
internal async Task<HtmlDocument> UrlGetToHtmlDocumentRetry(string request, string referer = null) {
|
||||
if (string.IsNullOrEmpty(request)) {
|
||||
Logging.LogNullError(nameof(request));
|
||||
return null;
|
||||
}
|
||||
|
||||
HtmlDocument result = null;
|
||||
for (byte i = 0; (i < MaxRetries) && (result == null); i++) {
|
||||
result = await UrlGetToHtmlDocument(request, referer).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
if (result != null) {
|
||||
return result;
|
||||
}
|
||||
|
||||
Logging.LogGenericWTF("Request failed even after " + MaxRetries + " tries", Identifier);
|
||||
return null;
|
||||
}
|
||||
|
||||
internal async Task<JObject> UrlGetToJObjectRetry(string request, string referer = null) {
|
||||
if (string.IsNullOrEmpty(request)) {
|
||||
Logging.LogNullError(nameof(request));
|
||||
return null;
|
||||
}
|
||||
|
||||
JObject result = null;
|
||||
for (byte i = 0; (i < MaxRetries) && (result == null); i++) {
|
||||
result = await UrlGetToJObject(request, referer).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
if (result != null) {
|
||||
return result;
|
||||
}
|
||||
|
||||
Logging.LogGenericWTF("Request failed even after " + MaxRetries + " tries", Identifier);
|
||||
return null;
|
||||
}
|
||||
|
||||
internal async Task<XmlDocument> UrlGetToXMLRetry(string request, string referer = null) {
|
||||
if (string.IsNullOrEmpty(request)) {
|
||||
Logging.LogNullError(nameof(request));
|
||||
return null;
|
||||
}
|
||||
|
||||
XmlDocument result = null;
|
||||
for (byte i = 0; (i < MaxRetries) && (result == null); i++) {
|
||||
result = await UrlGetToXML(request, referer).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
if (result != null) {
|
||||
return result;
|
||||
}
|
||||
|
||||
Logging.LogGenericWTF("Request failed even after " + MaxRetries + " tries", Identifier);
|
||||
return null;
|
||||
}
|
||||
|
||||
internal async Task<bool> UrlPostRetry(string request, Dictionary<string, string> data = null, string referer = null) {
|
||||
if (string.IsNullOrEmpty(request)) {
|
||||
Logging.LogNullError(nameof(request));
|
||||
return false;
|
||||
}
|
||||
|
||||
bool result = false;
|
||||
for (byte i = 0; (i < MaxRetries) && !result; i++) {
|
||||
result = await UrlPost(request, data, referer).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
if (result) {
|
||||
return true;
|
||||
}
|
||||
|
||||
Logging.LogGenericWTF("Request failed even after " + MaxRetries + " tries", Identifier);
|
||||
return false;
|
||||
}
|
||||
|
||||
private async Task<byte[]> UrlGetToBytes(string request, string referer = null) {
|
||||
if (string.IsNullOrEmpty(request)) {
|
||||
Logging.LogNullError(nameof(request));
|
||||
return null;
|
||||
}
|
||||
|
||||
using (HttpResponseMessage httpResponse = await UrlGetToResponse(request, referer).ConfigureAwait(false)) {
|
||||
if (httpResponse == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return await httpResponse.Content.ReadAsByteArrayAsync().ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task<string> UrlGetToContent(string request, string referer = null) {
|
||||
if (string.IsNullOrEmpty(request)) {
|
||||
Logging.LogNullError(nameof(request));
|
||||
return null;
|
||||
}
|
||||
|
||||
using (HttpResponseMessage httpResponse = await UrlGetToResponse(request, referer).ConfigureAwait(false)) {
|
||||
if (httpResponse == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return await httpResponse.Content.ReadAsStringAsync().ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task<HtmlDocument> UrlGetToHtmlDocument(string request, string referer = null) {
|
||||
if (string.IsNullOrEmpty(request)) {
|
||||
Logging.LogNullError(nameof(request));
|
||||
return null;
|
||||
}
|
||||
|
||||
string content = await UrlGetToContent(request, referer).ConfigureAwait(false);
|
||||
if (string.IsNullOrEmpty(content)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
content = WebUtility.HtmlDecode(content);
|
||||
HtmlDocument htmlDocument = new HtmlDocument();
|
||||
htmlDocument.LoadHtml(content);
|
||||
|
||||
htmlDocument.LoadHtml(WebUtility.HtmlDecode(content));
|
||||
return htmlDocument;
|
||||
}
|
||||
|
||||
internal static async Task<JObject> UrlGetToJObject(string request, Dictionary<string, string> cookies = null, string referer = null) {
|
||||
private async Task<JObject> UrlGetToJObject(string request, string referer = null) {
|
||||
if (string.IsNullOrEmpty(request)) {
|
||||
Logging.LogNullError(nameof(request));
|
||||
return null;
|
||||
}
|
||||
|
||||
string content = await UrlGetToContent(request, cookies, referer).ConfigureAwait(false);
|
||||
string content = await UrlGetToContent(request, referer).ConfigureAwait(false);
|
||||
if (string.IsNullOrEmpty(content)) {
|
||||
return null;
|
||||
}
|
||||
@@ -149,20 +295,30 @@ namespace ArchiSteamFarm {
|
||||
|
||||
try {
|
||||
jObject = JObject.Parse(content);
|
||||
} catch (Exception e) {
|
||||
Logging.LogGenericException(e);
|
||||
} catch (JsonException e) {
|
||||
Logging.LogGenericException(e, Identifier);
|
||||
return null;
|
||||
}
|
||||
|
||||
return jObject;
|
||||
}
|
||||
|
||||
internal static async Task<XmlDocument> UrlGetToXML(string request, Dictionary<string, string> cookies = null, string referer = null) {
|
||||
private async Task<HttpResponseMessage> UrlGetToResponse(string request, string referer = null) {
|
||||
if (!string.IsNullOrEmpty(request)) {
|
||||
return await UrlRequest(request, HttpMethod.Get, null, referer).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
Logging.LogNullError(nameof(request));
|
||||
return null;
|
||||
}
|
||||
|
||||
private async Task<XmlDocument> UrlGetToXML(string request, string referer = null) {
|
||||
if (string.IsNullOrEmpty(request)) {
|
||||
Logging.LogNullError(nameof(request));
|
||||
return null;
|
||||
}
|
||||
|
||||
string content = await UrlGetToContent(request, cookies, referer).ConfigureAwait(false);
|
||||
string content = await UrlGetToContent(request, referer).ConfigureAwait(false);
|
||||
if (string.IsNullOrEmpty(content)) {
|
||||
return null;
|
||||
}
|
||||
@@ -172,37 +328,85 @@ namespace ArchiSteamFarm {
|
||||
try {
|
||||
xmlDocument.LoadXml(content);
|
||||
} catch (XmlException e) {
|
||||
Logging.LogGenericException(e);
|
||||
Logging.LogGenericException(e, Identifier);
|
||||
return null;
|
||||
}
|
||||
|
||||
return xmlDocument;
|
||||
}
|
||||
|
||||
private static async Task<HttpResponseMessage> UrlRequest(string request, HttpMethod httpMethod, Dictionary<string, string> data = null, Dictionary<string, string> cookies = null, string referer = null) {
|
||||
if (string.IsNullOrEmpty(request) || httpMethod == null) {
|
||||
private async Task<bool> UrlHead(string request, string referer = null) {
|
||||
if (string.IsNullOrEmpty(request)) {
|
||||
Logging.LogNullError(nameof(request));
|
||||
return false;
|
||||
}
|
||||
|
||||
using (HttpResponseMessage response = await UrlHeadToResponse(request, referer).ConfigureAwait(false)) {
|
||||
return response != null;
|
||||
}
|
||||
}
|
||||
|
||||
private async Task<HttpResponseMessage> UrlHeadToResponse(string request, string referer = null) {
|
||||
if (!string.IsNullOrEmpty(request)) {
|
||||
return await UrlRequest(request, HttpMethod.Head, null, referer).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
Logging.LogNullError(nameof(request));
|
||||
return null;
|
||||
}
|
||||
|
||||
private async Task<Uri> UrlHeadToUri(string request, string referer = null) {
|
||||
if (string.IsNullOrEmpty(request)) {
|
||||
Logging.LogNullError(nameof(request));
|
||||
return null;
|
||||
}
|
||||
|
||||
using (HttpResponseMessage response = await UrlHeadToResponse(request, referer).ConfigureAwait(false)) {
|
||||
return response == null ? null : response.RequestMessage.RequestUri;
|
||||
}
|
||||
}
|
||||
|
||||
private async Task<bool> UrlPost(string request, Dictionary<string, string> data = null, string referer = null) {
|
||||
if (string.IsNullOrEmpty(request)) {
|
||||
Logging.LogNullError(nameof(request));
|
||||
return false;
|
||||
}
|
||||
|
||||
using (HttpResponseMessage response = await UrlPostToResponse(request, data, referer).ConfigureAwait(false)) {
|
||||
return response != null;
|
||||
}
|
||||
}
|
||||
|
||||
private async Task<HttpResponseMessage> UrlPostToResponse(string request, Dictionary<string, string> data = null, string referer = null) {
|
||||
if (!string.IsNullOrEmpty(request)) {
|
||||
return await UrlRequest(request, HttpMethod.Post, data, referer).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
Logging.LogNullError(nameof(request));
|
||||
return null;
|
||||
}
|
||||
|
||||
private async Task<HttpResponseMessage> UrlRequest(string request, HttpMethod httpMethod, Dictionary<string, string> data = null, string referer = null) {
|
||||
if (string.IsNullOrEmpty(request) || (httpMethod == null)) {
|
||||
Logging.LogNullError(nameof(request) + " || " + nameof(httpMethod));
|
||||
return null;
|
||||
}
|
||||
|
||||
if (request.StartsWith("https://", StringComparison.Ordinal) && Program.GlobalConfig.ForceHttp) {
|
||||
return null;
|
||||
}
|
||||
|
||||
HttpResponseMessage responseMessage;
|
||||
using (HttpRequestMessage requestMessage = new HttpRequestMessage(httpMethod, request)) {
|
||||
if (data != null && data.Count > 0) {
|
||||
if ((data != null) && (data.Count > 0)) {
|
||||
try {
|
||||
requestMessage.Content = new FormUrlEncodedContent(data);
|
||||
} catch (UriFormatException e) {
|
||||
Logging.LogGenericException(e);
|
||||
Logging.LogGenericException(e, Identifier);
|
||||
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)) {
|
||||
requestMessage.Headers.Referrer = new Uri(referer);
|
||||
}
|
||||
@@ -214,11 +418,22 @@ namespace ArchiSteamFarm {
|
||||
}
|
||||
}
|
||||
|
||||
if (responseMessage == null || !responseMessage.IsSuccessStatusCode) {
|
||||
if (responseMessage == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return responseMessage;
|
||||
if (responseMessage.IsSuccessStatusCode) {
|
||||
return responseMessage;
|
||||
}
|
||||
|
||||
if (Debugging.IsDebugBuild || Program.GlobalConfig.Debug) {
|
||||
Logging.LogGenericError("Request: " + request + " failed!", Identifier);
|
||||
Logging.LogGenericError("Status code: " + responseMessage.StatusCode, Identifier);
|
||||
Logging.LogGenericError("Content: " + Environment.NewLine + await responseMessage.Content.ReadAsStringAsync().ConfigureAwait(false), Identifier);
|
||||
}
|
||||
|
||||
responseMessage.Dispose();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
{
|
||||
"Debug": false,
|
||||
"Headless": false,
|
||||
"AutoUpdates": true,
|
||||
"AutoRestart": true,
|
||||
"UpdateChannel": 1,
|
||||
"SteamProtocol": 6,
|
||||
"SteamOwnerID": 0,
|
||||
"MaxFarmingTime": 10,
|
||||
"IdleFarmingPeriod": 3,
|
||||
"FarmingDelay": 5,
|
||||
"AccountPlayingDelay": 5,
|
||||
"LoginLimiterDelay": 7,
|
||||
"InventoryLimiterDelay": 3,
|
||||
"ForceHttp": false,
|
||||
|
||||
@@ -11,6 +11,8 @@
|
||||
"DismissInventoryNotifications": true,
|
||||
"FarmOffline": false,
|
||||
"HandleOfflineMessages": false,
|
||||
"AcceptGifts": false,
|
||||
"SteamTradeMatcher": false,
|
||||
"ForwardKeysToOtherBots": false,
|
||||
"DistributeKeys": false,
|
||||
"UseAsfAsMobileAuthenticator": false,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="HtmlAgilityPack" version="1.4.9" targetFramework="net45" />
|
||||
<package id="Newtonsoft.Json" version="8.0.3" targetFramework="net451" />
|
||||
<package id="Newtonsoft.Json" version="9.0.1-beta1" targetFramework="net451" />
|
||||
<package id="protobuf-net" version="2.0.0.668" targetFramework="net45" />
|
||||
<package id="SteamKit2" version="1.7.0" targetFramework="net452" />
|
||||
</packages>
|
||||
@@ -28,8 +28,8 @@ using System.Collections.Generic;
|
||||
using System.IO;
|
||||
|
||||
namespace ConfigGenerator {
|
||||
internal class ASFConfig {
|
||||
internal static List<ASFConfig> ASFConfigs = new List<ASFConfig>();
|
||||
internal abstract class ASFConfig {
|
||||
internal static readonly HashSet<ASFConfig> ASFConfigs = new HashSet<ASFConfig>();
|
||||
|
||||
internal string FilePath { get; set; }
|
||||
|
||||
@@ -37,12 +37,15 @@ namespace ConfigGenerator {
|
||||
ASFConfigs.Add(this);
|
||||
}
|
||||
|
||||
protected ASFConfig(string filePath) {
|
||||
protected ASFConfig(string filePath) : this() {
|
||||
if (string.IsNullOrEmpty(filePath)) {
|
||||
throw new ArgumentNullException(nameof(filePath));
|
||||
}
|
||||
|
||||
FilePath = filePath;
|
||||
ASFConfigs.Add(this);
|
||||
}
|
||||
|
||||
internal virtual void Save() {
|
||||
internal void Save() {
|
||||
lock (FilePath) {
|
||||
try {
|
||||
File.WriteAllText(FilePath, JsonConvert.SerializeObject(this, Formatting.Indented));
|
||||
@@ -52,34 +55,37 @@ namespace ConfigGenerator {
|
||||
}
|
||||
}
|
||||
|
||||
internal virtual void Remove() {
|
||||
internal void Remove() {
|
||||
string queryPath = Path.GetFileNameWithoutExtension(FilePath);
|
||||
lock (FilePath) {
|
||||
foreach (var configFile in Directory.EnumerateFiles(Program.ConfigDirectory, queryPath + ".*")) {
|
||||
foreach (string botFile in Directory.EnumerateFiles(Program.ConfigDirectory, queryPath + ".*")) {
|
||||
try {
|
||||
File.Delete(configFile);
|
||||
File.Delete(botFile);
|
||||
} catch (Exception e) {
|
||||
Logging.LogGenericException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ASFConfigs.Remove(this);
|
||||
}
|
||||
|
||||
internal virtual void Rename(string botName) {
|
||||
internal void Rename(string botName) {
|
||||
if (string.IsNullOrEmpty(botName)) {
|
||||
Logging.LogNullError(nameof(botName));
|
||||
return;
|
||||
}
|
||||
|
||||
string queryPath = Path.GetFileNameWithoutExtension(FilePath);
|
||||
lock (FilePath) {
|
||||
foreach (var file in Directory.EnumerateFiles(Program.ConfigDirectory, queryPath + ".*")) {
|
||||
foreach (string botFile in Directory.EnumerateFiles(Program.ConfigDirectory, queryPath + ".*")) {
|
||||
try {
|
||||
File.Move(file, Path.Combine(Program.ConfigDirectory, botName + Path.GetExtension(file)));
|
||||
File.Move(botFile, Path.Combine(Program.ConfigDirectory, botName + Path.GetExtension(botFile)));
|
||||
} catch (Exception e) {
|
||||
Logging.LogGenericException(e);
|
||||
}
|
||||
}
|
||||
|
||||
FilePath = Path.Combine(Program.ConfigDirectory, botName + ".json");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,9 +25,12 @@
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.IO;
|
||||
|
||||
namespace ConfigGenerator {
|
||||
[SuppressMessage("ReSharper", "AutoPropertyCanBeMadeGetOnly.Global"), SuppressMessage("ReSharper", "CollectionNeverQueried.Global"), SuppressMessage("ReSharper", "MemberCanBePrivate.Global"), SuppressMessage("ReSharper", "UnusedMember.Global")]
|
||||
internal sealed class BotConfig : ASFConfig {
|
||||
[JsonProperty(Required = Required.DisallowNull)]
|
||||
public bool Enabled { get; set; } = false;
|
||||
@@ -38,7 +41,7 @@ namespace ConfigGenerator {
|
||||
[JsonProperty]
|
||||
public string SteamLogin { get; set; } = null;
|
||||
|
||||
[JsonProperty]
|
||||
[JsonProperty, PasswordPropertyText(true)]
|
||||
public string SteamPassword { get; set; } = null;
|
||||
|
||||
[JsonProperty]
|
||||
@@ -65,6 +68,12 @@ namespace ConfigGenerator {
|
||||
[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 SteamTradeMatcher { get; set; } = false;
|
||||
|
||||
[JsonProperty(Required = Required.DisallowNull)]
|
||||
public bool ForwardKeysToOtherBots { get; set; } = false;
|
||||
|
||||
@@ -95,9 +104,9 @@ namespace ConfigGenerator {
|
||||
[JsonProperty(Required = Required.DisallowNull)]
|
||||
public List<uint> GamesPlayedWhileIdle { get; set; } = new List<uint>();
|
||||
|
||||
|
||||
internal static BotConfig Load(string filePath) {
|
||||
if (string.IsNullOrEmpty(filePath)) {
|
||||
Logging.LogNullError(nameof(filePath));
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -106,6 +115,7 @@ namespace ConfigGenerator {
|
||||
}
|
||||
|
||||
BotConfig botConfig;
|
||||
|
||||
try {
|
||||
botConfig = JsonConvert.DeserializeObject<BotConfig>(File.ReadAllText(filePath));
|
||||
} catch (Exception e) {
|
||||
@@ -113,16 +123,23 @@ namespace ConfigGenerator {
|
||||
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() : base() { }
|
||||
[SuppressMessage("ReSharper", "UnusedMember.Local")]
|
||||
private BotConfig() { }
|
||||
|
||||
private BotConfig(string filePath) : base(filePath) {
|
||||
FilePath = filePath;
|
||||
if (string.IsNullOrEmpty(filePath)) {
|
||||
throw new ArgumentNullException(nameof(filePath));
|
||||
}
|
||||
|
||||
GamesPlayedWhileIdle.Add(0);
|
||||
Save();
|
||||
}
|
||||
|
||||
@@ -38,21 +38,14 @@
|
||||
<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>
|
||||
<Reference Include="Newtonsoft.Json, Version=9.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Newtonsoft.Json.9.0.1-beta1\lib\net45\Newtonsoft.Json.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Deployment" />
|
||||
<Reference Include="System.Drawing" />
|
||||
<Reference Include="System.Net.Http" />
|
||||
<Reference Include="System.Windows.Forms" />
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="ASFConfig.cs" />
|
||||
@@ -90,6 +83,7 @@
|
||||
<Compile Include="Properties\Resources.Designer.cs">
|
||||
<AutoGen>True</AutoGen>
|
||||
<DependentUpon>Resources.resx</DependentUpon>
|
||||
<DesignTime>True</DesignTime>
|
||||
</Compile>
|
||||
<None Include="packages.config" />
|
||||
<None Include="Properties\Settings.settings">
|
||||
@@ -111,14 +105,12 @@
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<PropertyGroup>
|
||||
<PostBuildEvent Condition=" '$(OS)' != 'Unix' AND '$(ConfigurationName)' == 'Release' ">
|
||||
mkdir "$(SolutionDir)out" "$(SolutionDir)out\config"
|
||||
"$(SolutionDir)tools\ILRepack.exe" /ndebug /internalize /parallel /targetplatform:v4 /wildcards /out:"$(SolutionDir)out\ASF-GUI.exe" "$(TargetDir)$(TargetName).exe" "$(TargetDir)*.dll"
|
||||
del "$(SolutionDir)out\ASF-GUI.exe.config"
|
||||
"$(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' ">
|
||||
mkdir -p "$(SolutionDir)out" "$(SolutionDir)out/config"
|
||||
mono -O=all "$(SolutionDir)tools/ILRepack.exe" /ndebug /internalize /parallel /targetplatform:v4 /wildcards /out:"$(SolutionDir)out/ASF-GUI.exe" "$(TargetDir)$(TargetName).exe" "$(TargetDir)*.dll"
|
||||
rm "$(SolutionDir)out/ASF-GUI.exe.config"
|
||||
mono --llvm --server -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.
|
||||
|
||||
@@ -22,36 +22,27 @@
|
||||
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace ConfigGenerator {
|
||||
internal class ConfigPage : TabPage {
|
||||
|
||||
internal sealed class ConfigPage : TabPage {
|
||||
internal readonly ASFConfig ASFConfig;
|
||||
|
||||
private EnhancedPropertyGrid EnhancedPropertyGrid;
|
||||
|
||||
internal ConfigPage(ASFConfig config) : base() {
|
||||
internal ConfigPage(ASFConfig config) {
|
||||
if (config == null) {
|
||||
return;
|
||||
throw new ArgumentNullException(nameof(config));
|
||||
}
|
||||
|
||||
ASFConfig = config;
|
||||
|
||||
RefreshText();
|
||||
|
||||
EnhancedPropertyGrid = new EnhancedPropertyGrid(config);
|
||||
Controls.Add(EnhancedPropertyGrid);
|
||||
EnhancedPropertyGrid enhancedPropertyGrid = new EnhancedPropertyGrid(config);
|
||||
Controls.Add(enhancedPropertyGrid);
|
||||
}
|
||||
|
||||
internal void RefreshText() {
|
||||
Text = Path.GetFileNameWithoutExtension(ASFConfig.FilePath);
|
||||
}
|
||||
|
||||
private void InitializeComponent() {
|
||||
SuspendLayout();
|
||||
ResumeLayout(false);
|
||||
}
|
||||
internal void RefreshText() => Text = Path.GetFileNameWithoutExtension(ASFConfig.FilePath);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,17 +22,16 @@
|
||||
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
|
||||
namespace ConfigGenerator {
|
||||
internal static class Debugging {
|
||||
#if DEBUG
|
||||
[SuppressMessage("ReSharper", "ConvertToConstant.Global")]
|
||||
internal static readonly bool IsDebugBuild = true;
|
||||
#else
|
||||
[SuppressMessage("ReSharper", "ConvertToConstant.Global")]
|
||||
internal static readonly bool IsDebugBuild = false;
|
||||
#endif
|
||||
|
||||
internal static bool IsReleaseBuild => !IsDebugBuild;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,92 +25,97 @@
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using System.Windows.Forms;
|
||||
using ConfigGenerator.Properties;
|
||||
|
||||
namespace ConfigGenerator {
|
||||
class DialogBox {
|
||||
public static DialogResult InputBox(string title, string promptText, out string value) {
|
||||
internal static class DialogBox {
|
||||
internal static DialogResult InputBox(string title, string promptText, out string value) {
|
||||
if (string.IsNullOrEmpty(title) || string.IsNullOrEmpty(promptText)) {
|
||||
Logging.LogNullError(nameof(title) + " || " + nameof(promptText));
|
||||
value = null;
|
||||
return DialogResult.Abort;
|
||||
}
|
||||
|
||||
Form form = new Form();
|
||||
Label label = new Label();
|
||||
TextBox textBox = new TextBox();
|
||||
TextBox textBox = new TextBox {
|
||||
Anchor = AnchorStyles.Right,
|
||||
Bounds = new Rectangle(12, 36, 372, 20),
|
||||
Width = 1000
|
||||
};
|
||||
|
||||
textBox.Width = 1000;
|
||||
Button buttonOk = new Button();
|
||||
Button buttonCancel = new Button();
|
||||
Button buttonOk = new Button {
|
||||
Anchor = AnchorStyles.Bottom | AnchorStyles.Right,
|
||||
Bounds = new Rectangle(228, 72, 75, 23),
|
||||
DialogResult = DialogResult.OK,
|
||||
Text = Resources.OK
|
||||
};
|
||||
|
||||
form.Text = title;
|
||||
label.Text = promptText;
|
||||
Button buttonCancel = new Button {
|
||||
Anchor = AnchorStyles.Bottom | AnchorStyles.Right,
|
||||
Bounds = new Rectangle(309, 72, 75, 23),
|
||||
DialogResult = DialogResult.Cancel,
|
||||
Text = Resources.Cancel
|
||||
};
|
||||
|
||||
buttonOk.Text = "OK";
|
||||
buttonCancel.Text = "Cancel";
|
||||
buttonOk.DialogResult = DialogResult.OK;
|
||||
buttonCancel.DialogResult = DialogResult.Cancel;
|
||||
Label label = new Label {
|
||||
AutoSize = true,
|
||||
Bounds = new Rectangle(9, 20, 372, 13),
|
||||
Text = promptText
|
||||
};
|
||||
|
||||
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;
|
||||
Form form = new Form {
|
||||
AcceptButton = buttonOk,
|
||||
CancelButton = buttonCancel,
|
||||
ClientSize = new Size(Math.Max(300, label.Right + 10), 107),
|
||||
Controls = { label, textBox, buttonOk, buttonCancel },
|
||||
FormBorderStyle = FormBorderStyle.FixedDialog,
|
||||
MinimizeBox = false,
|
||||
MaximizeBox = false,
|
||||
StartPosition = FormStartPosition.CenterScreen,
|
||||
Text = title
|
||||
};
|
||||
|
||||
DialogResult dialogResult = form.ShowDialog();
|
||||
value = textBox.Text;
|
||||
return dialogResult;
|
||||
}
|
||||
|
||||
public static DialogResult YesNoBox(string title, string promptText) {
|
||||
internal static DialogResult YesNoBox(string title, string promptText) {
|
||||
if (string.IsNullOrEmpty(title) || string.IsNullOrEmpty(promptText)) {
|
||||
Logging.LogNullError(nameof(title) + " || " + nameof(promptText));
|
||||
return DialogResult.Abort;
|
||||
}
|
||||
|
||||
Form form = new Form();
|
||||
Label label = new Label();
|
||||
Button buttonYes = new Button {
|
||||
Anchor = AnchorStyles.Bottom | AnchorStyles.Right,
|
||||
Bounds = new Rectangle(228, 72, 75, 23),
|
||||
DialogResult = DialogResult.Yes,
|
||||
Text = Resources.Yes
|
||||
};
|
||||
|
||||
Button buttonOk = new Button();
|
||||
Button buttonCancel = new Button();
|
||||
Button buttonNo = new Button {
|
||||
Anchor = AnchorStyles.Bottom | AnchorStyles.Right,
|
||||
Bounds = new Rectangle(309, 72, 75, 23),
|
||||
DialogResult = DialogResult.No,
|
||||
Text = Resources.No
|
||||
};
|
||||
|
||||
form.Text = title;
|
||||
label.Text = promptText;
|
||||
Label label = new Label {
|
||||
AutoSize = true,
|
||||
Bounds = new Rectangle(9, 20, 372, 13),
|
||||
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;
|
||||
Form form = new Form {
|
||||
AcceptButton = buttonYes,
|
||||
CancelButton = buttonNo,
|
||||
ClientSize = new Size(Math.Max(300, label.Right + 10), 107),
|
||||
Controls = { label, buttonYes, buttonNo },
|
||||
FormBorderStyle = FormBorderStyle.FixedDialog,
|
||||
MinimizeBox = false,
|
||||
MaximizeBox = false,
|
||||
StartPosition = FormStartPosition.CenterScreen,
|
||||
Text = title
|
||||
};
|
||||
|
||||
DialogResult dialogResult = form.ShowDialog();
|
||||
return dialogResult;
|
||||
|
||||
@@ -22,14 +22,16 @@
|
||||
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace ConfigGenerator {
|
||||
internal sealed class EnhancedPropertyGrid : PropertyGrid {
|
||||
private ASFConfig ASFConfig;
|
||||
internal EnhancedPropertyGrid(ASFConfig config) : base() {
|
||||
private readonly ASFConfig ASFConfig;
|
||||
|
||||
internal EnhancedPropertyGrid(ASFConfig config) {
|
||||
if (config == null) {
|
||||
return;
|
||||
throw new ArgumentNullException(nameof(config));
|
||||
}
|
||||
|
||||
ASFConfig = config;
|
||||
@@ -41,32 +43,46 @@ namespace ConfigGenerator {
|
||||
ToolbarVisible = false;
|
||||
}
|
||||
|
||||
protected override void OnPropertyValueChanged(PropertyValueChangedEventArgs e) {
|
||||
if (e == null) {
|
||||
protected override void OnPropertyValueChanged(PropertyValueChangedEventArgs args) {
|
||||
if (args == null) {
|
||||
Logging.LogNullError(nameof(args));
|
||||
return;
|
||||
}
|
||||
|
||||
base.OnPropertyValueChanged(e);
|
||||
base.OnPropertyValueChanged(args);
|
||||
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);
|
||||
}
|
||||
if (!botConfig.Enabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
if (globalConfig == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (globalConfig.SteamOwnerID != 0) {
|
||||
Tutorial.OnAction(Tutorial.EPhase.GlobalConfigReady);
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnGotFocus(EventArgs args) {
|
||||
if (args == null) {
|
||||
Logging.LogNullError(nameof(args));
|
||||
return;
|
||||
}
|
||||
|
||||
base.OnGotFocus(args);
|
||||
ASFConfig.Save();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,46 +25,58 @@
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.IO;
|
||||
using System.Net.Sockets;
|
||||
|
||||
namespace ConfigGenerator {
|
||||
[SuppressMessage("ReSharper", "AutoPropertyCanBeMadeGetOnly.Global"), SuppressMessage("ReSharper", "CollectionNeverQueried.Global"), SuppressMessage("ReSharper", "MemberCanBePrivate.Global"), SuppressMessage("ReSharper", "UnusedMember.Global")]
|
||||
internal sealed class GlobalConfig : ASFConfig {
|
||||
[SuppressMessage("ReSharper", "UnusedMember.Global")]
|
||||
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 };
|
||||
private 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; } = ProtocolType.Tcp;
|
||||
public ProtocolType SteamProtocol { get; set; } = DefaultSteamProtocol;
|
||||
|
||||
[JsonProperty(Required = Required.DisallowNull)]
|
||||
public ulong SteamOwnerID { get; set; } = 0;
|
||||
|
||||
[JsonProperty(Required = Required.DisallowNull)]
|
||||
public byte MaxFarmingTime { get; set; } = 10;
|
||||
public byte MaxFarmingTime { get; set; } = DefaultMaxFarmingTime;
|
||||
|
||||
[JsonProperty(Required = Required.DisallowNull)]
|
||||
public byte IdleFarmingPeriod { get; set; } = 3;
|
||||
|
||||
[JsonProperty(Required = Required.DisallowNull)]
|
||||
public byte FarmingDelay { get; set; } = 5;
|
||||
|
||||
[JsonProperty(Required = Required.DisallowNull)]
|
||||
public byte AccountPlayingDelay { get; set; } = 5;
|
||||
public byte FarmingDelay { get; set; } = DefaultFarmingDelay;
|
||||
|
||||
[JsonProperty(Required = Required.DisallowNull)]
|
||||
public byte LoginLimiterDelay { get; set; } = 7;
|
||||
@@ -76,13 +88,13 @@ namespace ConfigGenerator {
|
||||
public bool ForceHttp { get; set; } = false;
|
||||
|
||||
[JsonProperty(Required = Required.DisallowNull)]
|
||||
public byte HttpTimeout { get; set; } = 60;
|
||||
public byte HttpTimeout { get; set; } = DefaultHttpTimeout;
|
||||
|
||||
[JsonProperty(Required = Required.DisallowNull)]
|
||||
[JsonProperty]
|
||||
public string WCFHostname { get; set; } = "localhost";
|
||||
|
||||
[JsonProperty(Required = Required.DisallowNull)]
|
||||
public ushort WCFPort { get; set; } = 1242;
|
||||
public ushort WCFPort { get; set; } = DefaultWCFPort;
|
||||
|
||||
[JsonProperty(Required = Required.DisallowNull)]
|
||||
public bool LogToFile { get; set; } = true;
|
||||
@@ -90,7 +102,6 @@ namespace ConfigGenerator {
|
||||
[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;
|
||||
|
||||
@@ -99,6 +110,7 @@ namespace ConfigGenerator {
|
||||
|
||||
internal static GlobalConfig Load(string filePath) {
|
||||
if (string.IsNullOrEmpty(filePath)) {
|
||||
Logging.LogNullError(nameof(filePath));
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -107,6 +119,7 @@ namespace ConfigGenerator {
|
||||
}
|
||||
|
||||
GlobalConfig globalConfig;
|
||||
|
||||
try {
|
||||
globalConfig = JsonConvert.DeserializeObject<GlobalConfig>(File.ReadAllText(filePath));
|
||||
} catch (Exception e) {
|
||||
@@ -114,28 +127,59 @@ namespace ConfigGenerator {
|
||||
return new GlobalConfig(filePath);
|
||||
}
|
||||
|
||||
if (globalConfig == null) {
|
||||
return new GlobalConfig(filePath);
|
||||
}
|
||||
|
||||
globalConfig.FilePath = filePath;
|
||||
|
||||
// SK2 supports only TCP and UDP steam protocols
|
||||
// Make sure that user can't screw this up
|
||||
// Ensure that user can't screw this up
|
||||
switch (globalConfig.SteamProtocol) {
|
||||
case ProtocolType.Tcp:
|
||||
case ProtocolType.Udp:
|
||||
break;
|
||||
default:
|
||||
Logging.LogGenericWarning("Configured SteamProtocol is invalid: " + globalConfig.SteamProtocol + ", default TCP protocol will be used instead");
|
||||
globalConfig.SteamProtocol = ProtocolType.Tcp;
|
||||
Logging.LogGenericWarning("Configured SteamProtocol is invalid: " + globalConfig.SteamProtocol + ". Value of " + DefaultSteamProtocol + " will be used instead");
|
||||
globalConfig.SteamProtocol = DefaultSteamProtocol;
|
||||
break;
|
||||
}
|
||||
|
||||
// User might not know what he's doing
|
||||
// Ensure that he can't screw core ASF variables
|
||||
if (globalConfig.MaxFarmingTime == 0) {
|
||||
Logging.LogGenericWarning("Configured MaxFarmingTime is invalid: " + globalConfig.MaxFarmingTime + ". Value of " + DefaultMaxFarmingTime + " will be used instead");
|
||||
globalConfig.MaxFarmingTime = DefaultMaxFarmingTime;
|
||||
}
|
||||
|
||||
if (globalConfig.FarmingDelay == 0) {
|
||||
Logging.LogGenericWarning("Configured FarmingDelay is invalid: " + globalConfig.FarmingDelay + ". Value of " + DefaultFarmingDelay + " will be used instead");
|
||||
globalConfig.FarmingDelay = DefaultFarmingDelay;
|
||||
}
|
||||
|
||||
if (globalConfig.HttpTimeout == 0) {
|
||||
Logging.LogGenericWarning("Configured HttpTimeout is invalid: " + globalConfig.HttpTimeout + ". Value of " + DefaultHttpTimeout + " will be used instead");
|
||||
globalConfig.HttpTimeout = DefaultHttpTimeout;
|
||||
}
|
||||
|
||||
if (globalConfig.WCFPort != 0) {
|
||||
return globalConfig;
|
||||
}
|
||||
|
||||
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() : base() { }
|
||||
[SuppressMessage("ReSharper", "UnusedMember.Local")]
|
||||
private GlobalConfig() { }
|
||||
|
||||
private GlobalConfig(string filePath) : base(filePath) {
|
||||
FilePath = filePath;
|
||||
if (string.IsNullOrEmpty(filePath)) {
|
||||
throw new ArgumentNullException(nameof(filePath));
|
||||
}
|
||||
|
||||
Blacklist.AddRange(GlobalBlacklist);
|
||||
Save();
|
||||
}
|
||||
|
||||
@@ -23,71 +23,78 @@
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Windows.Forms;
|
||||
using ConfigGenerator.Properties;
|
||||
|
||||
namespace ConfigGenerator {
|
||||
internal static class Logging {
|
||||
internal static void LogGenericInfo(string message) {
|
||||
internal static void LogGenericInfoWithoutStacktrace(string message) {
|
||||
if (string.IsNullOrEmpty(message)) {
|
||||
LogNullError(nameof(message));
|
||||
return;
|
||||
}
|
||||
|
||||
MessageBox.Show(message, "Information", MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||
MessageBox.Show(message, Resources.Information, MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||
}
|
||||
|
||||
internal static void LogGenericWTF(string message, [CallerMemberName] string previousMethodName = "") {
|
||||
internal static void LogGenericErrorWithoutStacktrace(string message) {
|
||||
if (string.IsNullOrEmpty(message)) {
|
||||
LogNullError(nameof(message));
|
||||
return;
|
||||
}
|
||||
|
||||
MessageBox.Show(previousMethodName + "() " + message, "WTF", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
MessageBox.Show(message, Resources.Error, MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
}
|
||||
|
||||
internal static void LogGenericError(string message, [CallerMemberName] string previousMethodName = "") {
|
||||
internal static void LogGenericException(Exception exception, [CallerMemberName] string previousMethodName = null) {
|
||||
while (true) {
|
||||
if (exception == null) {
|
||||
LogNullError(nameof(exception));
|
||||
return;
|
||||
}
|
||||
|
||||
MessageBox.Show(previousMethodName + @"() " + exception.Message + Environment.NewLine + exception.StackTrace, Resources.Exception, MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
|
||||
if (exception.InnerException != null) {
|
||||
exception = exception.InnerException;
|
||||
continue;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
internal static void LogGenericWarning(string message, [CallerMemberName] string previousMethodName = null) {
|
||||
if (string.IsNullOrEmpty(message)) {
|
||||
LogNullError(nameof(message));
|
||||
return;
|
||||
}
|
||||
|
||||
MessageBox.Show(previousMethodName + "() " + message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
MessageBox.Show(previousMethodName + @"() " + message, Resources.Warning, MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
||||
}
|
||||
|
||||
internal static void LogGenericException(Exception exception, [CallerMemberName] string previousMethodName = "") {
|
||||
if (exception == null) {
|
||||
return;
|
||||
}
|
||||
[SuppressMessage("ReSharper", "ExplicitCallerInfoArgument")]
|
||||
internal static void LogNullError(string nullObjectName, [CallerMemberName] string previousMethodName = null) {
|
||||
while (true) {
|
||||
if (string.IsNullOrEmpty(nullObjectName)) {
|
||||
nullObjectName = nameof(nullObjectName);
|
||||
continue;
|
||||
}
|
||||
|
||||
MessageBox.Show(previousMethodName + "() " + exception.Message + Environment.NewLine + exception.StackTrace, "Exception", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
|
||||
if (exception.InnerException != null) {
|
||||
LogGenericException(exception.InnerException, previousMethodName);
|
||||
LogGenericError(nullObjectName + " is null!", previousMethodName);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
internal static void LogGenericWarning(string message, [CallerMemberName] string previousMethodName = "") {
|
||||
private static void LogGenericError(string message, [CallerMemberName] string previousMethodName = null) {
|
||||
if (string.IsNullOrEmpty(message)) {
|
||||
LogNullError(nameof(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);
|
||||
LogGenericErrorWithoutStacktrace(previousMethodName + @"() " + message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
16
ConfigGenerator/MainForm.Designer.cs
generated
16
ConfigGenerator/MainForm.Designer.cs
generated
@@ -32,28 +32,30 @@
|
||||
this.MainTab.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
|
||||
| System.Windows.Forms.AnchorStyles.Left)
|
||||
| System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.MainTab.Appearance = System.Windows.Forms.TabAppearance.Buttons;
|
||||
this.MainTab.Font = new System.Drawing.Font("Segoe UI", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
|
||||
this.MainTab.HotTrack = true;
|
||||
this.MainTab.Location = new System.Drawing.Point(16, 13);
|
||||
this.MainTab.Location = new System.Drawing.Point(14, 14);
|
||||
this.MainTab.Margin = new System.Windows.Forms.Padding(4, 4, 4, 4);
|
||||
this.MainTab.Multiline = true;
|
||||
this.MainTab.Name = "MainTab";
|
||||
this.MainTab.SelectedIndex = 0;
|
||||
this.MainTab.Size = new System.Drawing.Size(748, 529);
|
||||
this.MainTab.Size = new System.Drawing.Size(854, 745);
|
||||
this.MainTab.SizeMode = System.Windows.Forms.TabSizeMode.Fixed;
|
||||
this.MainTab.TabIndex = 1;
|
||||
this.MainTab.Selected += new System.Windows.Forms.TabControlEventHandler(this.MainTab_Selected);
|
||||
this.MainTab.Deselecting += new System.Windows.Forms.TabControlCancelEventHandler(this.MainTab_Deselecting);
|
||||
//
|
||||
// MainForm
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 16F);
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 17F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.AutoScroll = true;
|
||||
this.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;
|
||||
this.ClientSize = new System.Drawing.Size(780, 557);
|
||||
this.ClientSize = new System.Drawing.Size(882, 774);
|
||||
this.Controls.Add(this.MainTab);
|
||||
this.Cursor = System.Windows.Forms.Cursors.Default;
|
||||
this.DoubleBuffered = true;
|
||||
this.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
|
||||
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.Fixed3D;
|
||||
this.Font = new System.Drawing.Font("Segoe UI", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
|
||||
this.HelpButton = true;
|
||||
this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
|
||||
this.Margin = new System.Windows.Forms.Padding(4, 4, 4, 4);
|
||||
|
||||
@@ -23,36 +23,31 @@
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace ConfigGenerator {
|
||||
public partial class MainForm : Form {
|
||||
internal sealed 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 RemoveTab = new TabPage() {
|
||||
Text = "-",
|
||||
};
|
||||
|
||||
private TabPage RenameTab = new TabPage() {
|
||||
Text = "~",
|
||||
};
|
||||
|
||||
private TabPage NewTab = new TabPage() {
|
||||
Text = "+",
|
||||
};
|
||||
|
||||
private TabPage OldTab;
|
||||
|
||||
public MainForm() {
|
||||
internal MainForm() {
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
private void MainForm_Load(object sender, EventArgs e) {
|
||||
if (sender == null || e == null) {
|
||||
private void MainForm_Load(object sender, EventArgs args) {
|
||||
if ((sender == null) || (args == null)) {
|
||||
Logging.LogNullError(nameof(sender) + " || " + nameof(args));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -60,7 +55,7 @@ namespace ConfigGenerator {
|
||||
|
||||
MainTab.TabPages.Add(ASFTab);
|
||||
|
||||
foreach (var configFile in Directory.EnumerateFiles(Program.ConfigDirectory, "*.json")) {
|
||||
foreach (string configFile in Directory.EnumerateFiles(Program.ConfigDirectory, "*.json")) {
|
||||
string botName = Path.GetFileNameWithoutExtension(configFile);
|
||||
switch (botName) {
|
||||
case Program.ASF:
|
||||
@@ -73,16 +68,17 @@ namespace ConfigGenerator {
|
||||
Tutorial.Enabled = false;
|
||||
}
|
||||
|
||||
MainTab.TabPages.AddRange(new TabPage[] { RemoveTab, RenameTab, NewTab });
|
||||
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) {
|
||||
private void MainTab_Selected(object sender, TabControlEventArgs args) {
|
||||
if ((sender == null) || (args == null)) {
|
||||
Logging.LogNullError(nameof(sender) + " || " + nameof(args));
|
||||
return;
|
||||
}
|
||||
|
||||
if (e.TabPage == RemoveTab) {
|
||||
if (args.TabPage == RemoveTab) {
|
||||
ConfigPage configPage = OldTab as ConfigPage;
|
||||
if (configPage == null) {
|
||||
MainTab.SelectedIndex = -1;
|
||||
@@ -91,7 +87,7 @@ namespace ConfigGenerator {
|
||||
|
||||
if (configPage == ASFTab) {
|
||||
MainTab.SelectedTab = ASFTab;
|
||||
Logging.LogGenericError("You can't remove global config!");
|
||||
Logging.LogGenericErrorWithoutStacktrace("You can't remove global config!");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -104,7 +100,7 @@ namespace ConfigGenerator {
|
||||
MainTab.SelectedIndex = 0;
|
||||
configPage.ASFConfig.Remove();
|
||||
MainTab.TabPages.Remove(configPage);
|
||||
} else if (e.TabPage == RenameTab) {
|
||||
} else if (args.TabPage == RenameTab) {
|
||||
ConfigPage configPage = OldTab as ConfigPage;
|
||||
if (configPage == null) {
|
||||
MainTab.SelectedIndex = -1;
|
||||
@@ -113,7 +109,7 @@ namespace ConfigGenerator {
|
||||
|
||||
if (configPage == ASFTab) {
|
||||
MainTab.SelectedTab = ASFTab;
|
||||
Logging.LogGenericError("You can't rename global config!");
|
||||
Logging.LogGenericErrorWithoutStacktrace("You can't rename global config!");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -125,13 +121,16 @@ namespace ConfigGenerator {
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(input)) {
|
||||
Logging.LogGenericError("Your bot name is empty!");
|
||||
Logging.LogGenericErrorWithoutStacktrace("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) {
|
||||
} else if (args.TabPage == NewTab) {
|
||||
ConfigPage configPage = OldTab as ConfigPage;
|
||||
if (configPage == null) {
|
||||
MainTab.SelectedIndex = -1;
|
||||
@@ -148,15 +147,16 @@ namespace ConfigGenerator {
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(input)) {
|
||||
Logging.LogGenericError("Your bot name is empty!");
|
||||
Logging.LogGenericErrorWithoutStacktrace("Your bot name is empty!");
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (ASFConfig config in ASFConfig.ASFConfigs) {
|
||||
if (Path.GetFileNameWithoutExtension(config.FilePath).Equals(input)) {
|
||||
Logging.LogGenericError("Bot with such name exists already!");
|
||||
return;
|
||||
}
|
||||
// Get rid of any potential whitespaces in bot name
|
||||
input = Regex.Replace(input, @"\s+", "");
|
||||
|
||||
if (ASFConfig.ASFConfigs.Select(config => Path.GetFileNameWithoutExtension(config.FilePath)).Any(fileNameWithoutExtension => (fileNameWithoutExtension == null) || fileNameWithoutExtension.Equals(input))) {
|
||||
Logging.LogGenericErrorWithoutStacktrace("Bot with such name exists already!");
|
||||
return;
|
||||
}
|
||||
|
||||
input = Path.Combine(Program.ConfigDirectory, input + ".json");
|
||||
@@ -165,33 +165,36 @@ namespace ConfigGenerator {
|
||||
MainTab.TabPages.Insert(MainTab.TabPages.Count - ReservedTabs, newConfigPage);
|
||||
MainTab.SelectedTab = newConfigPage;
|
||||
Tutorial.OnAction(Tutorial.EPhase.BotNicknameFinished);
|
||||
} else if (e.TabPage == ASFTab) {
|
||||
} else if (args.TabPage == ASFTab) {
|
||||
Tutorial.OnAction(Tutorial.EPhase.GlobalConfigOpened);
|
||||
}
|
||||
}
|
||||
|
||||
private void MainTab_Deselecting(object sender, TabControlCancelEventArgs e) {
|
||||
if (sender == null || e == null) {
|
||||
private void MainTab_Deselecting(object sender, TabControlCancelEventArgs args) {
|
||||
if ((sender == null) || (args == null)) {
|
||||
Logging.LogNullError(nameof(sender) + " || " + nameof(args));
|
||||
return;
|
||||
}
|
||||
|
||||
OldTab = e.TabPage;
|
||||
OldTab = args.TabPage;
|
||||
}
|
||||
|
||||
private void MainForm_Shown(object sender, EventArgs e) {
|
||||
if (sender == null || e == null) {
|
||||
private void MainForm_Shown(object sender, EventArgs args) {
|
||||
if ((sender == null) || (args == null)) {
|
||||
Logging.LogNullError(nameof(sender) + " || " + nameof(args));
|
||||
return;
|
||||
}
|
||||
|
||||
Tutorial.OnAction(Tutorial.EPhase.Shown);
|
||||
}
|
||||
|
||||
private void MainForm_HelpButtonClicked(object sender, System.ComponentModel.CancelEventArgs e) {
|
||||
if (sender == null || e == null) {
|
||||
private void MainForm_HelpButtonClicked(object sender, CancelEventArgs args) {
|
||||
if ((sender == null) || (args == null)) {
|
||||
Logging.LogNullError(nameof(sender) + " || " + nameof(args));
|
||||
return;
|
||||
}
|
||||
|
||||
e.Cancel = true;
|
||||
args.Cancel = true;
|
||||
Tutorial.OnAction(Tutorial.EPhase.Help);
|
||||
Process.Start("https://github.com/JustArchi/ArchiSteamFarm/wiki/Configuration");
|
||||
Tutorial.OnAction(Tutorial.EPhase.HelpFinished);
|
||||
|
||||
@@ -36,10 +36,7 @@ namespace ConfigGenerator {
|
||||
|
||||
private const string ASFDirectory = "ArchiSteamFarm";
|
||||
|
||||
private static readonly Assembly Assembly = Assembly.GetExecutingAssembly();
|
||||
private static readonly string ExecutableFile = Assembly.Location;
|
||||
private static readonly string ExecutableName = Path.GetFileName(ExecutableFile);
|
||||
private static readonly string ExecutableDirectory = Path.GetDirectoryName(ExecutableFile);
|
||||
private static readonly string ExecutableDirectory = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);
|
||||
|
||||
/// <summary>
|
||||
/// The main entry point for the application.
|
||||
@@ -64,10 +61,12 @@ namespace ConfigGenerator {
|
||||
// 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 (!Directory.Exists(ASFDirectory)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Directory.SetCurrentDirectory(ASFDirectory);
|
||||
break;
|
||||
}
|
||||
|
||||
// If config directory doesn't exist after our adjustment, abort all of that
|
||||
@@ -76,14 +75,17 @@ namespace ConfigGenerator {
|
||||
}
|
||||
}
|
||||
|
||||
if (!Directory.Exists(ConfigDirectory)) {
|
||||
Logging.LogGenericError("Config directory could not be found!");
|
||||
Environment.Exit(1);
|
||||
if (Directory.Exists(ConfigDirectory)) {
|
||||
return;
|
||||
}
|
||||
|
||||
Logging.LogGenericErrorWithoutStacktrace("Config directory could not be found!");
|
||||
Environment.Exit(1);
|
||||
}
|
||||
|
||||
private static void UnhandledExceptionHandler(object sender, UnhandledExceptionEventArgs args) {
|
||||
if (sender == null || args == null) {
|
||||
if ((sender == null) || (args == null) || (args.ExceptionObject == null)) {
|
||||
Logging.LogNullError(nameof(sender) + " || " + nameof(args) + " || " + nameof(args.ExceptionObject));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -91,7 +93,8 @@ namespace ConfigGenerator {
|
||||
}
|
||||
|
||||
private static void UnobservedTaskExceptionHandler(object sender, UnobservedTaskExceptionEventArgs args) {
|
||||
if (sender == null || args == null) {
|
||||
if ((sender == null) || (args == null) || (args.Exception == null)) {
|
||||
Logging.LogNullError(nameof(sender) + " || " + nameof(args) + " || " + nameof(args.Exception));
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// 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")]
|
||||
@@ -10,12 +9,12 @@ using System.Runtime.InteropServices;
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("ConfigGenerator")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2016")]
|
||||
[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
|
||||
// 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)]
|
||||
|
||||
@@ -25,11 +24,11 @@ using System.Runtime.InteropServices;
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// 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:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
|
||||
173
ConfigGenerator/Properties/Resources.Designer.cs
generated
173
ConfigGenerator/Properties/Resources.Designer.cs
generated
@@ -9,54 +9,127 @@
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
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("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;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Cancel.
|
||||
/// </summary>
|
||||
internal static string Cancel {
|
||||
get {
|
||||
return ResourceManager.GetString("Cancel", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Error.
|
||||
/// </summary>
|
||||
internal static string Error {
|
||||
get {
|
||||
return ResourceManager.GetString("Error", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Exception.
|
||||
/// </summary>
|
||||
internal static string Exception {
|
||||
get {
|
||||
return ResourceManager.GetString("Exception", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Information.
|
||||
/// </summary>
|
||||
internal static string Information {
|
||||
get {
|
||||
return ResourceManager.GetString("Information", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to No.
|
||||
/// </summary>
|
||||
internal static string No {
|
||||
get {
|
||||
return ResourceManager.GetString("No", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to OK.
|
||||
/// </summary>
|
||||
internal static string OK {
|
||||
get {
|
||||
return ResourceManager.GetString("OK", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Warning.
|
||||
/// </summary>
|
||||
internal static string Warning {
|
||||
get {
|
||||
return ResourceManager.GetString("Warning", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Yes.
|
||||
/// </summary>
|
||||
internal static string Yes {
|
||||
get {
|
||||
return ResourceManager.GetString("Yes", resourceCulture);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -114,4 +114,28 @@
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<data name="Information" xml:space="preserve">
|
||||
<value>Information</value>
|
||||
</data>
|
||||
<data name="Error" xml:space="preserve">
|
||||
<value>Error</value>
|
||||
</data>
|
||||
<data name="Exception" xml:space="preserve">
|
||||
<value>Exception</value>
|
||||
</data>
|
||||
<data name="Warning" xml:space="preserve">
|
||||
<value>Warning</value>
|
||||
</data>
|
||||
<data name="OK" xml:space="preserve">
|
||||
<value>OK</value>
|
||||
</data>
|
||||
<data name="Cancel" xml:space="preserve">
|
||||
<value>Cancel</value>
|
||||
</data>
|
||||
<data name="Yes" xml:space="preserve">
|
||||
<value>Yes</value>
|
||||
</data>
|
||||
<data name="No" xml:space="preserve">
|
||||
<value>No</value>
|
||||
</data>
|
||||
</root>
|
||||
@@ -35,15 +35,15 @@ namespace ConfigGenerator {
|
||||
BotEnabled,
|
||||
BotReady,
|
||||
GlobalConfigOpened,
|
||||
GlobalConfigReady,
|
||||
GlobalConfigReady
|
||||
}
|
||||
|
||||
internal static bool Enabled { get; set; } = true;
|
||||
internal static bool Enabled { private get; set; } = true;
|
||||
|
||||
private static EPhase NextPhase = EPhase.Start;
|
||||
|
||||
internal static void OnAction(EPhase phase) {
|
||||
if (!Enabled || phase != NextPhase) {
|
||||
if (!Enabled || (phase != NextPhase)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -51,42 +51,42 @@ namespace ConfigGenerator {
|
||||
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.");
|
||||
Logging.LogGenericInfoWithoutStacktrace("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.");
|
||||
Logging.LogGenericInfoWithoutStacktrace("You can now notice the main ASF Config Generator screen, it's really easy to use!");
|
||||
Logging.LogGenericInfoWithoutStacktrace("At the top of the window you can notice currently loaded configs, and 3 extra buttons for removing, renaming and adding new ones.");
|
||||
Logging.LogGenericInfoWithoutStacktrace("In the middle of the window you will be able to configure all config properties that are available for you.");
|
||||
Logging.LogGenericInfoWithoutStacktrace("In the top right corner you can find help button [?] which will redirect you to ASF wiki where you can find more information.");
|
||||
Logging.LogGenericInfoWithoutStacktrace("Please click the help button to continue.");
|
||||
break;
|
||||
case EPhase.Help:
|
||||
Logging.LogGenericInfo("That's right! On ASF wiki you can find detailed help about every config property you're going to configure in a moment.");
|
||||
Logging.LogGenericInfoWithoutStacktrace("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!");
|
||||
Logging.LogGenericInfoWithoutStacktrace("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("That's right! 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.");
|
||||
Logging.LogGenericInfoWithoutStacktrace("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!");
|
||||
Logging.LogGenericInfoWithoutStacktrace("As you can see your bot config is now ready to configure!");
|
||||
Logging.LogGenericInfoWithoutStacktrace("First thing that you want to do is switching \"Enabled\" property from False to True, try it!");
|
||||
break;
|
||||
case EPhase.BotEnabled:
|
||||
Logging.LogGenericInfo("That's right! 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!");
|
||||
Logging.LogGenericInfoWithoutStacktrace("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.");
|
||||
Logging.LogGenericInfoWithoutStacktrace("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!");
|
||||
Logging.LogGenericInfoWithoutStacktrace("While bot config affects only given bot instance you're configuring, global config affects whole ASF process, including all configured bots.");
|
||||
Logging.LogGenericInfoWithoutStacktrace("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 with 2 other buttons. Good luck!");
|
||||
Logging.LogGenericInfoWithoutStacktrace("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.LogGenericInfoWithoutStacktrace("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.LogGenericInfoWithoutStacktrace("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;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="Newtonsoft.Json" version="8.0.3" targetFramework="net451" />
|
||||
<package id="Newtonsoft.Json" version="9.0.1-beta1" 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>
|
||||
35
GUI/Debugging.cs
Normal file
35
GUI/Debugging.cs
Normal file
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
_ _ _ ____ _ _____
|
||||
/ \ _ __ ___ | |__ (_)/ ___| | |_ ___ __ _ _ __ ___ | ___|__ _ _ __ _ __ ___
|
||||
/ _ \ | '__|/ __|| '_ \ | |\___ \ | __|/ _ \ / _` || '_ ` _ \ | |_ / _` || '__|| '_ ` _ \
|
||||
/ ___ \ | | | (__ | | | || | ___) || |_| __/| (_| || | | | | || _|| (_| || | | | | | | |
|
||||
/_/ \_\|_| \___||_| |_||_||____/ \__|\___| \__,_||_| |_| |_||_| \__,_||_| |_| |_| |_|
|
||||
|
||||
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 GUI {
|
||||
internal static class Debugging {
|
||||
#if DEBUG
|
||||
internal static readonly bool IsDebugBuild = true;
|
||||
#else
|
||||
internal static readonly bool IsDebugBuild = false;
|
||||
#endif
|
||||
|
||||
internal static bool IsReleaseBuild => !IsDebugBuild;
|
||||
}
|
||||
}
|
||||
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
146
GUI/GUI.csproj
Normal file
146
GUI/GUI.csproj
Normal file
@@ -0,0 +1,146 @@
|
||||
<?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>
|
||||
</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 |
66
README.md
66
README.md
@@ -1,48 +1,50 @@
|
||||
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_)
|
||||
|
||||
---
|
||||
|
||||
ASF is a C# application that allows you to farm steam cards using multiple steam accounts simultaneously. Unlike idle master which works only on one account at given time, requires steam client running in background, and launches additional processes imitiating "game playing" status, ASF doesn't require any steam client running in the background, doesn't launch any additional processes and is made to handle unlimited steam accounts at once. In addition to that, it's meant to be run on servers or other desktop-less machines, and features full Mono support, which makes it possible to launch on any Mono-supported operating system, such as Windows, Linux or OS X. ASF is based on, and possible, thanks to [SteamKit2](https://github.com/SteamRE/SteamKit).
|
||||
ASF is a C# application that allows you to farm steam cards using multiple steam accounts simultaneously. Unlike Idle Master which works only for one account at given time, requires steam client running in background, and launches additional processes imitiating "game playing" status, ASF doesn't require any steam client running in the background, doesn't launch any additional processes and is made to handle unlimited steam accounts at once. In addition to that, it's meant to be run on servers or other desktop-less machines, and features full Mono support, which makes it possible to launch on any Mono-supported operating system, such as Windows, Linux or OS X. ASF is based on, and possible, thanks to [SteamKit2](https://github.com/SteamRE/SteamKit).
|
||||
|
||||
ASF doesn't require and doesn't interfere in any way with Steam client. In addition to that, it no longer requires exclusive access to given account, which means that you can use your main account in Steam client, and use ASF for farming the same account at the same time. If you decide to launch a game, ASF will get disconnected, and resume farming once you finish playing your game, being as transparent as possible.
|
||||
|
||||
**Core features:**
|
||||
**Core features**
|
||||
|
||||
- Automatically farm available games using any number of active accounts
|
||||
- Automatically accept friend requests sent from master
|
||||
- Automatically accept all trades coming from master
|
||||
- Automatically accept all steam cd-keys sent via chat from master
|
||||
- Possibility to choose the most efficient cards farming algorithm, based on given account
|
||||
- SteamGuard / SteamParental / 2FA support
|
||||
- Unique ASF 2FA mechanism allowing ASF to act as mobile authenticator (if needed)
|
||||
- ASF update notifications
|
||||
- Full Mono support, cross-OS compatibility
|
||||
- Automatic farming of available games with card drops using any number of active accounts
|
||||
- No requirement of running or even having official Steam client installed
|
||||
- Guarantee of being VAC-free
|
||||
- Complex error-reporting mechanism, allowing ASF to be smart and resume farming even in case of Steam or networking problems
|
||||
- Customizable cards farming algorithm which will push performance of cards farming to the maximum
|
||||
- Offline farming, allowing you to skip in-game status and not confuse your friends anymore
|
||||
- Advanced support for alt accounts, including ability to redeem keys, redeem gifts, accept trades and more through a simple Steam chat
|
||||
- Support for latest Steam security features, including SteamGuard, SteamParental and Two-Factor authentication
|
||||
- Unique ASF 2FA mechanism allowing ASF to act as a mobile authenticator (if needed)
|
||||
- StreamTradeMatcher integration allowing ASF to help you in completing your steam badges by accepting dupe trades
|
||||
- Full Mono support, cross-OS compatibility, official support for Windows, Linux and OS X
|
||||
- ...and many more!
|
||||
|
||||
**Setting up:**
|
||||
**Setting up / Help**
|
||||
|
||||
Detailed setting up instructions are available on **[our wiki](https://github.com/JustArchi/ArchiSteamFarm/wiki/Setting-up)**.
|
||||
Detailed guide regarding setting up and using ASF is available on **[our wiki](https://github.com/JustArchi/ArchiSteamFarm/wiki)**.
|
||||
|
||||
**Current Commands:**
|
||||
**Supported / Tested operating systems:**
|
||||
|
||||
Detailed documentation of all available commands is available on **[our wiki](https://github.com/JustArchi/ArchiSteamFarm/wiki/Commands)**.
|
||||
ASF officially supports Windows, Linux and OS X operating systems, including following tested variants:
|
||||
|
||||
> Commands can be executed via a private chat with your bot.
|
||||
> Remember that bot accepts commands only from ```SteamMasterID```. That property can be configured in the config.
|
||||
|
||||
**Supported / Tested Operating-Systems:**
|
||||
|
||||
- Windows 10 Professional/Enterprise Edition (Native)
|
||||
- Windows 8.1 Professional (Native)
|
||||
- Windows 7 Ultimate (Native)
|
||||
- Debian 9.0 Stretch (Mono)
|
||||
- Debian 8.1 Jessie (Mono)
|
||||
- OS X 10.11.1 (Mono)
|
||||
- Windows 10 (Native)
|
||||
- Windows 8.1 (Native)
|
||||
- Windows 7 (Native)
|
||||
- Windows Vista (Native)
|
||||
- Debian 9 Stretch (Mono)
|
||||
- Debian 8 Jessie (Mono)
|
||||
- Ubuntu 16.04 (Mono)
|
||||
- OS X 10.11 (Mono)
|
||||
- OS X 10.7 (Mono)
|
||||
|
||||
However, any operating system [listed here](http://www.mono-project.com/docs/about-mono/supported-platforms/) should run ASF flawlessly.
|
||||
|
||||
**Need help or more info?**
|
||||
|
||||
Head over to our [wiki](https://github.com/JustArchi/ArchiSteamFarm/wiki) then.
|
||||
However, any **[currently supported Windows](http://windows.microsoft.com/en-us/windows/lifecycle)** should run ASF flawlessly (with latest .NET framework), as well as any **[Mono-powered OS](http://www.mono-project.com/docs/about-mono/supported-platforms/)** (with latest Mono).
|
||||
|
||||
@@ -32,8 +32,8 @@
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</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>
|
||||
<Reference Include="Newtonsoft.Json, Version=9.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Newtonsoft.Json.9.0.1-beta1\lib\net45\Newtonsoft.Json.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="Newtonsoft.Json" version="8.0.3" targetFramework="net451" />
|
||||
<package id="Newtonsoft.Json" version="9.0.1-beta1" targetFramework="net451" />
|
||||
</packages>
|
||||
9
appveyor.yml
Normal file
9
appveyor.yml
Normal file
@@ -0,0 +1,9 @@
|
||||
version: 1.0.{build}-{branch}
|
||||
image: Visual Studio 2015
|
||||
configuration: Release
|
||||
platform: Any CPU
|
||||
clone_depth: 10
|
||||
build:
|
||||
project: ArchiSteamFarm.sln
|
||||
parallel: true
|
||||
verbosity: minimal
|
||||
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.
Binary file not shown.
Binary file not shown.
@@ -81,7 +81,7 @@
|
||||
Reads the next JSON token from the stream.
|
||||
</summary>
|
||||
<returns>
|
||||
true if the next token was read successfully; false if there are no more tokens to read.
|
||||
<c>true</c> if the next token was read successfully; <c>false</c> if there are no more tokens to read.
|
||||
</returns>
|
||||
</member>
|
||||
<member name="M:Newtonsoft.Json.Bson.BsonReader.Close">
|
||||
@@ -320,12 +320,12 @@
|
||||
</member>
|
||||
<member name="F:Newtonsoft.Json.ConstructorHandling.Default">
|
||||
<summary>
|
||||
First attempt to use the public default constructor, then fall back to single paramatized constructor, then the non-public default constructor.
|
||||
First attempt to use the public default constructor, then fall back to single parameterized constructor, then the non-public default constructor.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="F:Newtonsoft.Json.ConstructorHandling.AllowNonPublicDefaultConstructor">
|
||||
<summary>
|
||||
Json.NET will use a non-public default constructor before falling back to a paramatized constructor.
|
||||
Json.NET will use a non-public default constructor before falling back to a parameterized constructor.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:Newtonsoft.Json.Converters.BinaryConverter">
|
||||
@@ -781,7 +781,7 @@
|
||||
</summary>
|
||||
<param name="attributeName">Attribute name to test.</param>
|
||||
<param name="prefix">The attribute name prefix if it has one, otherwise an empty string.</param>
|
||||
<returns>True if attribute name is for a namespace attribute, otherwise false.</returns>
|
||||
<returns><c>true</c> if attribute name is for a namespace attribute, otherwise <c>false</c>.</returns>
|
||||
</member>
|
||||
<member name="M:Newtonsoft.Json.Converters.XmlNodeConverter.CanConvert(System.Type)">
|
||||
<summary>
|
||||
@@ -1118,10 +1118,9 @@
|
||||
When overridden in a derived class, returns whether resetting an object changes its value.
|
||||
</summary>
|
||||
<returns>
|
||||
true if resetting the component changes its value; otherwise, false.
|
||||
<c>true</c> if resetting the component changes its value; otherwise, <c>false</c>.
|
||||
</returns>
|
||||
<param name="component">The component to test for reset capability.
|
||||
</param>
|
||||
<param name="component">The component to test for reset capability.</param>
|
||||
</member>
|
||||
<member name="M:Newtonsoft.Json.Linq.JPropertyDescriptor.GetValue(System.Object)">
|
||||
<summary>
|
||||
@@ -1153,10 +1152,9 @@
|
||||
When overridden in a derived class, determines a value indicating whether the value of this property needs to be persisted.
|
||||
</summary>
|
||||
<returns>
|
||||
true if the property should be persisted; otherwise, false.
|
||||
<c>true</c> if the property should be persisted; otherwise, <c>false</c>.
|
||||
</returns>
|
||||
<param name="component">The component with the property to be examined for persistence.
|
||||
</param>
|
||||
<param name="component">The component with the property to be examined for persistence.</param>
|
||||
</member>
|
||||
<member name="P:Newtonsoft.Json.Linq.JPropertyDescriptor.ComponentType">
|
||||
<summary>
|
||||
@@ -1171,7 +1169,7 @@
|
||||
When overridden in a derived class, gets a value indicating whether this property is read-only.
|
||||
</summary>
|
||||
<returns>
|
||||
true if the property is read-only; otherwise, false.
|
||||
<c>true</c> if the property is read-only; otherwise, <c>false</c>.
|
||||
</returns>
|
||||
</member>
|
||||
<member name="P:Newtonsoft.Json.Linq.JPropertyDescriptor.PropertyType">
|
||||
@@ -1239,7 +1237,7 @@
|
||||
<param name="x">The first object of type <see cref="T:Newtonsoft.Json.Linq.JToken"/> to compare.</param>
|
||||
<param name="y">The second object of type <see cref="T:Newtonsoft.Json.Linq.JToken"/> to compare.</param>
|
||||
<returns>
|
||||
true if the specified objects are equal; otherwise, false.
|
||||
<c>true</c> if the specified objects are equal; otherwise, <c>false</c>.
|
||||
</returns>
|
||||
</member>
|
||||
<member name="M:Newtonsoft.Json.Linq.JTokenEqualityComparer.GetHashCode(Newtonsoft.Json.Linq.JToken)">
|
||||
@@ -1822,7 +1820,7 @@
|
||||
<param name="propertyName">Name of the property.</param>
|
||||
<param name="value">The value.</param>
|
||||
<param name="comparison">One of the enumeration values that specifies how the strings will be compared.</param>
|
||||
<returns>true if a value was successfully retrieved; otherwise, false.</returns>
|
||||
<returns><c>true</c> if a value was successfully retrieved; otherwise, <c>false</c>.</returns>
|
||||
</member>
|
||||
<member name="M:Newtonsoft.Json.Linq.JObject.Add(System.String,Newtonsoft.Json.Linq.JToken)">
|
||||
<summary>
|
||||
@@ -1836,7 +1834,7 @@
|
||||
Removes the property with the specified name.
|
||||
</summary>
|
||||
<param name="propertyName">Name of the property.</param>
|
||||
<returns>true if item was successfully removed; otherwise, false.</returns>
|
||||
<returns><c>true</c> if item was successfully removed; otherwise, <c>false</c>.</returns>
|
||||
</member>
|
||||
<member name="M:Newtonsoft.Json.Linq.JObject.TryGetValue(System.String,Newtonsoft.Json.Linq.JToken@)">
|
||||
<summary>
|
||||
@@ -1844,7 +1842,7 @@
|
||||
</summary>
|
||||
<param name="propertyName">Name of the property.</param>
|
||||
<param name="value">The value.</param>
|
||||
<returns>true if a value was successfully retrieved; otherwise, false.</returns>
|
||||
<returns><c>true</c> if a value was successfully retrieved; otherwise, <c>false</c>.</returns>
|
||||
</member>
|
||||
<member name="M:Newtonsoft.Json.Linq.JObject.GetEnumerator">
|
||||
<summary>
|
||||
@@ -2177,7 +2175,7 @@
|
||||
Reads the next JSON token from the stream.
|
||||
</summary>
|
||||
<returns>
|
||||
true if the next token was read successfully; false if there are no more tokens to read.
|
||||
<c>true</c> if the next token was read successfully; <c>false</c> if there are no more tokens to read.
|
||||
</returns>
|
||||
</member>
|
||||
<member name="P:Newtonsoft.Json.Linq.JTokenReader.Path">
|
||||
@@ -2436,7 +2434,7 @@
|
||||
</summary>
|
||||
<param name="t1">The first <see cref="T:Newtonsoft.Json.Linq.JToken"/> to compare.</param>
|
||||
<param name="t2">The second <see cref="T:Newtonsoft.Json.Linq.JToken"/> to compare.</param>
|
||||
<returns>true if the tokens are equal; otherwise false.</returns>
|
||||
<returns><c>true</c> if the tokens are equal; otherwise <c>false</c>.</returns>
|
||||
</member>
|
||||
<member name="P:Newtonsoft.Json.Linq.JToken.Next">
|
||||
<summary>
|
||||
@@ -3566,7 +3564,7 @@
|
||||
Indicates whether the current object is equal to another object of the same type.
|
||||
</summary>
|
||||
<returns>
|
||||
true if the current object is equal to the <paramref name="other"/> parameter; otherwise, false.
|
||||
<c>true</c> if the current object is equal to the <paramref name="other"/> parameter; otherwise, <c>false</c>.
|
||||
</returns>
|
||||
<param name="other">An object to compare with this object.</param>
|
||||
</member>
|
||||
@@ -3576,7 +3574,7 @@
|
||||
</summary>
|
||||
<param name="obj">The <see cref="T:System.Object"/> to compare with the current <see cref="T:System.Object"/>.</param>
|
||||
<returns>
|
||||
true if the specified <see cref="T:System.Object"/> is equal to the current <see cref="T:System.Object"/>; otherwise, false.
|
||||
<c>true</c> if the specified <see cref="T:System.Object"/> is equal to the current <see cref="T:System.Object"/>; otherwise, <c>false</c>.
|
||||
</returns>
|
||||
<exception cref="T:System.NullReferenceException">
|
||||
The <paramref name="obj"/> parameter is null.
|
||||
@@ -3666,6 +3664,47 @@
|
||||
Do not try to read metadata properties.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:Newtonsoft.Json.Serialization.CamelCaseNamingStrategy">
|
||||
<summary>
|
||||
A camel case naming strategy.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:Newtonsoft.Json.Serialization.CamelCaseNamingStrategy.#ctor(System.Boolean,System.Boolean)">
|
||||
<summary>
|
||||
Initializes a new instance of the <see cref="T:Newtonsoft.Json.Serialization.CamelCaseNamingStrategy"/> class.
|
||||
</summary>
|
||||
<param name="processDictionaryKeys">
|
||||
A flag indicating whether dictionary keys should be processed.
|
||||
</param>
|
||||
<param name="overrideSpecifiedNames">
|
||||
A flag indicating whether explicitly specified property names should be processed,
|
||||
e.g. a property name customized with a <see cref="T:Newtonsoft.Json.JsonPropertyAttribute"/>.
|
||||
</param>
|
||||
</member>
|
||||
<member name="M:Newtonsoft.Json.Serialization.CamelCaseNamingStrategy.#ctor">
|
||||
<summary>
|
||||
Initializes a new instance of the <see cref="T:Newtonsoft.Json.Serialization.CamelCaseNamingStrategy"/> class.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:Newtonsoft.Json.Serialization.CamelCaseNamingStrategy.ResolvePropertyName(System.String)">
|
||||
<summary>
|
||||
Resolves the specified property name.
|
||||
</summary>
|
||||
<param name="name">The property name to resolve.</param>
|
||||
<returns>The resolved property name.</returns>
|
||||
</member>
|
||||
<member name="T:Newtonsoft.Json.Serialization.DefaultNamingStrategy">
|
||||
<summary>
|
||||
The default naming strategy. Property names and dictionary keys are unchanged.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:Newtonsoft.Json.Serialization.DefaultNamingStrategy.ResolvePropertyName(System.String)">
|
||||
<summary>
|
||||
Resolves the specified property name.
|
||||
</summary>
|
||||
<param name="name">The property name to resolve.</param>
|
||||
<returns>The resolved property name.</returns>
|
||||
</member>
|
||||
<member name="T:Newtonsoft.Json.Serialization.DiagnosticsTraceWriter">
|
||||
<summary>
|
||||
Represents a trace writer that writes to the application's <see cref="T:System.Diagnostics.TraceListener"/> instances.
|
||||
@@ -3808,6 +3847,46 @@
|
||||
A <see cref="T:System.String"/> of the most recent trace messages.
|
||||
</returns>
|
||||
</member>
|
||||
<member name="T:Newtonsoft.Json.Serialization.NamingStrategy">
|
||||
<summary>
|
||||
A base class for resolving how property names and dictionary keys are serialized.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:Newtonsoft.Json.Serialization.NamingStrategy.ProcessDictionaryKeys">
|
||||
<summary>
|
||||
A flag indicating whether dictionary keys should be processed.
|
||||
Defaults to <c>false</c>.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:Newtonsoft.Json.Serialization.NamingStrategy.OverrideSpecifiedNames">
|
||||
<summary>
|
||||
A flag indicating whether explicitly specified property names,
|
||||
e.g. a property name customized with a <see cref="T:Newtonsoft.Json.JsonPropertyAttribute"/>, should be processed.
|
||||
Defaults to <c>false</c>.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:Newtonsoft.Json.Serialization.NamingStrategy.GetPropertyName(System.String,System.Boolean)">
|
||||
<summary>
|
||||
Gets the serialized name for a given property name.
|
||||
</summary>
|
||||
<param name="name">The initial property name.</param>
|
||||
<param name="hasSpecifiedName">A flag indicating whether the property has had a name explicitly specfied.</param>
|
||||
<returns>The serialized property name.</returns>
|
||||
</member>
|
||||
<member name="M:Newtonsoft.Json.Serialization.NamingStrategy.GetDictionaryKey(System.String)">
|
||||
<summary>
|
||||
Gets the serialized key for a given dictionary key.
|
||||
</summary>
|
||||
<param name="key">The initial dictionary key.</param>
|
||||
<returns>The serialized dictionary key.</returns>
|
||||
</member>
|
||||
<member name="M:Newtonsoft.Json.Serialization.NamingStrategy.ResolvePropertyName(System.String)">
|
||||
<summary>
|
||||
Resolves the specified property name.
|
||||
</summary>
|
||||
<param name="name">The property name to resolve.</param>
|
||||
<returns>The resolved property name.</returns>
|
||||
</member>
|
||||
<member name="T:Newtonsoft.Json.Serialization.ReflectionAttributeProvider">
|
||||
<summary>
|
||||
Provides methods to get attributes from a <see cref="T:System.Type"/>, <see cref="T:System.Reflection.MemberInfo"/>, <see cref="T:System.Reflection.ParameterInfo"/> or <see cref="T:System.Reflection.Assembly"/>.
|
||||
@@ -3834,6 +3913,35 @@
|
||||
<param name="inherit">When true, look up the hierarchy chain for the inherited custom attribute.</param>
|
||||
<returns>A collection of <see cref="T:System.Attribute"/>s, or an empty collection.</returns>
|
||||
</member>
|
||||
<member name="T:Newtonsoft.Json.Serialization.SnakeCaseNamingStrategy">
|
||||
<summary>
|
||||
A snake case naming strategy.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:Newtonsoft.Json.Serialization.SnakeCaseNamingStrategy.#ctor(System.Boolean,System.Boolean)">
|
||||
<summary>
|
||||
Initializes a new instance of the <see cref="T:Newtonsoft.Json.Serialization.SnakeCaseNamingStrategy"/> class.
|
||||
</summary>
|
||||
<param name="processDictionaryKeys">
|
||||
A flag indicating whether dictionary keys should be processed.
|
||||
</param>
|
||||
<param name="overrideSpecifiedNames">
|
||||
A flag indicating whether explicitly specified property names should be processed,
|
||||
e.g. a property name customized with a <see cref="T:Newtonsoft.Json.JsonPropertyAttribute"/>.
|
||||
</param>
|
||||
</member>
|
||||
<member name="M:Newtonsoft.Json.Serialization.SnakeCaseNamingStrategy.#ctor">
|
||||
<summary>
|
||||
Initializes a new instance of the <see cref="T:Newtonsoft.Json.Serialization.SnakeCaseNamingStrategy"/> class.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:Newtonsoft.Json.Serialization.SnakeCaseNamingStrategy.ResolvePropertyName(System.String)">
|
||||
<summary>
|
||||
Resolves the specified property name.
|
||||
</summary>
|
||||
<param name="name">The property name to resolve.</param>
|
||||
<returns>The resolved property name.</returns>
|
||||
</member>
|
||||
<member name="T:Newtonsoft.Json.Serialization.CamelCasePropertyNamesContractResolver">
|
||||
<summary>
|
||||
Resolves member mappings for a type, camel casing property names.
|
||||
@@ -3844,13 +3952,6 @@
|
||||
Initializes a new instance of the <see cref="T:Newtonsoft.Json.Serialization.CamelCasePropertyNamesContractResolver"/> class.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:Newtonsoft.Json.Serialization.CamelCasePropertyNamesContractResolver.ResolvePropertyName(System.String)">
|
||||
<summary>
|
||||
Resolves the name of the property.
|
||||
</summary>
|
||||
<param name="propertyName">Name of the property.</param>
|
||||
<returns>The property name camel cased.</returns>
|
||||
</member>
|
||||
<member name="T:Newtonsoft.Json.Serialization.DefaultContractResolver">
|
||||
<summary>
|
||||
Used by <see cref="T:Newtonsoft.Json.JsonSerializer"/> to resolves a <see cref="T:Newtonsoft.Json.Serialization.JsonContract"/> for a given <see cref="T:System.Type"/>.
|
||||
@@ -3895,6 +3996,12 @@
|
||||
<c>true</c> if the <see cref="T:System.SerializableAttribute"/> attribute will be ignored when serializing and deserializing types; otherwise, <c>false</c>.
|
||||
</value>
|
||||
</member>
|
||||
<member name="P:Newtonsoft.Json.Serialization.DefaultContractResolver.NamingStrategy">
|
||||
<summary>
|
||||
Gets or sets the naming strategy used to resolve how property names and dictionary keys are serialized.
|
||||
</summary>
|
||||
<value>The naming strategy used to resolve how property names and dictionary keys are serialized.</value>
|
||||
</member>
|
||||
<member name="M:Newtonsoft.Json.Serialization.DefaultContractResolver.#ctor">
|
||||
<summary>
|
||||
Initializes a new instance of the <see cref="T:Newtonsoft.Json.Serialization.DefaultContractResolver"/> class.
|
||||
@@ -4799,13 +4906,6 @@
|
||||
<param name="converterArgs">Optional arguments to pass to an initializing constructor of the JsonConverter.
|
||||
If null, the default constructor is used.</param>
|
||||
</member>
|
||||
<member name="M:Newtonsoft.Json.Serialization.JsonTypeReflector.GetJsonConverterCreator(System.Type)">
|
||||
<summary>
|
||||
Create a factory function that can be used to create instances of a JsonConverter described by the
|
||||
argument type. The returned function can then be used to either invoke the converter's default ctor, or any
|
||||
parameterized constructors by way of an object array.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:Newtonsoft.Json.Serialization.ObjectConstructor`1">
|
||||
<summary>
|
||||
Represents a method that constructs an object.
|
||||
@@ -5967,16 +6067,6 @@
|
||||
<param name="initial">The list to add to.</param>
|
||||
<param name="collection">The collection of elements to add.</param>
|
||||
</member>
|
||||
<member name="M:Newtonsoft.Json.Utilities.CollectionUtils.IndexOf``1(System.Collections.Generic.IEnumerable{``0},``0,System.Collections.Generic.IEqualityComparer{``0})">
|
||||
<summary>
|
||||
Returns the index of the first occurrence in a sequence by using a specified IEqualityComparer{TSource}.
|
||||
</summary>
|
||||
<typeparam name="TSource">The type of the elements of source.</typeparam>
|
||||
<param name="list">A sequence in which to locate a value.</param>
|
||||
<param name="value">The object to locate in the sequence</param>
|
||||
<param name="comparer">An equality comparer to compare values.</param>
|
||||
<returns>The zero-based index of the first occurrence of value within the entire sequence, if found; otherwise, –1.</returns>
|
||||
</member>
|
||||
<member name="M:Newtonsoft.Json.Utilities.ReflectionUtils.GetCollectionItemType(System.Type)">
|
||||
<summary>
|
||||
Gets the type of the typed collection's items.
|
||||
@@ -6055,13 +6145,6 @@
|
||||
<c>true</c> if the string is all white space; otherwise, <c>false</c>.
|
||||
</returns>
|
||||
</member>
|
||||
<member name="M:Newtonsoft.Json.Utilities.StringUtils.NullEmptyString(System.String)">
|
||||
<summary>
|
||||
Nulls an empty string.
|
||||
</summary>
|
||||
<param name="s">The string.</param>
|
||||
<returns>Null if the string was null, otherwise the string unchanged.</returns>
|
||||
</member>
|
||||
<member name="T:Newtonsoft.Json.Required">
|
||||
<summary>
|
||||
Indicating whether a property is required.
|
||||
@@ -6194,21 +6277,38 @@
|
||||
</member>
|
||||
<member name="P:Newtonsoft.Json.JsonContainerAttribute.ItemConverterType">
|
||||
<summary>
|
||||
Gets the collection's items converter.
|
||||
Gets or sets the collection's items converter.
|
||||
</summary>
|
||||
<value>The collection's items converter.</value>
|
||||
</member>
|
||||
<member name="P:Newtonsoft.Json.JsonContainerAttribute.ItemConverterParameters">
|
||||
<summary>
|
||||
The parameter list to use when constructing the JsonConverter described by ItemConverterType.
|
||||
The parameter list to use when constructing the <see cref="T:Newtonsoft.Json.JsonConverter"/> described by ItemConverterType.
|
||||
If null, the default constructor is used.
|
||||
When non-null, there must be a constructor defined in the JsonConverter that exactly matches the number,
|
||||
When non-null, there must be a constructor defined in the <see cref="T:Newtonsoft.Json.JsonConverter"/> that exactly matches the number,
|
||||
order, and type of these parameters.
|
||||
</summary>
|
||||
<example>
|
||||
[JsonContainer(ItemConverterType = typeof(MyContainerConverter), ItemConverterParameters = new object[] { 123, "Four" })]
|
||||
</example>
|
||||
</member>
|
||||
<member name="P:Newtonsoft.Json.JsonContainerAttribute.NamingStrategyType">
|
||||
<summary>
|
||||
Gets or sets the <see cref="T:System.Type"/> of the <see cref="T:Newtonsoft.Json.Serialization.NamingStrategy"/>.
|
||||
</summary>
|
||||
<value>The <see cref="T:System.Type"/> of the <see cref="T:Newtonsoft.Json.Serialization.NamingStrategy"/>.</value>
|
||||
</member>
|
||||
<member name="P:Newtonsoft.Json.JsonContainerAttribute.NamingStrategyParameters">
|
||||
<summary>
|
||||
The parameter list to use when constructing the <see cref="T:Newtonsoft.Json.Serialization.NamingStrategy"/> described by NamingStrategyType.
|
||||
If null, the default constructor is used.
|
||||
When non-null, there must be a constructor defined in the <see cref="T:Newtonsoft.Json.Serialization.NamingStrategy"/> that exactly matches the number,
|
||||
order, and type of these parameters.
|
||||
</summary>
|
||||
<example>
|
||||
[JsonContainer(NamingStrategyType = typeof(MyNamingStrategy), NamingStrategyParameters = new object[] { 123, "Four" })]
|
||||
</example>
|
||||
</member>
|
||||
<member name="P:Newtonsoft.Json.JsonContainerAttribute.IsReference">
|
||||
<summary>
|
||||
Gets or sets a value that indicates whether to preserve object references.
|
||||
@@ -6290,13 +6390,13 @@
|
||||
</member>
|
||||
<member name="P:Newtonsoft.Json.JsonConverterAttribute.ConverterType">
|
||||
<summary>
|
||||
Gets the <see cref="T:System.Type"/> of the converter.
|
||||
Gets the <see cref="T:System.Type"/> of the <see cref="T:Newtonsoft.Json.JsonConverter"/>.
|
||||
</summary>
|
||||
<value>The <see cref="T:System.Type"/> of the converter.</value>
|
||||
<value>The <see cref="T:System.Type"/> of the <see cref="T:Newtonsoft.Json.JsonConverter"/>.</value>
|
||||
</member>
|
||||
<member name="P:Newtonsoft.Json.JsonConverterAttribute.ConverterParameters">
|
||||
<summary>
|
||||
The parameter list to use when constructing the JsonConverter described by ConverterType.
|
||||
The parameter list to use when constructing the <see cref="T:Newtonsoft.Json.JsonConverter"/> described by ConverterType.
|
||||
If null, the default constructor is used.
|
||||
</summary>
|
||||
</member>
|
||||
@@ -6304,14 +6404,14 @@
|
||||
<summary>
|
||||
Initializes a new instance of the <see cref="T:Newtonsoft.Json.JsonConverterAttribute"/> class.
|
||||
</summary>
|
||||
<param name="converterType">Type of the converter.</param>
|
||||
<param name="converterType">Type of the <see cref="T:Newtonsoft.Json.JsonConverter"/>.</param>
|
||||
</member>
|
||||
<member name="M:Newtonsoft.Json.JsonConverterAttribute.#ctor(System.Type,System.Object[])">
|
||||
<summary>
|
||||
Initializes a new instance of the <see cref="T:Newtonsoft.Json.JsonConverterAttribute"/> class.
|
||||
</summary>
|
||||
<param name="converterType">Type of the converter.</param>
|
||||
<param name="converterParameters">Parameter list to use when constructing the JsonConverter. Can be null.</param>
|
||||
<param name="converterType">Type of the <see cref="T:Newtonsoft.Json.JsonConverter"/>.</param>
|
||||
<param name="converterParameters">Parameter list to use when constructing the <see cref="T:Newtonsoft.Json.JsonConverter"/>. Can be null.</param>
|
||||
</member>
|
||||
<member name="T:Newtonsoft.Json.JsonObjectAttribute">
|
||||
<summary>
|
||||
@@ -6657,7 +6757,7 @@
|
||||
Reads the next JSON token from the stream.
|
||||
</summary>
|
||||
<returns>
|
||||
true if the next token was read successfully; false if there are no more tokens to read.
|
||||
<c>true</c> if the next token was read successfully; <c>false</c> if there are no more tokens to read.
|
||||
</returns>
|
||||
</member>
|
||||
<member name="T:Newtonsoft.Json.MemberSerialization">
|
||||
@@ -6725,7 +6825,7 @@
|
||||
Reads the next JSON token from the stream.
|
||||
</summary>
|
||||
<returns>
|
||||
true if the next token was read successfully; false if there are no more tokens to read.
|
||||
<c>true</c> if the next token was read successfully; <c>false</c> if there are no more tokens to read.
|
||||
</returns>
|
||||
</member>
|
||||
<member name="M:Newtonsoft.Json.JsonTextReader.ReadAsInt32">
|
||||
@@ -6806,21 +6906,38 @@
|
||||
</member>
|
||||
<member name="P:Newtonsoft.Json.JsonPropertyAttribute.ItemConverterType">
|
||||
<summary>
|
||||
Gets or sets the converter used when serializing the property's collection items.
|
||||
Gets or sets the <see cref="T:Newtonsoft.Json.JsonConverter"/> used when serializing the property's collection items.
|
||||
</summary>
|
||||
<value>The collection's items converter.</value>
|
||||
<value>The collection's items <see cref="T:Newtonsoft.Json.JsonConverter"/>.</value>
|
||||
</member>
|
||||
<member name="P:Newtonsoft.Json.JsonPropertyAttribute.ItemConverterParameters">
|
||||
<summary>
|
||||
The parameter list to use when constructing the JsonConverter described by ItemConverterType.
|
||||
The parameter list to use when constructing the <see cref="T:Newtonsoft.Json.JsonConverter"/> described by ItemConverterType.
|
||||
If null, the default constructor is used.
|
||||
When non-null, there must be a constructor defined in the JsonConverter that exactly matches the number,
|
||||
When non-null, there must be a constructor defined in the <see cref="T:Newtonsoft.Json.JsonConverter"/> that exactly matches the number,
|
||||
order, and type of these parameters.
|
||||
</summary>
|
||||
<example>
|
||||
[JsonProperty(ItemConverterType = typeof(MyContainerConverter), ItemConverterParameters = new object[] { 123, "Four" })]
|
||||
</example>
|
||||
</member>
|
||||
<member name="P:Newtonsoft.Json.JsonPropertyAttribute.NamingStrategyType">
|
||||
<summary>
|
||||
Gets or sets the <see cref="T:System.Type"/> of the <see cref="T:Newtonsoft.Json.Serialization.NamingStrategy"/>.
|
||||
</summary>
|
||||
<value>The <see cref="T:System.Type"/> of the <see cref="T:Newtonsoft.Json.Serialization.NamingStrategy"/>.</value>
|
||||
</member>
|
||||
<member name="P:Newtonsoft.Json.JsonPropertyAttribute.NamingStrategyParameters">
|
||||
<summary>
|
||||
The parameter list to use when constructing the <see cref="T:Newtonsoft.Json.Serialization.NamingStrategy"/> described by NamingStrategyType.
|
||||
If null, the default constructor is used.
|
||||
When non-null, there must be a constructor defined in the <see cref="T:Newtonsoft.Json.Serialization.NamingStrategy"/> that exactly matches the number,
|
||||
order, and type of these parameters.
|
||||
</summary>
|
||||
<example>
|
||||
[JsonProperty(NamingStrategyType = typeof(MyNamingStrategy), NamingStrategyParameters = new object[] { 123, "Four" })]
|
||||
</example>
|
||||
</member>
|
||||
<member name="P:Newtonsoft.Json.JsonPropertyAttribute.NullValueHandling">
|
||||
<summary>
|
||||
Gets or sets the null value handling used when serializing this property.
|
||||
@@ -7490,7 +7607,7 @@
|
||||
<summary>
|
||||
Reads the next JSON token from the stream.
|
||||
</summary>
|
||||
<returns>true if the next token was read successfully; false if there are no more tokens to read.</returns>
|
||||
<returns><c>true</c> if the next token was read successfully; <c>false</c> if there are no more tokens to read.</returns>
|
||||
</member>
|
||||
<member name="M:Newtonsoft.Json.JsonReader.ReadAsInt32">
|
||||
<summary>
|
||||
Binary file not shown.
@@ -64,7 +64,7 @@
|
||||
Reads the next JSON token from the stream.
|
||||
</summary>
|
||||
<returns>
|
||||
true if the next token was read successfully; false if there are no more tokens to read.
|
||||
<c>true</c> if the next token was read successfully; <c>false</c> if there are no more tokens to read.
|
||||
</returns>
|
||||
</member>
|
||||
<member name="M:Newtonsoft.Json.Bson.BsonReader.Close">
|
||||
@@ -804,7 +804,7 @@
|
||||
</summary>
|
||||
<param name="attributeName">Attribute name to test.</param>
|
||||
<param name="prefix">The attribute name prefix if it has one, otherwise an empty string.</param>
|
||||
<returns>True if attribute name is for a namespace attribute, otherwise false.</returns>
|
||||
<returns><c>true</c> if attribute name is for a namespace attribute, otherwise <c>false</c>.</returns>
|
||||
</member>
|
||||
<member name="M:Newtonsoft.Json.Converters.XmlNodeConverter.CanConvert(System.Type)">
|
||||
<summary>
|
||||
@@ -822,12 +822,12 @@
|
||||
</member>
|
||||
<member name="F:Newtonsoft.Json.ConstructorHandling.Default">
|
||||
<summary>
|
||||
First attempt to use the public default constructor, then fall back to single paramatized constructor, then the non-public default constructor.
|
||||
First attempt to use the public default constructor, then fall back to single parameterized constructor, then the non-public default constructor.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="F:Newtonsoft.Json.ConstructorHandling.AllowNonPublicDefaultConstructor">
|
||||
<summary>
|
||||
Json.NET will use a non-public default constructor before falling back to a paramatized constructor.
|
||||
Json.NET will use a non-public default constructor before falling back to a parameterized constructor.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:Newtonsoft.Json.DateFormatHandling">
|
||||
@@ -1095,10 +1095,9 @@
|
||||
When overridden in a derived class, returns whether resetting an object changes its value.
|
||||
</summary>
|
||||
<returns>
|
||||
true if resetting the component changes its value; otherwise, false.
|
||||
<c>true</c> if resetting the component changes its value; otherwise, <c>false</c>.
|
||||
</returns>
|
||||
<param name="component">The component to test for reset capability.
|
||||
</param>
|
||||
<param name="component">The component to test for reset capability.</param>
|
||||
</member>
|
||||
<member name="M:Newtonsoft.Json.Linq.JPropertyDescriptor.GetValue(System.Object)">
|
||||
<summary>
|
||||
@@ -1130,10 +1129,9 @@
|
||||
When overridden in a derived class, determines a value indicating whether the value of this property needs to be persisted.
|
||||
</summary>
|
||||
<returns>
|
||||
true if the property should be persisted; otherwise, false.
|
||||
<c>true</c> if the property should be persisted; otherwise, <c>false</c>.
|
||||
</returns>
|
||||
<param name="component">The component with the property to be examined for persistence.
|
||||
</param>
|
||||
<param name="component">The component with the property to be examined for persistence.</param>
|
||||
</member>
|
||||
<member name="P:Newtonsoft.Json.Linq.JPropertyDescriptor.ComponentType">
|
||||
<summary>
|
||||
@@ -1148,7 +1146,7 @@
|
||||
When overridden in a derived class, gets a value indicating whether this property is read-only.
|
||||
</summary>
|
||||
<returns>
|
||||
true if the property is read-only; otherwise, false.
|
||||
<c>true</c> if the property is read-only; otherwise, <c>false</c>.
|
||||
</returns>
|
||||
</member>
|
||||
<member name="P:Newtonsoft.Json.Linq.JPropertyDescriptor.PropertyType">
|
||||
@@ -1282,7 +1280,7 @@
|
||||
<param name="x">The first object of type <see cref="T:Newtonsoft.Json.Linq.JToken"/> to compare.</param>
|
||||
<param name="y">The second object of type <see cref="T:Newtonsoft.Json.Linq.JToken"/> to compare.</param>
|
||||
<returns>
|
||||
true if the specified objects are equal; otherwise, false.
|
||||
<c>true</c> if the specified objects are equal; otherwise, <c>false</c>.
|
||||
</returns>
|
||||
</member>
|
||||
<member name="M:Newtonsoft.Json.Linq.JTokenEqualityComparer.GetHashCode(Newtonsoft.Json.Linq.JToken)">
|
||||
@@ -1870,7 +1868,7 @@
|
||||
<param name="propertyName">Name of the property.</param>
|
||||
<param name="value">The value.</param>
|
||||
<param name="comparison">One of the enumeration values that specifies how the strings will be compared.</param>
|
||||
<returns>true if a value was successfully retrieved; otherwise, false.</returns>
|
||||
<returns><c>true</c> if a value was successfully retrieved; otherwise, <c>false</c>.</returns>
|
||||
</member>
|
||||
<member name="M:Newtonsoft.Json.Linq.JObject.Add(System.String,Newtonsoft.Json.Linq.JToken)">
|
||||
<summary>
|
||||
@@ -1884,7 +1882,7 @@
|
||||
Removes the property with the specified name.
|
||||
</summary>
|
||||
<param name="propertyName">Name of the property.</param>
|
||||
<returns>true if item was successfully removed; otherwise, false.</returns>
|
||||
<returns><c>true</c> if item was successfully removed; otherwise, <c>false</c>.</returns>
|
||||
</member>
|
||||
<member name="M:Newtonsoft.Json.Linq.JObject.TryGetValue(System.String,Newtonsoft.Json.Linq.JToken@)">
|
||||
<summary>
|
||||
@@ -1892,7 +1890,7 @@
|
||||
</summary>
|
||||
<param name="propertyName">Name of the property.</param>
|
||||
<param name="value">The value.</param>
|
||||
<returns>true if a value was successfully retrieved; otherwise, false.</returns>
|
||||
<returns><c>true</c> if a value was successfully retrieved; otherwise, <c>false</c>.</returns>
|
||||
</member>
|
||||
<member name="M:Newtonsoft.Json.Linq.JObject.GetEnumerator">
|
||||
<summary>
|
||||
@@ -2231,7 +2229,7 @@
|
||||
Reads the next JSON token from the stream.
|
||||
</summary>
|
||||
<returns>
|
||||
true if the next token was read successfully; false if there are no more tokens to read.
|
||||
<c>true</c> if the next token was read successfully; <c>false</c> if there are no more tokens to read.
|
||||
</returns>
|
||||
</member>
|
||||
<member name="P:Newtonsoft.Json.Linq.JTokenReader.Path">
|
||||
@@ -2496,7 +2494,7 @@
|
||||
</summary>
|
||||
<param name="t1">The first <see cref="T:Newtonsoft.Json.Linq.JToken"/> to compare.</param>
|
||||
<param name="t2">The second <see cref="T:Newtonsoft.Json.Linq.JToken"/> to compare.</param>
|
||||
<returns>true if the tokens are equal; otherwise false.</returns>
|
||||
<returns><c>true</c> if the tokens are equal; otherwise <c>false</c>.</returns>
|
||||
</member>
|
||||
<member name="P:Newtonsoft.Json.Linq.JToken.Next">
|
||||
<summary>
|
||||
@@ -3660,7 +3658,7 @@
|
||||
Indicates whether the current object is equal to another object of the same type.
|
||||
</summary>
|
||||
<returns>
|
||||
true if the current object is equal to the <paramref name="other"/> parameter; otherwise, false.
|
||||
<c>true</c> if the current object is equal to the <paramref name="other"/> parameter; otherwise, <c>false</c>.
|
||||
</returns>
|
||||
<param name="other">An object to compare with this object.</param>
|
||||
</member>
|
||||
@@ -3670,7 +3668,7 @@
|
||||
</summary>
|
||||
<param name="obj">The <see cref="T:System.Object"/> to compare with the current <see cref="T:System.Object"/>.</param>
|
||||
<returns>
|
||||
true if the specified <see cref="T:System.Object"/> is equal to the current <see cref="T:System.Object"/>; otherwise, false.
|
||||
<c>true</c> if the specified <see cref="T:System.Object"/> is equal to the current <see cref="T:System.Object"/>; otherwise, <c>false</c>.
|
||||
</returns>
|
||||
<exception cref="T:System.NullReferenceException">
|
||||
The <paramref name="obj"/> parameter is null.
|
||||
@@ -3760,6 +3758,47 @@
|
||||
Do not try to read metadata properties.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:Newtonsoft.Json.Serialization.CamelCaseNamingStrategy">
|
||||
<summary>
|
||||
A camel case naming strategy.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:Newtonsoft.Json.Serialization.CamelCaseNamingStrategy.#ctor(System.Boolean,System.Boolean)">
|
||||
<summary>
|
||||
Initializes a new instance of the <see cref="T:Newtonsoft.Json.Serialization.CamelCaseNamingStrategy"/> class.
|
||||
</summary>
|
||||
<param name="processDictionaryKeys">
|
||||
A flag indicating whether dictionary keys should be processed.
|
||||
</param>
|
||||
<param name="overrideSpecifiedNames">
|
||||
A flag indicating whether explicitly specified property names should be processed,
|
||||
e.g. a property name customized with a <see cref="T:Newtonsoft.Json.JsonPropertyAttribute"/>.
|
||||
</param>
|
||||
</member>
|
||||
<member name="M:Newtonsoft.Json.Serialization.CamelCaseNamingStrategy.#ctor">
|
||||
<summary>
|
||||
Initializes a new instance of the <see cref="T:Newtonsoft.Json.Serialization.CamelCaseNamingStrategy"/> class.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:Newtonsoft.Json.Serialization.CamelCaseNamingStrategy.ResolvePropertyName(System.String)">
|
||||
<summary>
|
||||
Resolves the specified property name.
|
||||
</summary>
|
||||
<param name="name">The property name to resolve.</param>
|
||||
<returns>The resolved property name.</returns>
|
||||
</member>
|
||||
<member name="T:Newtonsoft.Json.Serialization.DefaultNamingStrategy">
|
||||
<summary>
|
||||
The default naming strategy. Property names and dictionary keys are unchanged.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:Newtonsoft.Json.Serialization.DefaultNamingStrategy.ResolvePropertyName(System.String)">
|
||||
<summary>
|
||||
Resolves the specified property name.
|
||||
</summary>
|
||||
<param name="name">The property name to resolve.</param>
|
||||
<returns>The resolved property name.</returns>
|
||||
</member>
|
||||
<member name="T:Newtonsoft.Json.Serialization.DiagnosticsTraceWriter">
|
||||
<summary>
|
||||
Represents a trace writer that writes to the application's <see cref="T:System.Diagnostics.TraceListener"/> instances.
|
||||
@@ -3902,6 +3941,46 @@
|
||||
A <see cref="T:System.String"/> of the most recent trace messages.
|
||||
</returns>
|
||||
</member>
|
||||
<member name="T:Newtonsoft.Json.Serialization.NamingStrategy">
|
||||
<summary>
|
||||
A base class for resolving how property names and dictionary keys are serialized.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:Newtonsoft.Json.Serialization.NamingStrategy.ProcessDictionaryKeys">
|
||||
<summary>
|
||||
A flag indicating whether dictionary keys should be processed.
|
||||
Defaults to <c>false</c>.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:Newtonsoft.Json.Serialization.NamingStrategy.OverrideSpecifiedNames">
|
||||
<summary>
|
||||
A flag indicating whether explicitly specified property names,
|
||||
e.g. a property name customized with a <see cref="T:Newtonsoft.Json.JsonPropertyAttribute"/>, should be processed.
|
||||
Defaults to <c>false</c>.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:Newtonsoft.Json.Serialization.NamingStrategy.GetPropertyName(System.String,System.Boolean)">
|
||||
<summary>
|
||||
Gets the serialized name for a given property name.
|
||||
</summary>
|
||||
<param name="name">The initial property name.</param>
|
||||
<param name="hasSpecifiedName">A flag indicating whether the property has had a name explicitly specfied.</param>
|
||||
<returns>The serialized property name.</returns>
|
||||
</member>
|
||||
<member name="M:Newtonsoft.Json.Serialization.NamingStrategy.GetDictionaryKey(System.String)">
|
||||
<summary>
|
||||
Gets the serialized key for a given dictionary key.
|
||||
</summary>
|
||||
<param name="key">The initial dictionary key.</param>
|
||||
<returns>The serialized dictionary key.</returns>
|
||||
</member>
|
||||
<member name="M:Newtonsoft.Json.Serialization.NamingStrategy.ResolvePropertyName(System.String)">
|
||||
<summary>
|
||||
Resolves the specified property name.
|
||||
</summary>
|
||||
<param name="name">The property name to resolve.</param>
|
||||
<returns>The resolved property name.</returns>
|
||||
</member>
|
||||
<member name="T:Newtonsoft.Json.Serialization.ReflectionAttributeProvider">
|
||||
<summary>
|
||||
Provides methods to get attributes from a <see cref="T:System.Type"/>, <see cref="T:System.Reflection.MemberInfo"/>, <see cref="T:System.Reflection.ParameterInfo"/> or <see cref="T:System.Reflection.Assembly"/>.
|
||||
@@ -3928,6 +4007,35 @@
|
||||
<param name="inherit">When true, look up the hierarchy chain for the inherited custom attribute.</param>
|
||||
<returns>A collection of <see cref="T:System.Attribute"/>s, or an empty collection.</returns>
|
||||
</member>
|
||||
<member name="T:Newtonsoft.Json.Serialization.SnakeCaseNamingStrategy">
|
||||
<summary>
|
||||
A snake case naming strategy.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:Newtonsoft.Json.Serialization.SnakeCaseNamingStrategy.#ctor(System.Boolean,System.Boolean)">
|
||||
<summary>
|
||||
Initializes a new instance of the <see cref="T:Newtonsoft.Json.Serialization.SnakeCaseNamingStrategy"/> class.
|
||||
</summary>
|
||||
<param name="processDictionaryKeys">
|
||||
A flag indicating whether dictionary keys should be processed.
|
||||
</param>
|
||||
<param name="overrideSpecifiedNames">
|
||||
A flag indicating whether explicitly specified property names should be processed,
|
||||
e.g. a property name customized with a <see cref="T:Newtonsoft.Json.JsonPropertyAttribute"/>.
|
||||
</param>
|
||||
</member>
|
||||
<member name="M:Newtonsoft.Json.Serialization.SnakeCaseNamingStrategy.#ctor">
|
||||
<summary>
|
||||
Initializes a new instance of the <see cref="T:Newtonsoft.Json.Serialization.SnakeCaseNamingStrategy"/> class.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:Newtonsoft.Json.Serialization.SnakeCaseNamingStrategy.ResolvePropertyName(System.String)">
|
||||
<summary>
|
||||
Resolves the specified property name.
|
||||
</summary>
|
||||
<param name="name">The property name to resolve.</param>
|
||||
<returns>The resolved property name.</returns>
|
||||
</member>
|
||||
<member name="T:Newtonsoft.Json.Serialization.JsonISerializableContract">
|
||||
<summary>
|
||||
Contract details for a <see cref="T:System.Type"/> used by the <see cref="T:Newtonsoft.Json.JsonSerializer"/>.
|
||||
@@ -4026,13 +4134,6 @@
|
||||
Initializes a new instance of the <see cref="T:Newtonsoft.Json.Serialization.CamelCasePropertyNamesContractResolver"/> class.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:Newtonsoft.Json.Serialization.CamelCasePropertyNamesContractResolver.ResolvePropertyName(System.String)">
|
||||
<summary>
|
||||
Resolves the name of the property.
|
||||
</summary>
|
||||
<param name="propertyName">Name of the property.</param>
|
||||
<returns>The property name camel cased.</returns>
|
||||
</member>
|
||||
<member name="T:Newtonsoft.Json.Serialization.DefaultContractResolver">
|
||||
<summary>
|
||||
Used by <see cref="T:Newtonsoft.Json.JsonSerializer"/> to resolves a <see cref="T:Newtonsoft.Json.Serialization.JsonContract"/> for a given <see cref="T:System.Type"/>.
|
||||
@@ -4077,6 +4178,12 @@
|
||||
<c>true</c> if the <see cref="T:System.SerializableAttribute"/> attribute will be ignored when serializing and deserializing types; otherwise, <c>false</c>.
|
||||
</value>
|
||||
</member>
|
||||
<member name="P:Newtonsoft.Json.Serialization.DefaultContractResolver.NamingStrategy">
|
||||
<summary>
|
||||
Gets or sets the naming strategy used to resolve how property names and dictionary keys are serialized.
|
||||
</summary>
|
||||
<value>The naming strategy used to resolve how property names and dictionary keys are serialized.</value>
|
||||
</member>
|
||||
<member name="M:Newtonsoft.Json.Serialization.DefaultContractResolver.#ctor">
|
||||
<summary>
|
||||
Initializes a new instance of the <see cref="T:Newtonsoft.Json.Serialization.DefaultContractResolver"/> class.
|
||||
@@ -4893,13 +5000,6 @@
|
||||
<param name="converterArgs">Optional arguments to pass to an initializing constructor of the JsonConverter.
|
||||
If null, the default constructor is used.</param>
|
||||
</member>
|
||||
<member name="M:Newtonsoft.Json.Serialization.JsonTypeReflector.GetJsonConverterCreator(System.Type)">
|
||||
<summary>
|
||||
Create a factory function that can be used to create instances of a JsonConverter described by the
|
||||
argument type. The returned function can then be used to either invoke the converter's default ctor, or any
|
||||
parameterized constructors by way of an object array.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:Newtonsoft.Json.Serialization.ReflectionValueProvider">
|
||||
<summary>
|
||||
Get and set values for a <see cref="T:System.Reflection.MemberInfo"/> using reflection.
|
||||
@@ -5003,16 +5103,6 @@
|
||||
<param name="initial">The list to add to.</param>
|
||||
<param name="collection">The collection of elements to add.</param>
|
||||
</member>
|
||||
<member name="M:Newtonsoft.Json.Utilities.CollectionUtils.IndexOf``1(System.Collections.Generic.IEnumerable{``0},``0,System.Collections.Generic.IEqualityComparer{``0})">
|
||||
<summary>
|
||||
Returns the index of the first occurrence in a sequence by using a specified IEqualityComparer{TSource}.
|
||||
</summary>
|
||||
<typeparam name="TSource">The type of the elements of source.</typeparam>
|
||||
<param name="list">A sequence in which to locate a value.</param>
|
||||
<param name="value">The object to locate in the sequence</param>
|
||||
<param name="comparer">An equality comparer to compare values.</param>
|
||||
<returns>The zero-based index of the first occurrence of value within the entire sequence, if found; otherwise, –1.</returns>
|
||||
</member>
|
||||
<member name="M:Newtonsoft.Json.Utilities.ReflectionUtils.GetCollectionItemType(System.Type)">
|
||||
<summary>
|
||||
Gets the type of the typed collection's items.
|
||||
@@ -5091,13 +5181,6 @@
|
||||
<c>true</c> if the string is all white space; otherwise, <c>false</c>.
|
||||
</returns>
|
||||
</member>
|
||||
<member name="M:Newtonsoft.Json.Utilities.StringUtils.NullEmptyString(System.String)">
|
||||
<summary>
|
||||
Nulls an empty string.
|
||||
</summary>
|
||||
<param name="s">The string.</param>
|
||||
<returns>Null if the string was null, otherwise the string unchanged.</returns>
|
||||
</member>
|
||||
<member name="T:Newtonsoft.Json.Required">
|
||||
<summary>
|
||||
Indicating whether a property is required.
|
||||
@@ -5230,21 +5313,38 @@
|
||||
</member>
|
||||
<member name="P:Newtonsoft.Json.JsonContainerAttribute.ItemConverterType">
|
||||
<summary>
|
||||
Gets the collection's items converter.
|
||||
Gets or sets the collection's items converter.
|
||||
</summary>
|
||||
<value>The collection's items converter.</value>
|
||||
</member>
|
||||
<member name="P:Newtonsoft.Json.JsonContainerAttribute.ItemConverterParameters">
|
||||
<summary>
|
||||
The parameter list to use when constructing the JsonConverter described by ItemConverterType.
|
||||
The parameter list to use when constructing the <see cref="T:Newtonsoft.Json.JsonConverter"/> described by ItemConverterType.
|
||||
If null, the default constructor is used.
|
||||
When non-null, there must be a constructor defined in the JsonConverter that exactly matches the number,
|
||||
When non-null, there must be a constructor defined in the <see cref="T:Newtonsoft.Json.JsonConverter"/> that exactly matches the number,
|
||||
order, and type of these parameters.
|
||||
</summary>
|
||||
<example>
|
||||
[JsonContainer(ItemConverterType = typeof(MyContainerConverter), ItemConverterParameters = new object[] { 123, "Four" })]
|
||||
</example>
|
||||
</member>
|
||||
<member name="P:Newtonsoft.Json.JsonContainerAttribute.NamingStrategyType">
|
||||
<summary>
|
||||
Gets or sets the <see cref="T:System.Type"/> of the <see cref="T:Newtonsoft.Json.Serialization.NamingStrategy"/>.
|
||||
</summary>
|
||||
<value>The <see cref="T:System.Type"/> of the <see cref="T:Newtonsoft.Json.Serialization.NamingStrategy"/>.</value>
|
||||
</member>
|
||||
<member name="P:Newtonsoft.Json.JsonContainerAttribute.NamingStrategyParameters">
|
||||
<summary>
|
||||
The parameter list to use when constructing the <see cref="T:Newtonsoft.Json.Serialization.NamingStrategy"/> described by NamingStrategyType.
|
||||
If null, the default constructor is used.
|
||||
When non-null, there must be a constructor defined in the <see cref="T:Newtonsoft.Json.Serialization.NamingStrategy"/> that exactly matches the number,
|
||||
order, and type of these parameters.
|
||||
</summary>
|
||||
<example>
|
||||
[JsonContainer(NamingStrategyType = typeof(MyNamingStrategy), NamingStrategyParameters = new object[] { 123, "Four" })]
|
||||
</example>
|
||||
</member>
|
||||
<member name="P:Newtonsoft.Json.JsonContainerAttribute.IsReference">
|
||||
<summary>
|
||||
Gets or sets a value that indicates whether to preserve object references.
|
||||
@@ -5326,13 +5426,13 @@
|
||||
</member>
|
||||
<member name="P:Newtonsoft.Json.JsonConverterAttribute.ConverterType">
|
||||
<summary>
|
||||
Gets the <see cref="T:System.Type"/> of the converter.
|
||||
Gets the <see cref="T:System.Type"/> of the <see cref="T:Newtonsoft.Json.JsonConverter"/>.
|
||||
</summary>
|
||||
<value>The <see cref="T:System.Type"/> of the converter.</value>
|
||||
<value>The <see cref="T:System.Type"/> of the <see cref="T:Newtonsoft.Json.JsonConverter"/>.</value>
|
||||
</member>
|
||||
<member name="P:Newtonsoft.Json.JsonConverterAttribute.ConverterParameters">
|
||||
<summary>
|
||||
The parameter list to use when constructing the JsonConverter described by ConverterType.
|
||||
The parameter list to use when constructing the <see cref="T:Newtonsoft.Json.JsonConverter"/> described by ConverterType.
|
||||
If null, the default constructor is used.
|
||||
</summary>
|
||||
</member>
|
||||
@@ -5340,14 +5440,14 @@
|
||||
<summary>
|
||||
Initializes a new instance of the <see cref="T:Newtonsoft.Json.JsonConverterAttribute"/> class.
|
||||
</summary>
|
||||
<param name="converterType">Type of the converter.</param>
|
||||
<param name="converterType">Type of the <see cref="T:Newtonsoft.Json.JsonConverter"/>.</param>
|
||||
</member>
|
||||
<member name="M:Newtonsoft.Json.JsonConverterAttribute.#ctor(System.Type,System.Object[])">
|
||||
<summary>
|
||||
Initializes a new instance of the <see cref="T:Newtonsoft.Json.JsonConverterAttribute"/> class.
|
||||
</summary>
|
||||
<param name="converterType">Type of the converter.</param>
|
||||
<param name="converterParameters">Parameter list to use when constructing the JsonConverter. Can be null.</param>
|
||||
<param name="converterType">Type of the <see cref="T:Newtonsoft.Json.JsonConverter"/>.</param>
|
||||
<param name="converterParameters">Parameter list to use when constructing the <see cref="T:Newtonsoft.Json.JsonConverter"/>. Can be null.</param>
|
||||
</member>
|
||||
<member name="T:Newtonsoft.Json.JsonObjectAttribute">
|
||||
<summary>
|
||||
@@ -5699,7 +5799,7 @@
|
||||
Reads the next JSON token from the stream.
|
||||
</summary>
|
||||
<returns>
|
||||
true if the next token was read successfully; false if there are no more tokens to read.
|
||||
<c>true</c> if the next token was read successfully; <c>false</c> if there are no more tokens to read.
|
||||
</returns>
|
||||
</member>
|
||||
<member name="T:Newtonsoft.Json.MemberSerialization">
|
||||
@@ -5767,7 +5867,7 @@
|
||||
Reads the next JSON token from the stream.
|
||||
</summary>
|
||||
<returns>
|
||||
true if the next token was read successfully; false if there are no more tokens to read.
|
||||
<c>true</c> if the next token was read successfully; <c>false</c> if there are no more tokens to read.
|
||||
</returns>
|
||||
</member>
|
||||
<member name="M:Newtonsoft.Json.JsonTextReader.ReadAsInt32">
|
||||
@@ -5854,21 +5954,38 @@
|
||||
</member>
|
||||
<member name="P:Newtonsoft.Json.JsonPropertyAttribute.ItemConverterType">
|
||||
<summary>
|
||||
Gets or sets the converter used when serializing the property's collection items.
|
||||
Gets or sets the <see cref="T:Newtonsoft.Json.JsonConverter"/> used when serializing the property's collection items.
|
||||
</summary>
|
||||
<value>The collection's items converter.</value>
|
||||
<value>The collection's items <see cref="T:Newtonsoft.Json.JsonConverter"/>.</value>
|
||||
</member>
|
||||
<member name="P:Newtonsoft.Json.JsonPropertyAttribute.ItemConverterParameters">
|
||||
<summary>
|
||||
The parameter list to use when constructing the JsonConverter described by ItemConverterType.
|
||||
The parameter list to use when constructing the <see cref="T:Newtonsoft.Json.JsonConverter"/> described by ItemConverterType.
|
||||
If null, the default constructor is used.
|
||||
When non-null, there must be a constructor defined in the JsonConverter that exactly matches the number,
|
||||
When non-null, there must be a constructor defined in the <see cref="T:Newtonsoft.Json.JsonConverter"/> that exactly matches the number,
|
||||
order, and type of these parameters.
|
||||
</summary>
|
||||
<example>
|
||||
[JsonProperty(ItemConverterType = typeof(MyContainerConverter), ItemConverterParameters = new object[] { 123, "Four" })]
|
||||
</example>
|
||||
</member>
|
||||
<member name="P:Newtonsoft.Json.JsonPropertyAttribute.NamingStrategyType">
|
||||
<summary>
|
||||
Gets or sets the <see cref="T:System.Type"/> of the <see cref="T:Newtonsoft.Json.Serialization.NamingStrategy"/>.
|
||||
</summary>
|
||||
<value>The <see cref="T:System.Type"/> of the <see cref="T:Newtonsoft.Json.Serialization.NamingStrategy"/>.</value>
|
||||
</member>
|
||||
<member name="P:Newtonsoft.Json.JsonPropertyAttribute.NamingStrategyParameters">
|
||||
<summary>
|
||||
The parameter list to use when constructing the <see cref="T:Newtonsoft.Json.Serialization.NamingStrategy"/> described by NamingStrategyType.
|
||||
If null, the default constructor is used.
|
||||
When non-null, there must be a constructor defined in the <see cref="T:Newtonsoft.Json.Serialization.NamingStrategy"/> that exactly matches the number,
|
||||
order, and type of these parameters.
|
||||
</summary>
|
||||
<example>
|
||||
[JsonProperty(NamingStrategyType = typeof(MyNamingStrategy), NamingStrategyParameters = new object[] { 123, "Four" })]
|
||||
</example>
|
||||
</member>
|
||||
<member name="P:Newtonsoft.Json.JsonPropertyAttribute.NullValueHandling">
|
||||
<summary>
|
||||
Gets or sets the null value handling used when serializing this property.
|
||||
@@ -6544,7 +6661,7 @@
|
||||
<summary>
|
||||
Reads the next JSON token from the stream.
|
||||
</summary>
|
||||
<returns>true if the next token was read successfully; false if there are no more tokens to read.</returns>
|
||||
<returns><c>true</c> if the next token was read successfully; <c>false</c> if there are no more tokens to read.</returns>
|
||||
</member>
|
||||
<member name="M:Newtonsoft.Json.JsonReader.ReadAsInt32">
|
||||
<summary>
|
||||
Binary file not shown.
@@ -64,7 +64,7 @@
|
||||
Reads the next JSON token from the stream.
|
||||
</summary>
|
||||
<returns>
|
||||
true if the next token was read successfully; false if there are no more tokens to read.
|
||||
<c>true</c> if the next token was read successfully; <c>false</c> if there are no more tokens to read.
|
||||
</returns>
|
||||
</member>
|
||||
<member name="M:Newtonsoft.Json.Bson.BsonReader.Close">
|
||||
@@ -876,7 +876,7 @@
|
||||
</summary>
|
||||
<param name="attributeName">Attribute name to test.</param>
|
||||
<param name="prefix">The attribute name prefix if it has one, otherwise an empty string.</param>
|
||||
<returns>True if attribute name is for a namespace attribute, otherwise false.</returns>
|
||||
<returns><c>true</c> if attribute name is for a namespace attribute, otherwise <c>false</c>.</returns>
|
||||
</member>
|
||||
<member name="M:Newtonsoft.Json.Converters.XmlNodeConverter.CanConvert(System.Type)">
|
||||
<summary>
|
||||
@@ -894,12 +894,12 @@
|
||||
</member>
|
||||
<member name="F:Newtonsoft.Json.ConstructorHandling.Default">
|
||||
<summary>
|
||||
First attempt to use the public default constructor, then fall back to single paramatized constructor, then the non-public default constructor.
|
||||
First attempt to use the public default constructor, then fall back to single parameterized constructor, then the non-public default constructor.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="F:Newtonsoft.Json.ConstructorHandling.AllowNonPublicDefaultConstructor">
|
||||
<summary>
|
||||
Json.NET will use a non-public default constructor before falling back to a paramatized constructor.
|
||||
Json.NET will use a non-public default constructor before falling back to a parameterized constructor.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:Newtonsoft.Json.FloatFormatHandling">
|
||||
@@ -1257,10 +1257,9 @@
|
||||
When overridden in a derived class, returns whether resetting an object changes its value.
|
||||
</summary>
|
||||
<returns>
|
||||
true if resetting the component changes its value; otherwise, false.
|
||||
<c>true</c> if resetting the component changes its value; otherwise, <c>false</c>.
|
||||
</returns>
|
||||
<param name="component">The component to test for reset capability.
|
||||
</param>
|
||||
<param name="component">The component to test for reset capability.</param>
|
||||
</member>
|
||||
<member name="M:Newtonsoft.Json.Linq.JPropertyDescriptor.GetValue(System.Object)">
|
||||
<summary>
|
||||
@@ -1292,10 +1291,9 @@
|
||||
When overridden in a derived class, determines a value indicating whether the value of this property needs to be persisted.
|
||||
</summary>
|
||||
<returns>
|
||||
true if the property should be persisted; otherwise, false.
|
||||
<c>true</c> if the property should be persisted; otherwise, <c>false</c>.
|
||||
</returns>
|
||||
<param name="component">The component with the property to be examined for persistence.
|
||||
</param>
|
||||
<param name="component">The component with the property to be examined for persistence.</param>
|
||||
</member>
|
||||
<member name="P:Newtonsoft.Json.Linq.JPropertyDescriptor.ComponentType">
|
||||
<summary>
|
||||
@@ -1310,7 +1308,7 @@
|
||||
When overridden in a derived class, gets a value indicating whether this property is read-only.
|
||||
</summary>
|
||||
<returns>
|
||||
true if the property is read-only; otherwise, false.
|
||||
<c>true</c> if the property is read-only; otherwise, <c>false</c>.
|
||||
</returns>
|
||||
</member>
|
||||
<member name="P:Newtonsoft.Json.Linq.JPropertyDescriptor.PropertyType">
|
||||
@@ -1354,7 +1352,7 @@
|
||||
<param name="x">The first object of type <see cref="T:Newtonsoft.Json.Linq.JToken"/> to compare.</param>
|
||||
<param name="y">The second object of type <see cref="T:Newtonsoft.Json.Linq.JToken"/> to compare.</param>
|
||||
<returns>
|
||||
true if the specified objects are equal; otherwise, false.
|
||||
<c>true</c> if the specified objects are equal; otherwise, <c>false</c>.
|
||||
</returns>
|
||||
</member>
|
||||
<member name="M:Newtonsoft.Json.Linq.JTokenEqualityComparer.GetHashCode(Newtonsoft.Json.Linq.JToken)">
|
||||
@@ -1953,7 +1951,7 @@
|
||||
<param name="propertyName">Name of the property.</param>
|
||||
<param name="value">The value.</param>
|
||||
<param name="comparison">One of the enumeration values that specifies how the strings will be compared.</param>
|
||||
<returns>true if a value was successfully retrieved; otherwise, false.</returns>
|
||||
<returns><c>true</c> if a value was successfully retrieved; otherwise, <c>false</c>.</returns>
|
||||
</member>
|
||||
<member name="M:Newtonsoft.Json.Linq.JObject.Add(System.String,Newtonsoft.Json.Linq.JToken)">
|
||||
<summary>
|
||||
@@ -1967,7 +1965,7 @@
|
||||
Removes the property with the specified name.
|
||||
</summary>
|
||||
<param name="propertyName">Name of the property.</param>
|
||||
<returns>true if item was successfully removed; otherwise, false.</returns>
|
||||
<returns><c>true</c> if item was successfully removed; otherwise, <c>false</c>.</returns>
|
||||
</member>
|
||||
<member name="M:Newtonsoft.Json.Linq.JObject.TryGetValue(System.String,Newtonsoft.Json.Linq.JToken@)">
|
||||
<summary>
|
||||
@@ -1975,7 +1973,7 @@
|
||||
</summary>
|
||||
<param name="propertyName">Name of the property.</param>
|
||||
<param name="value">The value.</param>
|
||||
<returns>true if a value was successfully retrieved; otherwise, false.</returns>
|
||||
<returns><c>true</c> if a value was successfully retrieved; otherwise, <c>false</c>.</returns>
|
||||
</member>
|
||||
<member name="M:Newtonsoft.Json.Linq.JObject.GetEnumerator">
|
||||
<summary>
|
||||
@@ -2323,7 +2321,7 @@
|
||||
Reads the next JSON token from the stream.
|
||||
</summary>
|
||||
<returns>
|
||||
true if the next token was read successfully; false if there are no more tokens to read.
|
||||
<c>true</c> if the next token was read successfully; <c>false</c> if there are no more tokens to read.
|
||||
</returns>
|
||||
</member>
|
||||
<member name="P:Newtonsoft.Json.Linq.JTokenReader.Path">
|
||||
@@ -2588,7 +2586,7 @@
|
||||
</summary>
|
||||
<param name="t1">The first <see cref="T:Newtonsoft.Json.Linq.JToken"/> to compare.</param>
|
||||
<param name="t2">The second <see cref="T:Newtonsoft.Json.Linq.JToken"/> to compare.</param>
|
||||
<returns>true if the tokens are equal; otherwise false.</returns>
|
||||
<returns><c>true</c> if the tokens are equal; otherwise <c>false</c>.</returns>
|
||||
</member>
|
||||
<member name="P:Newtonsoft.Json.Linq.JToken.Next">
|
||||
<summary>
|
||||
@@ -3770,7 +3768,7 @@
|
||||
Indicates whether the current object is equal to another object of the same type.
|
||||
</summary>
|
||||
<returns>
|
||||
true if the current object is equal to the <paramref name="other"/> parameter; otherwise, false.
|
||||
<c>true</c> if the current object is equal to the <paramref name="other"/> parameter; otherwise, <c>false</c>.
|
||||
</returns>
|
||||
<param name="other">An object to compare with this object.</param>
|
||||
</member>
|
||||
@@ -3780,7 +3778,7 @@
|
||||
</summary>
|
||||
<param name="obj">The <see cref="T:System.Object"/> to compare with the current <see cref="T:System.Object"/>.</param>
|
||||
<returns>
|
||||
true if the specified <see cref="T:System.Object"/> is equal to the current <see cref="T:System.Object"/>; otherwise, false.
|
||||
<c>true</c> if the specified <see cref="T:System.Object"/> is equal to the current <see cref="T:System.Object"/>; otherwise, <c>false</c>.
|
||||
</returns>
|
||||
<exception cref="T:System.NullReferenceException">
|
||||
The <paramref name="obj"/> parameter is null.
|
||||
@@ -3879,6 +3877,47 @@
|
||||
Do not try to read metadata properties.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:Newtonsoft.Json.Serialization.CamelCaseNamingStrategy">
|
||||
<summary>
|
||||
A camel case naming strategy.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:Newtonsoft.Json.Serialization.CamelCaseNamingStrategy.#ctor(System.Boolean,System.Boolean)">
|
||||
<summary>
|
||||
Initializes a new instance of the <see cref="T:Newtonsoft.Json.Serialization.CamelCaseNamingStrategy"/> class.
|
||||
</summary>
|
||||
<param name="processDictionaryKeys">
|
||||
A flag indicating whether dictionary keys should be processed.
|
||||
</param>
|
||||
<param name="overrideSpecifiedNames">
|
||||
A flag indicating whether explicitly specified property names should be processed,
|
||||
e.g. a property name customized with a <see cref="T:Newtonsoft.Json.JsonPropertyAttribute"/>.
|
||||
</param>
|
||||
</member>
|
||||
<member name="M:Newtonsoft.Json.Serialization.CamelCaseNamingStrategy.#ctor">
|
||||
<summary>
|
||||
Initializes a new instance of the <see cref="T:Newtonsoft.Json.Serialization.CamelCaseNamingStrategy"/> class.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:Newtonsoft.Json.Serialization.CamelCaseNamingStrategy.ResolvePropertyName(System.String)">
|
||||
<summary>
|
||||
Resolves the specified property name.
|
||||
</summary>
|
||||
<param name="name">The property name to resolve.</param>
|
||||
<returns>The resolved property name.</returns>
|
||||
</member>
|
||||
<member name="T:Newtonsoft.Json.Serialization.DefaultNamingStrategy">
|
||||
<summary>
|
||||
The default naming strategy. Property names and dictionary keys are unchanged.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:Newtonsoft.Json.Serialization.DefaultNamingStrategy.ResolvePropertyName(System.String)">
|
||||
<summary>
|
||||
Resolves the specified property name.
|
||||
</summary>
|
||||
<param name="name">The property name to resolve.</param>
|
||||
<returns>The resolved property name.</returns>
|
||||
</member>
|
||||
<member name="T:Newtonsoft.Json.Serialization.DiagnosticsTraceWriter">
|
||||
<summary>
|
||||
Represents a trace writer that writes to the application's <see cref="T:System.Diagnostics.TraceListener"/> instances.
|
||||
@@ -4046,6 +4085,46 @@
|
||||
A <see cref="T:System.String"/> of the most recent trace messages.
|
||||
</returns>
|
||||
</member>
|
||||
<member name="T:Newtonsoft.Json.Serialization.NamingStrategy">
|
||||
<summary>
|
||||
A base class for resolving how property names and dictionary keys are serialized.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:Newtonsoft.Json.Serialization.NamingStrategy.ProcessDictionaryKeys">
|
||||
<summary>
|
||||
A flag indicating whether dictionary keys should be processed.
|
||||
Defaults to <c>false</c>.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:Newtonsoft.Json.Serialization.NamingStrategy.OverrideSpecifiedNames">
|
||||
<summary>
|
||||
A flag indicating whether explicitly specified property names,
|
||||
e.g. a property name customized with a <see cref="T:Newtonsoft.Json.JsonPropertyAttribute"/>, should be processed.
|
||||
Defaults to <c>false</c>.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:Newtonsoft.Json.Serialization.NamingStrategy.GetPropertyName(System.String,System.Boolean)">
|
||||
<summary>
|
||||
Gets the serialized name for a given property name.
|
||||
</summary>
|
||||
<param name="name">The initial property name.</param>
|
||||
<param name="hasSpecifiedName">A flag indicating whether the property has had a name explicitly specfied.</param>
|
||||
<returns>The serialized property name.</returns>
|
||||
</member>
|
||||
<member name="M:Newtonsoft.Json.Serialization.NamingStrategy.GetDictionaryKey(System.String)">
|
||||
<summary>
|
||||
Gets the serialized key for a given dictionary key.
|
||||
</summary>
|
||||
<param name="key">The initial dictionary key.</param>
|
||||
<returns>The serialized dictionary key.</returns>
|
||||
</member>
|
||||
<member name="M:Newtonsoft.Json.Serialization.NamingStrategy.ResolvePropertyName(System.String)">
|
||||
<summary>
|
||||
Resolves the specified property name.
|
||||
</summary>
|
||||
<param name="name">The property name to resolve.</param>
|
||||
<returns>The resolved property name.</returns>
|
||||
</member>
|
||||
<member name="T:Newtonsoft.Json.Serialization.ReflectionAttributeProvider">
|
||||
<summary>
|
||||
Provides methods to get attributes from a <see cref="T:System.Type"/>, <see cref="T:System.Reflection.MemberInfo"/>, <see cref="T:System.Reflection.ParameterInfo"/> or <see cref="T:System.Reflection.Assembly"/>.
|
||||
@@ -4072,6 +4151,35 @@
|
||||
<param name="inherit">When true, look up the hierarchy chain for the inherited custom attribute.</param>
|
||||
<returns>A collection of <see cref="T:System.Attribute"/>s, or an empty collection.</returns>
|
||||
</member>
|
||||
<member name="T:Newtonsoft.Json.Serialization.SnakeCaseNamingStrategy">
|
||||
<summary>
|
||||
A snake case naming strategy.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:Newtonsoft.Json.Serialization.SnakeCaseNamingStrategy.#ctor(System.Boolean,System.Boolean)">
|
||||
<summary>
|
||||
Initializes a new instance of the <see cref="T:Newtonsoft.Json.Serialization.SnakeCaseNamingStrategy"/> class.
|
||||
</summary>
|
||||
<param name="processDictionaryKeys">
|
||||
A flag indicating whether dictionary keys should be processed.
|
||||
</param>
|
||||
<param name="overrideSpecifiedNames">
|
||||
A flag indicating whether explicitly specified property names should be processed,
|
||||
e.g. a property name customized with a <see cref="T:Newtonsoft.Json.JsonPropertyAttribute"/>.
|
||||
</param>
|
||||
</member>
|
||||
<member name="M:Newtonsoft.Json.Serialization.SnakeCaseNamingStrategy.#ctor">
|
||||
<summary>
|
||||
Initializes a new instance of the <see cref="T:Newtonsoft.Json.Serialization.SnakeCaseNamingStrategy"/> class.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:Newtonsoft.Json.Serialization.SnakeCaseNamingStrategy.ResolvePropertyName(System.String)">
|
||||
<summary>
|
||||
Resolves the specified property name.
|
||||
</summary>
|
||||
<param name="name">The property name to resolve.</param>
|
||||
<returns>The resolved property name.</returns>
|
||||
</member>
|
||||
<member name="T:Newtonsoft.Json.Serialization.JsonDynamicContract">
|
||||
<summary>
|
||||
Contract details for a <see cref="T:System.Type"/> used by the <see cref="T:Newtonsoft.Json.JsonSerializer"/>.
|
||||
@@ -4193,13 +4301,6 @@
|
||||
Initializes a new instance of the <see cref="T:Newtonsoft.Json.Serialization.CamelCasePropertyNamesContractResolver"/> class.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:Newtonsoft.Json.Serialization.CamelCasePropertyNamesContractResolver.ResolvePropertyName(System.String)">
|
||||
<summary>
|
||||
Resolves the name of the property.
|
||||
</summary>
|
||||
<param name="propertyName">Name of the property.</param>
|
||||
<returns>The property name camel cased.</returns>
|
||||
</member>
|
||||
<member name="T:Newtonsoft.Json.Serialization.DefaultContractResolver">
|
||||
<summary>
|
||||
Used by <see cref="T:Newtonsoft.Json.JsonSerializer"/> to resolves a <see cref="T:Newtonsoft.Json.Serialization.JsonContract"/> for a given <see cref="T:System.Type"/>.
|
||||
@@ -4244,6 +4345,12 @@
|
||||
<c>true</c> if the <see cref="T:System.SerializableAttribute"/> attribute will be ignored when serializing and deserializing types; otherwise, <c>false</c>.
|
||||
</value>
|
||||
</member>
|
||||
<member name="P:Newtonsoft.Json.Serialization.DefaultContractResolver.NamingStrategy">
|
||||
<summary>
|
||||
Gets or sets the naming strategy used to resolve how property names and dictionary keys are serialized.
|
||||
</summary>
|
||||
<value>The naming strategy used to resolve how property names and dictionary keys are serialized.</value>
|
||||
</member>
|
||||
<member name="M:Newtonsoft.Json.Serialization.DefaultContractResolver.#ctor">
|
||||
<summary>
|
||||
Initializes a new instance of the <see cref="T:Newtonsoft.Json.Serialization.DefaultContractResolver"/> class.
|
||||
@@ -5075,13 +5182,6 @@
|
||||
<param name="converterArgs">Optional arguments to pass to an initializing constructor of the JsonConverter.
|
||||
If null, the default constructor is used.</param>
|
||||
</member>
|
||||
<member name="M:Newtonsoft.Json.Serialization.JsonTypeReflector.GetJsonConverterCreator(System.Type)">
|
||||
<summary>
|
||||
Create a factory function that can be used to create instances of a JsonConverter described by the
|
||||
argument type. The returned function can then be used to either invoke the converter's default ctor, or any
|
||||
parameterized constructors by way of an object array.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:Newtonsoft.Json.Serialization.ReflectionValueProvider">
|
||||
<summary>
|
||||
Get and set values for a <see cref="T:System.Reflection.MemberInfo"/> using reflection.
|
||||
@@ -5211,16 +5311,6 @@
|
||||
<param name="initial">The list to add to.</param>
|
||||
<param name="collection">The collection of elements to add.</param>
|
||||
</member>
|
||||
<member name="M:Newtonsoft.Json.Utilities.CollectionUtils.IndexOf``1(System.Collections.Generic.IEnumerable{``0},``0,System.Collections.Generic.IEqualityComparer{``0})">
|
||||
<summary>
|
||||
Returns the index of the first occurrence in a sequence by using a specified IEqualityComparer{TSource}.
|
||||
</summary>
|
||||
<typeparam name="TSource">The type of the elements of source.</typeparam>
|
||||
<param name="list">A sequence in which to locate a value.</param>
|
||||
<param name="value">The object to locate in the sequence</param>
|
||||
<param name="comparer">An equality comparer to compare values.</param>
|
||||
<returns>The zero-based index of the first occurrence of value within the entire sequence, if found; otherwise, –1.</returns>
|
||||
</member>
|
||||
<member name="M:Newtonsoft.Json.Utilities.ReflectionUtils.GetCollectionItemType(System.Type)">
|
||||
<summary>
|
||||
Gets the type of the typed collection's items.
|
||||
@@ -5299,13 +5389,6 @@
|
||||
<c>true</c> if the string is all white space; otherwise, <c>false</c>.
|
||||
</returns>
|
||||
</member>
|
||||
<member name="M:Newtonsoft.Json.Utilities.StringUtils.NullEmptyString(System.String)">
|
||||
<summary>
|
||||
Nulls an empty string.
|
||||
</summary>
|
||||
<param name="s">The string.</param>
|
||||
<returns>Null if the string was null, otherwise the string unchanged.</returns>
|
||||
</member>
|
||||
<member name="T:Newtonsoft.Json.Required">
|
||||
<summary>
|
||||
Indicating whether a property is required.
|
||||
@@ -5438,21 +5521,38 @@
|
||||
</member>
|
||||
<member name="P:Newtonsoft.Json.JsonContainerAttribute.ItemConverterType">
|
||||
<summary>
|
||||
Gets the collection's items converter.
|
||||
Gets or sets the collection's items converter.
|
||||
</summary>
|
||||
<value>The collection's items converter.</value>
|
||||
</member>
|
||||
<member name="P:Newtonsoft.Json.JsonContainerAttribute.ItemConverterParameters">
|
||||
<summary>
|
||||
The parameter list to use when constructing the JsonConverter described by ItemConverterType.
|
||||
The parameter list to use when constructing the <see cref="T:Newtonsoft.Json.JsonConverter"/> described by ItemConverterType.
|
||||
If null, the default constructor is used.
|
||||
When non-null, there must be a constructor defined in the JsonConverter that exactly matches the number,
|
||||
When non-null, there must be a constructor defined in the <see cref="T:Newtonsoft.Json.JsonConverter"/> that exactly matches the number,
|
||||
order, and type of these parameters.
|
||||
</summary>
|
||||
<example>
|
||||
[JsonContainer(ItemConverterType = typeof(MyContainerConverter), ItemConverterParameters = new object[] { 123, "Four" })]
|
||||
</example>
|
||||
</member>
|
||||
<member name="P:Newtonsoft.Json.JsonContainerAttribute.NamingStrategyType">
|
||||
<summary>
|
||||
Gets or sets the <see cref="T:System.Type"/> of the <see cref="T:Newtonsoft.Json.Serialization.NamingStrategy"/>.
|
||||
</summary>
|
||||
<value>The <see cref="T:System.Type"/> of the <see cref="T:Newtonsoft.Json.Serialization.NamingStrategy"/>.</value>
|
||||
</member>
|
||||
<member name="P:Newtonsoft.Json.JsonContainerAttribute.NamingStrategyParameters">
|
||||
<summary>
|
||||
The parameter list to use when constructing the <see cref="T:Newtonsoft.Json.Serialization.NamingStrategy"/> described by NamingStrategyType.
|
||||
If null, the default constructor is used.
|
||||
When non-null, there must be a constructor defined in the <see cref="T:Newtonsoft.Json.Serialization.NamingStrategy"/> that exactly matches the number,
|
||||
order, and type of these parameters.
|
||||
</summary>
|
||||
<example>
|
||||
[JsonContainer(NamingStrategyType = typeof(MyNamingStrategy), NamingStrategyParameters = new object[] { 123, "Four" })]
|
||||
</example>
|
||||
</member>
|
||||
<member name="P:Newtonsoft.Json.JsonContainerAttribute.IsReference">
|
||||
<summary>
|
||||
Gets or sets a value that indicates whether to preserve object references.
|
||||
@@ -5534,13 +5634,13 @@
|
||||
</member>
|
||||
<member name="P:Newtonsoft.Json.JsonConverterAttribute.ConverterType">
|
||||
<summary>
|
||||
Gets the <see cref="T:System.Type"/> of the converter.
|
||||
Gets the <see cref="T:System.Type"/> of the <see cref="T:Newtonsoft.Json.JsonConverter"/>.
|
||||
</summary>
|
||||
<value>The <see cref="T:System.Type"/> of the converter.</value>
|
||||
<value>The <see cref="T:System.Type"/> of the <see cref="T:Newtonsoft.Json.JsonConverter"/>.</value>
|
||||
</member>
|
||||
<member name="P:Newtonsoft.Json.JsonConverterAttribute.ConverterParameters">
|
||||
<summary>
|
||||
The parameter list to use when constructing the JsonConverter described by ConverterType.
|
||||
The parameter list to use when constructing the <see cref="T:Newtonsoft.Json.JsonConverter"/> described by ConverterType.
|
||||
If null, the default constructor is used.
|
||||
</summary>
|
||||
</member>
|
||||
@@ -5548,14 +5648,14 @@
|
||||
<summary>
|
||||
Initializes a new instance of the <see cref="T:Newtonsoft.Json.JsonConverterAttribute"/> class.
|
||||
</summary>
|
||||
<param name="converterType">Type of the converter.</param>
|
||||
<param name="converterType">Type of the <see cref="T:Newtonsoft.Json.JsonConverter"/>.</param>
|
||||
</member>
|
||||
<member name="M:Newtonsoft.Json.JsonConverterAttribute.#ctor(System.Type,System.Object[])">
|
||||
<summary>
|
||||
Initializes a new instance of the <see cref="T:Newtonsoft.Json.JsonConverterAttribute"/> class.
|
||||
</summary>
|
||||
<param name="converterType">Type of the converter.</param>
|
||||
<param name="converterParameters">Parameter list to use when constructing the JsonConverter. Can be null.</param>
|
||||
<param name="converterType">Type of the <see cref="T:Newtonsoft.Json.JsonConverter"/>.</param>
|
||||
<param name="converterParameters">Parameter list to use when constructing the <see cref="T:Newtonsoft.Json.JsonConverter"/>. Can be null.</param>
|
||||
</member>
|
||||
<member name="T:Newtonsoft.Json.JsonObjectAttribute">
|
||||
<summary>
|
||||
@@ -5907,7 +6007,7 @@
|
||||
Reads the next JSON token from the stream.
|
||||
</summary>
|
||||
<returns>
|
||||
true if the next token was read successfully; false if there are no more tokens to read.
|
||||
<c>true</c> if the next token was read successfully; <c>false</c> if there are no more tokens to read.
|
||||
</returns>
|
||||
</member>
|
||||
<member name="T:Newtonsoft.Json.MemberSerialization">
|
||||
@@ -5975,7 +6075,7 @@
|
||||
Reads the next JSON token from the stream.
|
||||
</summary>
|
||||
<returns>
|
||||
true if the next token was read successfully; false if there are no more tokens to read.
|
||||
<c>true</c> if the next token was read successfully; <c>false</c> if there are no more tokens to read.
|
||||
</returns>
|
||||
</member>
|
||||
<member name="M:Newtonsoft.Json.JsonTextReader.ReadAsInt32">
|
||||
@@ -6062,21 +6162,38 @@
|
||||
</member>
|
||||
<member name="P:Newtonsoft.Json.JsonPropertyAttribute.ItemConverterType">
|
||||
<summary>
|
||||
Gets or sets the converter used when serializing the property's collection items.
|
||||
Gets or sets the <see cref="T:Newtonsoft.Json.JsonConverter"/> used when serializing the property's collection items.
|
||||
</summary>
|
||||
<value>The collection's items converter.</value>
|
||||
<value>The collection's items <see cref="T:Newtonsoft.Json.JsonConverter"/>.</value>
|
||||
</member>
|
||||
<member name="P:Newtonsoft.Json.JsonPropertyAttribute.ItemConverterParameters">
|
||||
<summary>
|
||||
The parameter list to use when constructing the JsonConverter described by ItemConverterType.
|
||||
The parameter list to use when constructing the <see cref="T:Newtonsoft.Json.JsonConverter"/> described by ItemConverterType.
|
||||
If null, the default constructor is used.
|
||||
When non-null, there must be a constructor defined in the JsonConverter that exactly matches the number,
|
||||
When non-null, there must be a constructor defined in the <see cref="T:Newtonsoft.Json.JsonConverter"/> that exactly matches the number,
|
||||
order, and type of these parameters.
|
||||
</summary>
|
||||
<example>
|
||||
[JsonProperty(ItemConverterType = typeof(MyContainerConverter), ItemConverterParameters = new object[] { 123, "Four" })]
|
||||
</example>
|
||||
</member>
|
||||
<member name="P:Newtonsoft.Json.JsonPropertyAttribute.NamingStrategyType">
|
||||
<summary>
|
||||
Gets or sets the <see cref="T:System.Type"/> of the <see cref="T:Newtonsoft.Json.Serialization.NamingStrategy"/>.
|
||||
</summary>
|
||||
<value>The <see cref="T:System.Type"/> of the <see cref="T:Newtonsoft.Json.Serialization.NamingStrategy"/>.</value>
|
||||
</member>
|
||||
<member name="P:Newtonsoft.Json.JsonPropertyAttribute.NamingStrategyParameters">
|
||||
<summary>
|
||||
The parameter list to use when constructing the <see cref="T:Newtonsoft.Json.Serialization.NamingStrategy"/> described by NamingStrategyType.
|
||||
If null, the default constructor is used.
|
||||
When non-null, there must be a constructor defined in the <see cref="T:Newtonsoft.Json.Serialization.NamingStrategy"/> that exactly matches the number,
|
||||
order, and type of these parameters.
|
||||
</summary>
|
||||
<example>
|
||||
[JsonProperty(NamingStrategyType = typeof(MyNamingStrategy), NamingStrategyParameters = new object[] { 123, "Four" })]
|
||||
</example>
|
||||
</member>
|
||||
<member name="P:Newtonsoft.Json.JsonPropertyAttribute.NullValueHandling">
|
||||
<summary>
|
||||
Gets or sets the null value handling used when serializing this property.
|
||||
@@ -6752,7 +6869,7 @@
|
||||
<summary>
|
||||
Reads the next JSON token from the stream.
|
||||
</summary>
|
||||
<returns>true if the next token was read successfully; false if there are no more tokens to read.</returns>
|
||||
<returns><c>true</c> if the next token was read successfully; <c>false</c> if there are no more tokens to read.</returns>
|
||||
</member>
|
||||
<member name="M:Newtonsoft.Json.JsonReader.ReadAsInt32">
|
||||
<summary>
|
||||
Binary file not shown.
@@ -81,7 +81,7 @@
|
||||
Reads the next JSON token from the stream.
|
||||
</summary>
|
||||
<returns>
|
||||
true if the next token was read successfully; false if there are no more tokens to read.
|
||||
<c>true</c> if the next token was read successfully; <c>false</c> if there are no more tokens to read.
|
||||
</returns>
|
||||
</member>
|
||||
<member name="M:Newtonsoft.Json.Bson.BsonReader.Close">
|
||||
@@ -326,12 +326,12 @@
|
||||
</member>
|
||||
<member name="F:Newtonsoft.Json.ConstructorHandling.Default">
|
||||
<summary>
|
||||
First attempt to use the public default constructor, then fall back to single paramatized constructor, then the non-public default constructor.
|
||||
First attempt to use the public default constructor, then fall back to single parameterized constructor, then the non-public default constructor.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="F:Newtonsoft.Json.ConstructorHandling.AllowNonPublicDefaultConstructor">
|
||||
<summary>
|
||||
Json.NET will use a non-public default constructor before falling back to a paramatized constructor.
|
||||
Json.NET will use a non-public default constructor before falling back to a parameterized constructor.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:Newtonsoft.Json.Converters.BinaryConverter">
|
||||
@@ -891,7 +891,7 @@
|
||||
</summary>
|
||||
<param name="attributeName">Attribute name to test.</param>
|
||||
<param name="prefix">The attribute name prefix if it has one, otherwise an empty string.</param>
|
||||
<returns>True if attribute name is for a namespace attribute, otherwise false.</returns>
|
||||
<returns><c>true</c> if attribute name is for a namespace attribute, otherwise <c>false</c>.</returns>
|
||||
</member>
|
||||
<member name="M:Newtonsoft.Json.Converters.XmlNodeConverter.CanConvert(System.Type)">
|
||||
<summary>
|
||||
@@ -1152,21 +1152,38 @@
|
||||
</member>
|
||||
<member name="P:Newtonsoft.Json.JsonContainerAttribute.ItemConverterType">
|
||||
<summary>
|
||||
Gets the collection's items converter.
|
||||
Gets or sets the collection's items converter.
|
||||
</summary>
|
||||
<value>The collection's items converter.</value>
|
||||
</member>
|
||||
<member name="P:Newtonsoft.Json.JsonContainerAttribute.ItemConverterParameters">
|
||||
<summary>
|
||||
The parameter list to use when constructing the JsonConverter described by ItemConverterType.
|
||||
The parameter list to use when constructing the <see cref="T:Newtonsoft.Json.JsonConverter"/> described by ItemConverterType.
|
||||
If null, the default constructor is used.
|
||||
When non-null, there must be a constructor defined in the JsonConverter that exactly matches the number,
|
||||
When non-null, there must be a constructor defined in the <see cref="T:Newtonsoft.Json.JsonConverter"/> that exactly matches the number,
|
||||
order, and type of these parameters.
|
||||
</summary>
|
||||
<example>
|
||||
[JsonContainer(ItemConverterType = typeof(MyContainerConverter), ItemConverterParameters = new object[] { 123, "Four" })]
|
||||
</example>
|
||||
</member>
|
||||
<member name="P:Newtonsoft.Json.JsonContainerAttribute.NamingStrategyType">
|
||||
<summary>
|
||||
Gets or sets the <see cref="T:System.Type"/> of the <see cref="T:Newtonsoft.Json.Serialization.NamingStrategy"/>.
|
||||
</summary>
|
||||
<value>The <see cref="T:System.Type"/> of the <see cref="T:Newtonsoft.Json.Serialization.NamingStrategy"/>.</value>
|
||||
</member>
|
||||
<member name="P:Newtonsoft.Json.JsonContainerAttribute.NamingStrategyParameters">
|
||||
<summary>
|
||||
The parameter list to use when constructing the <see cref="T:Newtonsoft.Json.Serialization.NamingStrategy"/> described by NamingStrategyType.
|
||||
If null, the default constructor is used.
|
||||
When non-null, there must be a constructor defined in the <see cref="T:Newtonsoft.Json.Serialization.NamingStrategy"/> that exactly matches the number,
|
||||
order, and type of these parameters.
|
||||
</summary>
|
||||
<example>
|
||||
[JsonContainer(NamingStrategyType = typeof(MyNamingStrategy), NamingStrategyParameters = new object[] { 123, "Four" })]
|
||||
</example>
|
||||
</member>
|
||||
<member name="P:Newtonsoft.Json.JsonContainerAttribute.IsReference">
|
||||
<summary>
|
||||
Gets or sets a value that indicates whether to preserve object references.
|
||||
@@ -1918,13 +1935,13 @@
|
||||
</member>
|
||||
<member name="P:Newtonsoft.Json.JsonConverterAttribute.ConverterType">
|
||||
<summary>
|
||||
Gets the <see cref="T:System.Type"/> of the converter.
|
||||
Gets the <see cref="T:System.Type"/> of the <see cref="T:Newtonsoft.Json.JsonConverter"/>.
|
||||
</summary>
|
||||
<value>The <see cref="T:System.Type"/> of the converter.</value>
|
||||
<value>The <see cref="T:System.Type"/> of the <see cref="T:Newtonsoft.Json.JsonConverter"/>.</value>
|
||||
</member>
|
||||
<member name="P:Newtonsoft.Json.JsonConverterAttribute.ConverterParameters">
|
||||
<summary>
|
||||
The parameter list to use when constructing the JsonConverter described by ConverterType.
|
||||
The parameter list to use when constructing the <see cref="T:Newtonsoft.Json.JsonConverter"/> described by ConverterType.
|
||||
If null, the default constructor is used.
|
||||
</summary>
|
||||
</member>
|
||||
@@ -1932,14 +1949,14 @@
|
||||
<summary>
|
||||
Initializes a new instance of the <see cref="T:Newtonsoft.Json.JsonConverterAttribute"/> class.
|
||||
</summary>
|
||||
<param name="converterType">Type of the converter.</param>
|
||||
<param name="converterType">Type of the <see cref="T:Newtonsoft.Json.JsonConverter"/>.</param>
|
||||
</member>
|
||||
<member name="M:Newtonsoft.Json.JsonConverterAttribute.#ctor(System.Type,System.Object[])">
|
||||
<summary>
|
||||
Initializes a new instance of the <see cref="T:Newtonsoft.Json.JsonConverterAttribute"/> class.
|
||||
</summary>
|
||||
<param name="converterType">Type of the converter.</param>
|
||||
<param name="converterParameters">Parameter list to use when constructing the JsonConverter. Can be null.</param>
|
||||
<param name="converterType">Type of the <see cref="T:Newtonsoft.Json.JsonConverter"/>.</param>
|
||||
<param name="converterParameters">Parameter list to use when constructing the <see cref="T:Newtonsoft.Json.JsonConverter"/>. Can be null.</param>
|
||||
</member>
|
||||
<member name="T:Newtonsoft.Json.JsonConverterCollection">
|
||||
<summary>
|
||||
@@ -2071,21 +2088,38 @@
|
||||
</member>
|
||||
<member name="P:Newtonsoft.Json.JsonPropertyAttribute.ItemConverterType">
|
||||
<summary>
|
||||
Gets or sets the converter used when serializing the property's collection items.
|
||||
Gets or sets the <see cref="T:Newtonsoft.Json.JsonConverter"/> used when serializing the property's collection items.
|
||||
</summary>
|
||||
<value>The collection's items converter.</value>
|
||||
<value>The collection's items <see cref="T:Newtonsoft.Json.JsonConverter"/>.</value>
|
||||
</member>
|
||||
<member name="P:Newtonsoft.Json.JsonPropertyAttribute.ItemConverterParameters">
|
||||
<summary>
|
||||
The parameter list to use when constructing the JsonConverter described by ItemConverterType.
|
||||
The parameter list to use when constructing the <see cref="T:Newtonsoft.Json.JsonConverter"/> described by ItemConverterType.
|
||||
If null, the default constructor is used.
|
||||
When non-null, there must be a constructor defined in the JsonConverter that exactly matches the number,
|
||||
When non-null, there must be a constructor defined in the <see cref="T:Newtonsoft.Json.JsonConverter"/> that exactly matches the number,
|
||||
order, and type of these parameters.
|
||||
</summary>
|
||||
<example>
|
||||
[JsonProperty(ItemConverterType = typeof(MyContainerConverter), ItemConverterParameters = new object[] { 123, "Four" })]
|
||||
</example>
|
||||
</member>
|
||||
<member name="P:Newtonsoft.Json.JsonPropertyAttribute.NamingStrategyType">
|
||||
<summary>
|
||||
Gets or sets the <see cref="T:System.Type"/> of the <see cref="T:Newtonsoft.Json.Serialization.NamingStrategy"/>.
|
||||
</summary>
|
||||
<value>The <see cref="T:System.Type"/> of the <see cref="T:Newtonsoft.Json.Serialization.NamingStrategy"/>.</value>
|
||||
</member>
|
||||
<member name="P:Newtonsoft.Json.JsonPropertyAttribute.NamingStrategyParameters">
|
||||
<summary>
|
||||
The parameter list to use when constructing the <see cref="T:Newtonsoft.Json.Serialization.NamingStrategy"/> described by NamingStrategyType.
|
||||
If null, the default constructor is used.
|
||||
When non-null, there must be a constructor defined in the <see cref="T:Newtonsoft.Json.Serialization.NamingStrategy"/> that exactly matches the number,
|
||||
order, and type of these parameters.
|
||||
</summary>
|
||||
<example>
|
||||
[JsonProperty(NamingStrategyType = typeof(MyNamingStrategy), NamingStrategyParameters = new object[] { 123, "Four" })]
|
||||
</example>
|
||||
</member>
|
||||
<member name="P:Newtonsoft.Json.JsonPropertyAttribute.NullValueHandling">
|
||||
<summary>
|
||||
Gets or sets the null value handling used when serializing this property.
|
||||
@@ -2341,7 +2375,7 @@
|
||||
<summary>
|
||||
Reads the next JSON token from the stream.
|
||||
</summary>
|
||||
<returns>true if the next token was read successfully; false if there are no more tokens to read.</returns>
|
||||
<returns><c>true</c> if the next token was read successfully; <c>false</c> if there are no more tokens to read.</returns>
|
||||
</member>
|
||||
<member name="M:Newtonsoft.Json.JsonReader.ReadAsInt32">
|
||||
<summary>
|
||||
@@ -3047,7 +3081,7 @@
|
||||
Reads the next JSON token from the stream.
|
||||
</summary>
|
||||
<returns>
|
||||
true if the next token was read successfully; false if there are no more tokens to read.
|
||||
<c>true</c> if the next token was read successfully; <c>false</c> if there are no more tokens to read.
|
||||
</returns>
|
||||
</member>
|
||||
<member name="M:Newtonsoft.Json.JsonTextReader.ReadAsInt32">
|
||||
@@ -3609,7 +3643,7 @@
|
||||
Reads the next JSON token from the stream.
|
||||
</summary>
|
||||
<returns>
|
||||
true if the next token was read successfully; false if there are no more tokens to read.
|
||||
<c>true</c> if the next token was read successfully; <c>false</c> if there are no more tokens to read.
|
||||
</returns>
|
||||
</member>
|
||||
<member name="T:Newtonsoft.Json.JsonWriter">
|
||||
@@ -4936,7 +4970,7 @@
|
||||
<param name="propertyName">Name of the property.</param>
|
||||
<param name="value">The value.</param>
|
||||
<param name="comparison">One of the enumeration values that specifies how the strings will be compared.</param>
|
||||
<returns>true if a value was successfully retrieved; otherwise, false.</returns>
|
||||
<returns><c>true</c> if a value was successfully retrieved; otherwise, <c>false</c>.</returns>
|
||||
</member>
|
||||
<member name="M:Newtonsoft.Json.Linq.JObject.Add(System.String,Newtonsoft.Json.Linq.JToken)">
|
||||
<summary>
|
||||
@@ -4950,7 +4984,7 @@
|
||||
Removes the property with the specified name.
|
||||
</summary>
|
||||
<param name="propertyName">Name of the property.</param>
|
||||
<returns>true if item was successfully removed; otherwise, false.</returns>
|
||||
<returns><c>true</c> if item was successfully removed; otherwise, <c>false</c>.</returns>
|
||||
</member>
|
||||
<member name="M:Newtonsoft.Json.Linq.JObject.TryGetValue(System.String,Newtonsoft.Json.Linq.JToken@)">
|
||||
<summary>
|
||||
@@ -4958,7 +4992,7 @@
|
||||
</summary>
|
||||
<param name="propertyName">Name of the property.</param>
|
||||
<param name="value">The value.</param>
|
||||
<returns>true if a value was successfully retrieved; otherwise, false.</returns>
|
||||
<returns><c>true</c> if a value was successfully retrieved; otherwise, <c>false</c>.</returns>
|
||||
</member>
|
||||
<member name="M:Newtonsoft.Json.Linq.JObject.GetEnumerator">
|
||||
<summary>
|
||||
@@ -5194,10 +5228,9 @@
|
||||
When overridden in a derived class, returns whether resetting an object changes its value.
|
||||
</summary>
|
||||
<returns>
|
||||
true if resetting the component changes its value; otherwise, false.
|
||||
<c>true</c> if resetting the component changes its value; otherwise, <c>false</c>.
|
||||
</returns>
|
||||
<param name="component">The component to test for reset capability.
|
||||
</param>
|
||||
<param name="component">The component to test for reset capability.</param>
|
||||
</member>
|
||||
<member name="M:Newtonsoft.Json.Linq.JPropertyDescriptor.GetValue(System.Object)">
|
||||
<summary>
|
||||
@@ -5229,10 +5262,9 @@
|
||||
When overridden in a derived class, determines a value indicating whether the value of this property needs to be persisted.
|
||||
</summary>
|
||||
<returns>
|
||||
true if the property should be persisted; otherwise, false.
|
||||
<c>true</c> if the property should be persisted; otherwise, <c>false</c>.
|
||||
</returns>
|
||||
<param name="component">The component with the property to be examined for persistence.
|
||||
</param>
|
||||
<param name="component">The component with the property to be examined for persistence.</param>
|
||||
</member>
|
||||
<member name="P:Newtonsoft.Json.Linq.JPropertyDescriptor.ComponentType">
|
||||
<summary>
|
||||
@@ -5247,7 +5279,7 @@
|
||||
When overridden in a derived class, gets a value indicating whether this property is read-only.
|
||||
</summary>
|
||||
<returns>
|
||||
true if the property is read-only; otherwise, false.
|
||||
<c>true</c> if the property is read-only; otherwise, <c>false</c>.
|
||||
</returns>
|
||||
</member>
|
||||
<member name="P:Newtonsoft.Json.Linq.JPropertyDescriptor.PropertyType">
|
||||
@@ -5334,7 +5366,7 @@
|
||||
</summary>
|
||||
<param name="t1">The first <see cref="T:Newtonsoft.Json.Linq.JToken"/> to compare.</param>
|
||||
<param name="t2">The second <see cref="T:Newtonsoft.Json.Linq.JToken"/> to compare.</param>
|
||||
<returns>true if the tokens are equal; otherwise false.</returns>
|
||||
<returns><c>true</c> if the tokens are equal; otherwise <c>false</c>.</returns>
|
||||
</member>
|
||||
<member name="P:Newtonsoft.Json.Linq.JToken.Next">
|
||||
<summary>
|
||||
@@ -6208,7 +6240,7 @@
|
||||
<param name="x">The first object of type <see cref="T:Newtonsoft.Json.Linq.JToken"/> to compare.</param>
|
||||
<param name="y">The second object of type <see cref="T:Newtonsoft.Json.Linq.JToken"/> to compare.</param>
|
||||
<returns>
|
||||
true if the specified objects are equal; otherwise, false.
|
||||
<c>true</c> if the specified objects are equal; otherwise, <c>false</c>.
|
||||
</returns>
|
||||
</member>
|
||||
<member name="M:Newtonsoft.Json.Linq.JTokenEqualityComparer.GetHashCode(Newtonsoft.Json.Linq.JToken)">
|
||||
@@ -6240,7 +6272,7 @@
|
||||
Reads the next JSON token from the stream.
|
||||
</summary>
|
||||
<returns>
|
||||
true if the next token was read successfully; false if there are no more tokens to read.
|
||||
<c>true</c> if the next token was read successfully; <c>false</c> if there are no more tokens to read.
|
||||
</returns>
|
||||
</member>
|
||||
<member name="P:Newtonsoft.Json.Linq.JTokenReader.Path">
|
||||
@@ -6710,7 +6742,7 @@
|
||||
Indicates whether the current object is equal to another object of the same type.
|
||||
</summary>
|
||||
<returns>
|
||||
true if the current object is equal to the <paramref name="other"/> parameter; otherwise, false.
|
||||
<c>true</c> if the current object is equal to the <paramref name="other"/> parameter; otherwise, <c>false</c>.
|
||||
</returns>
|
||||
<param name="other">An object to compare with this object.</param>
|
||||
</member>
|
||||
@@ -6720,7 +6752,7 @@
|
||||
</summary>
|
||||
<param name="obj">The <see cref="T:System.Object"/> to compare with the current <see cref="T:System.Object"/>.</param>
|
||||
<returns>
|
||||
true if the specified <see cref="T:System.Object"/> is equal to the current <see cref="T:System.Object"/>; otherwise, false.
|
||||
<c>true</c> if the specified <see cref="T:System.Object"/> is equal to the current <see cref="T:System.Object"/>; otherwise, <c>false</c>.
|
||||
</returns>
|
||||
<exception cref="T:System.NullReferenceException">
|
||||
The <paramref name="obj"/> parameter is null.
|
||||
@@ -7604,6 +7636,64 @@
|
||||
</note>
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:Newtonsoft.Json.Serialization.SnakeCaseNamingStrategy">
|
||||
<summary>
|
||||
A snake case naming strategy.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:Newtonsoft.Json.Serialization.SnakeCaseNamingStrategy.#ctor(System.Boolean,System.Boolean)">
|
||||
<summary>
|
||||
Initializes a new instance of the <see cref="T:Newtonsoft.Json.Serialization.SnakeCaseNamingStrategy"/> class.
|
||||
</summary>
|
||||
<param name="processDictionaryKeys">
|
||||
A flag indicating whether dictionary keys should be processed.
|
||||
</param>
|
||||
<param name="overrideSpecifiedNames">
|
||||
A flag indicating whether explicitly specified property names should be processed,
|
||||
e.g. a property name customized with a <see cref="T:Newtonsoft.Json.JsonPropertyAttribute"/>.
|
||||
</param>
|
||||
</member>
|
||||
<member name="M:Newtonsoft.Json.Serialization.SnakeCaseNamingStrategy.#ctor">
|
||||
<summary>
|
||||
Initializes a new instance of the <see cref="T:Newtonsoft.Json.Serialization.SnakeCaseNamingStrategy"/> class.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:Newtonsoft.Json.Serialization.SnakeCaseNamingStrategy.ResolvePropertyName(System.String)">
|
||||
<summary>
|
||||
Resolves the specified property name.
|
||||
</summary>
|
||||
<param name="name">The property name to resolve.</param>
|
||||
<returns>The resolved property name.</returns>
|
||||
</member>
|
||||
<member name="T:Newtonsoft.Json.Serialization.CamelCaseNamingStrategy">
|
||||
<summary>
|
||||
A camel case naming strategy.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:Newtonsoft.Json.Serialization.CamelCaseNamingStrategy.#ctor(System.Boolean,System.Boolean)">
|
||||
<summary>
|
||||
Initializes a new instance of the <see cref="T:Newtonsoft.Json.Serialization.CamelCaseNamingStrategy"/> class.
|
||||
</summary>
|
||||
<param name="processDictionaryKeys">
|
||||
A flag indicating whether dictionary keys should be processed.
|
||||
</param>
|
||||
<param name="overrideSpecifiedNames">
|
||||
A flag indicating whether explicitly specified property names should be processed,
|
||||
e.g. a property name customized with a <see cref="T:Newtonsoft.Json.JsonPropertyAttribute"/>.
|
||||
</param>
|
||||
</member>
|
||||
<member name="M:Newtonsoft.Json.Serialization.CamelCaseNamingStrategy.#ctor">
|
||||
<summary>
|
||||
Initializes a new instance of the <see cref="T:Newtonsoft.Json.Serialization.CamelCaseNamingStrategy"/> class.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:Newtonsoft.Json.Serialization.CamelCaseNamingStrategy.ResolvePropertyName(System.String)">
|
||||
<summary>
|
||||
Resolves the specified property name.
|
||||
</summary>
|
||||
<param name="name">The property name to resolve.</param>
|
||||
<returns>The resolved property name.</returns>
|
||||
</member>
|
||||
<member name="T:Newtonsoft.Json.Serialization.CamelCasePropertyNamesContractResolver">
|
||||
<summary>
|
||||
Resolves member mappings for a type, camel casing property names.
|
||||
@@ -7614,13 +7704,6 @@
|
||||
Initializes a new instance of the <see cref="T:Newtonsoft.Json.Serialization.CamelCasePropertyNamesContractResolver"/> class.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:Newtonsoft.Json.Serialization.CamelCasePropertyNamesContractResolver.ResolvePropertyName(System.String)">
|
||||
<summary>
|
||||
Resolves the name of the property.
|
||||
</summary>
|
||||
<param name="propertyName">Name of the property.</param>
|
||||
<returns>The property name camel cased.</returns>
|
||||
</member>
|
||||
<member name="T:Newtonsoft.Json.Serialization.DefaultContractResolver">
|
||||
<summary>
|
||||
Used by <see cref="T:Newtonsoft.Json.JsonSerializer"/> to resolves a <see cref="T:Newtonsoft.Json.Serialization.JsonContract"/> for a given <see cref="T:System.Type"/>.
|
||||
@@ -7665,6 +7748,12 @@
|
||||
<c>true</c> if the <see cref="T:System.SerializableAttribute"/> attribute will be ignored when serializing and deserializing types; otherwise, <c>false</c>.
|
||||
</value>
|
||||
</member>
|
||||
<member name="P:Newtonsoft.Json.Serialization.DefaultContractResolver.NamingStrategy">
|
||||
<summary>
|
||||
Gets or sets the naming strategy used to resolve how property names and dictionary keys are serialized.
|
||||
</summary>
|
||||
<value>The naming strategy used to resolve how property names and dictionary keys are serialized.</value>
|
||||
</member>
|
||||
<member name="M:Newtonsoft.Json.Serialization.DefaultContractResolver.#ctor">
|
||||
<summary>
|
||||
Initializes a new instance of the <see cref="T:Newtonsoft.Json.Serialization.DefaultContractResolver"/> class.
|
||||
@@ -7825,6 +7914,18 @@
|
||||
<param name="propertyName">Name of the property.</param>
|
||||
<returns>Name of the property.</returns>
|
||||
</member>
|
||||
<member name="T:Newtonsoft.Json.Serialization.DefaultNamingStrategy">
|
||||
<summary>
|
||||
The default naming strategy. Property names and dictionary keys are unchanged.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:Newtonsoft.Json.Serialization.DefaultNamingStrategy.ResolvePropertyName(System.String)">
|
||||
<summary>
|
||||
Resolves the specified property name.
|
||||
</summary>
|
||||
<param name="name">The property name to resolve.</param>
|
||||
<returns>The resolved property name.</returns>
|
||||
</member>
|
||||
<member name="T:Newtonsoft.Json.Serialization.DefaultSerializationBinder">
|
||||
<summary>
|
||||
The default serialization binder used when resolving and loading classes from type names.
|
||||
@@ -8016,6 +8117,46 @@
|
||||
<param name="type">The type to resolve a contract for.</param>
|
||||
<returns>The contract for a given type.</returns>
|
||||
</member>
|
||||
<member name="T:Newtonsoft.Json.Serialization.NamingStrategy">
|
||||
<summary>
|
||||
A base class for resolving how property names and dictionary keys are serialized.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:Newtonsoft.Json.Serialization.NamingStrategy.ProcessDictionaryKeys">
|
||||
<summary>
|
||||
A flag indicating whether dictionary keys should be processed.
|
||||
Defaults to <c>false</c>.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:Newtonsoft.Json.Serialization.NamingStrategy.OverrideSpecifiedNames">
|
||||
<summary>
|
||||
A flag indicating whether explicitly specified property names,
|
||||
e.g. a property name customized with a <see cref="T:Newtonsoft.Json.JsonPropertyAttribute"/>, should be processed.
|
||||
Defaults to <c>false</c>.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:Newtonsoft.Json.Serialization.NamingStrategy.GetPropertyName(System.String,System.Boolean)">
|
||||
<summary>
|
||||
Gets the serialized name for a given property name.
|
||||
</summary>
|
||||
<param name="name">The initial property name.</param>
|
||||
<param name="hasSpecifiedName">A flag indicating whether the property has had a name explicitly specfied.</param>
|
||||
<returns>The serialized property name.</returns>
|
||||
</member>
|
||||
<member name="M:Newtonsoft.Json.Serialization.NamingStrategy.GetDictionaryKey(System.String)">
|
||||
<summary>
|
||||
Gets the serialized key for a given dictionary key.
|
||||
</summary>
|
||||
<param name="key">The initial dictionary key.</param>
|
||||
<returns>The serialized dictionary key.</returns>
|
||||
</member>
|
||||
<member name="M:Newtonsoft.Json.Serialization.NamingStrategy.ResolvePropertyName(System.String)">
|
||||
<summary>
|
||||
Resolves the specified property name.
|
||||
</summary>
|
||||
<param name="name">The property name to resolve.</param>
|
||||
<returns>The resolved property name.</returns>
|
||||
</member>
|
||||
<member name="T:Newtonsoft.Json.Serialization.IReferenceResolver">
|
||||
<summary>
|
||||
Used to resolve references when serializing and deserializing JSON by the <see cref="T:Newtonsoft.Json.JsonSerializer"/>.
|
||||
@@ -8731,13 +8872,6 @@
|
||||
<param name="converterArgs">Optional arguments to pass to an initializing constructor of the JsonConverter.
|
||||
If null, the default constructor is used.</param>
|
||||
</member>
|
||||
<member name="M:Newtonsoft.Json.Serialization.JsonTypeReflector.GetJsonConverterCreator(System.Type)">
|
||||
<summary>
|
||||
Create a factory function that can be used to create instances of a JsonConverter described by the
|
||||
argument type. The returned function can then be used to either invoke the converter's default ctor, or any
|
||||
parameterized constructors by way of an object array.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:Newtonsoft.Json.Serialization.MemoryTraceWriter">
|
||||
<summary>
|
||||
Represents a trace writer that writes to memory. When the trace message limit is
|
||||
@@ -8914,16 +9048,6 @@
|
||||
<param name="initial">The list to add to.</param>
|
||||
<param name="collection">The collection of elements to add.</param>
|
||||
</member>
|
||||
<member name="M:Newtonsoft.Json.Utilities.CollectionUtils.IndexOf``1(System.Collections.Generic.IEnumerable{``0},``0,System.Collections.Generic.IEqualityComparer{``0})">
|
||||
<summary>
|
||||
Returns the index of the first occurrence in a sequence by using a specified IEqualityComparer{TSource}.
|
||||
</summary>
|
||||
<typeparam name="TSource">The type of the elements of source.</typeparam>
|
||||
<param name="list">A sequence in which to locate a value.</param>
|
||||
<param name="value">The object to locate in the sequence</param>
|
||||
<param name="comparer">An equality comparer to compare values.</param>
|
||||
<returns>The zero-based index of the first occurrence of value within the entire sequence, if found; otherwise, –1.</returns>
|
||||
</member>
|
||||
<member name="M:Newtonsoft.Json.Utilities.ConvertUtils.ConvertOrCast(System.Object,System.Globalization.CultureInfo,System.Type)">
|
||||
<summary>
|
||||
Converts the value to the specified type. If the value is unable to be converted, the
|
||||
@@ -9059,13 +9183,6 @@
|
||||
<c>true</c> if the string is all white space; otherwise, <c>false</c>.
|
||||
</returns>
|
||||
</member>
|
||||
<member name="M:Newtonsoft.Json.Utilities.StringUtils.NullEmptyString(System.String)">
|
||||
<summary>
|
||||
Nulls an empty string.
|
||||
</summary>
|
||||
<param name="s">The string.</param>
|
||||
<returns>Null if the string was null, otherwise the string unchanged.</returns>
|
||||
</member>
|
||||
<member name="T:Newtonsoft.Json.WriteState">
|
||||
<summary>
|
||||
Specifies the state of the <see cref="T:Newtonsoft.Json.JsonWriter"/>.
|
||||
BIN
packages/Newtonsoft.Json.9.0.1-beta1/lib/netstandard1.0/Newtonsoft.Json.dll
vendored
Normal file
BIN
packages/Newtonsoft.Json.9.0.1-beta1/lib/netstandard1.0/Newtonsoft.Json.dll
vendored
Normal file
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
@@ -81,7 +81,7 @@
|
||||
Reads the next JSON token from the stream.
|
||||
</summary>
|
||||
<returns>
|
||||
true if the next token was read successfully; false if there are no more tokens to read.
|
||||
<c>true</c> if the next token was read successfully; <c>false</c> if there are no more tokens to read.
|
||||
</returns>
|
||||
</member>
|
||||
<member name="M:Newtonsoft.Json.Bson.BsonReader.Close">
|
||||
@@ -326,12 +326,12 @@
|
||||
</member>
|
||||
<member name="F:Newtonsoft.Json.ConstructorHandling.Default">
|
||||
<summary>
|
||||
First attempt to use the public default constructor, then fall back to single paramatized constructor, then the non-public default constructor.
|
||||
First attempt to use the public default constructor, then fall back to single parameterized constructor, then the non-public default constructor.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="F:Newtonsoft.Json.ConstructorHandling.AllowNonPublicDefaultConstructor">
|
||||
<summary>
|
||||
Json.NET will use a non-public default constructor before falling back to a paramatized constructor.
|
||||
Json.NET will use a non-public default constructor before falling back to a parameterized constructor.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:Newtonsoft.Json.Converters.BsonObjectIdConverter">
|
||||
@@ -925,21 +925,38 @@
|
||||
</member>
|
||||
<member name="P:Newtonsoft.Json.JsonContainerAttribute.ItemConverterType">
|
||||
<summary>
|
||||
Gets the collection's items converter.
|
||||
Gets or sets the collection's items converter.
|
||||
</summary>
|
||||
<value>The collection's items converter.</value>
|
||||
</member>
|
||||
<member name="P:Newtonsoft.Json.JsonContainerAttribute.ItemConverterParameters">
|
||||
<summary>
|
||||
The parameter list to use when constructing the JsonConverter described by ItemConverterType.
|
||||
The parameter list to use when constructing the <see cref="T:Newtonsoft.Json.JsonConverter"/> described by ItemConverterType.
|
||||
If null, the default constructor is used.
|
||||
When non-null, there must be a constructor defined in the JsonConverter that exactly matches the number,
|
||||
When non-null, there must be a constructor defined in the <see cref="T:Newtonsoft.Json.JsonConverter"/> that exactly matches the number,
|
||||
order, and type of these parameters.
|
||||
</summary>
|
||||
<example>
|
||||
[JsonContainer(ItemConverterType = typeof(MyContainerConverter), ItemConverterParameters = new object[] { 123, "Four" })]
|
||||
</example>
|
||||
</member>
|
||||
<member name="P:Newtonsoft.Json.JsonContainerAttribute.NamingStrategyType">
|
||||
<summary>
|
||||
Gets or sets the <see cref="T:System.Type"/> of the <see cref="T:Newtonsoft.Json.Serialization.NamingStrategy"/>.
|
||||
</summary>
|
||||
<value>The <see cref="T:System.Type"/> of the <see cref="T:Newtonsoft.Json.Serialization.NamingStrategy"/>.</value>
|
||||
</member>
|
||||
<member name="P:Newtonsoft.Json.JsonContainerAttribute.NamingStrategyParameters">
|
||||
<summary>
|
||||
The parameter list to use when constructing the <see cref="T:Newtonsoft.Json.Serialization.NamingStrategy"/> described by NamingStrategyType.
|
||||
If null, the default constructor is used.
|
||||
When non-null, there must be a constructor defined in the <see cref="T:Newtonsoft.Json.Serialization.NamingStrategy"/> that exactly matches the number,
|
||||
order, and type of these parameters.
|
||||
</summary>
|
||||
<example>
|
||||
[JsonContainer(NamingStrategyType = typeof(MyNamingStrategy), NamingStrategyParameters = new object[] { 123, "Four" })]
|
||||
</example>
|
||||
</member>
|
||||
<member name="P:Newtonsoft.Json.JsonContainerAttribute.IsReference">
|
||||
<summary>
|
||||
Gets or sets a value that indicates whether to preserve object references.
|
||||
@@ -1488,13 +1505,13 @@
|
||||
</member>
|
||||
<member name="P:Newtonsoft.Json.JsonConverterAttribute.ConverterType">
|
||||
<summary>
|
||||
Gets the <see cref="T:System.Type"/> of the converter.
|
||||
Gets the <see cref="T:System.Type"/> of the <see cref="T:Newtonsoft.Json.JsonConverter"/>.
|
||||
</summary>
|
||||
<value>The <see cref="T:System.Type"/> of the converter.</value>
|
||||
<value>The <see cref="T:System.Type"/> of the <see cref="T:Newtonsoft.Json.JsonConverter"/>.</value>
|
||||
</member>
|
||||
<member name="P:Newtonsoft.Json.JsonConverterAttribute.ConverterParameters">
|
||||
<summary>
|
||||
The parameter list to use when constructing the JsonConverter described by ConverterType.
|
||||
The parameter list to use when constructing the <see cref="T:Newtonsoft.Json.JsonConverter"/> described by ConverterType.
|
||||
If null, the default constructor is used.
|
||||
</summary>
|
||||
</member>
|
||||
@@ -1502,14 +1519,14 @@
|
||||
<summary>
|
||||
Initializes a new instance of the <see cref="T:Newtonsoft.Json.JsonConverterAttribute"/> class.
|
||||
</summary>
|
||||
<param name="converterType">Type of the converter.</param>
|
||||
<param name="converterType">Type of the <see cref="T:Newtonsoft.Json.JsonConverter"/>.</param>
|
||||
</member>
|
||||
<member name="M:Newtonsoft.Json.JsonConverterAttribute.#ctor(System.Type,System.Object[])">
|
||||
<summary>
|
||||
Initializes a new instance of the <see cref="T:Newtonsoft.Json.JsonConverterAttribute"/> class.
|
||||
</summary>
|
||||
<param name="converterType">Type of the converter.</param>
|
||||
<param name="converterParameters">Parameter list to use when constructing the JsonConverter. Can be null.</param>
|
||||
<param name="converterType">Type of the <see cref="T:Newtonsoft.Json.JsonConverter"/>.</param>
|
||||
<param name="converterParameters">Parameter list to use when constructing the <see cref="T:Newtonsoft.Json.JsonConverter"/>. Can be null.</param>
|
||||
</member>
|
||||
<member name="T:Newtonsoft.Json.JsonConverterCollection">
|
||||
<summary>
|
||||
@@ -1632,21 +1649,38 @@
|
||||
</member>
|
||||
<member name="P:Newtonsoft.Json.JsonPropertyAttribute.ItemConverterType">
|
||||
<summary>
|
||||
Gets or sets the converter used when serializing the property's collection items.
|
||||
Gets or sets the <see cref="T:Newtonsoft.Json.JsonConverter"/> used when serializing the property's collection items.
|
||||
</summary>
|
||||
<value>The collection's items converter.</value>
|
||||
<value>The collection's items <see cref="T:Newtonsoft.Json.JsonConverter"/>.</value>
|
||||
</member>
|
||||
<member name="P:Newtonsoft.Json.JsonPropertyAttribute.ItemConverterParameters">
|
||||
<summary>
|
||||
The parameter list to use when constructing the JsonConverter described by ItemConverterType.
|
||||
The parameter list to use when constructing the <see cref="T:Newtonsoft.Json.JsonConverter"/> described by ItemConverterType.
|
||||
If null, the default constructor is used.
|
||||
When non-null, there must be a constructor defined in the JsonConverter that exactly matches the number,
|
||||
When non-null, there must be a constructor defined in the <see cref="T:Newtonsoft.Json.JsonConverter"/> that exactly matches the number,
|
||||
order, and type of these parameters.
|
||||
</summary>
|
||||
<example>
|
||||
[JsonProperty(ItemConverterType = typeof(MyContainerConverter), ItemConverterParameters = new object[] { 123, "Four" })]
|
||||
</example>
|
||||
</member>
|
||||
<member name="P:Newtonsoft.Json.JsonPropertyAttribute.NamingStrategyType">
|
||||
<summary>
|
||||
Gets or sets the <see cref="T:System.Type"/> of the <see cref="T:Newtonsoft.Json.Serialization.NamingStrategy"/>.
|
||||
</summary>
|
||||
<value>The <see cref="T:System.Type"/> of the <see cref="T:Newtonsoft.Json.Serialization.NamingStrategy"/>.</value>
|
||||
</member>
|
||||
<member name="P:Newtonsoft.Json.JsonPropertyAttribute.NamingStrategyParameters">
|
||||
<summary>
|
||||
The parameter list to use when constructing the <see cref="T:Newtonsoft.Json.Serialization.NamingStrategy"/> described by NamingStrategyType.
|
||||
If null, the default constructor is used.
|
||||
When non-null, there must be a constructor defined in the <see cref="T:Newtonsoft.Json.Serialization.NamingStrategy"/> that exactly matches the number,
|
||||
order, and type of these parameters.
|
||||
</summary>
|
||||
<example>
|
||||
[JsonProperty(NamingStrategyType = typeof(MyNamingStrategy), NamingStrategyParameters = new object[] { 123, "Four" })]
|
||||
</example>
|
||||
</member>
|
||||
<member name="P:Newtonsoft.Json.JsonPropertyAttribute.NullValueHandling">
|
||||
<summary>
|
||||
Gets or sets the null value handling used when serializing this property.
|
||||
@@ -1902,7 +1936,7 @@
|
||||
<summary>
|
||||
Reads the next JSON token from the stream.
|
||||
</summary>
|
||||
<returns>true if the next token was read successfully; false if there are no more tokens to read.</returns>
|
||||
<returns><c>true</c> if the next token was read successfully; <c>false</c> if there are no more tokens to read.</returns>
|
||||
</member>
|
||||
<member name="M:Newtonsoft.Json.JsonReader.ReadAsInt32">
|
||||
<summary>
|
||||
@@ -2590,7 +2624,7 @@
|
||||
Reads the next JSON token from the stream.
|
||||
</summary>
|
||||
<returns>
|
||||
true if the next token was read successfully; false if there are no more tokens to read.
|
||||
<c>true</c> if the next token was read successfully; <c>false</c> if there are no more tokens to read.
|
||||
</returns>
|
||||
</member>
|
||||
<member name="M:Newtonsoft.Json.JsonTextReader.ReadAsInt32">
|
||||
@@ -3152,7 +3186,7 @@
|
||||
Reads the next JSON token from the stream.
|
||||
</summary>
|
||||
<returns>
|
||||
true if the next token was read successfully; false if there are no more tokens to read.
|
||||
<c>true</c> if the next token was read successfully; <c>false</c> if there are no more tokens to read.
|
||||
</returns>
|
||||
</member>
|
||||
<member name="T:Newtonsoft.Json.JsonWriter">
|
||||
@@ -4432,7 +4466,7 @@
|
||||
<param name="propertyName">Name of the property.</param>
|
||||
<param name="value">The value.</param>
|
||||
<param name="comparison">One of the enumeration values that specifies how the strings will be compared.</param>
|
||||
<returns>true if a value was successfully retrieved; otherwise, false.</returns>
|
||||
<returns><c>true</c> if a value was successfully retrieved; otherwise, <c>false</c>.</returns>
|
||||
</member>
|
||||
<member name="M:Newtonsoft.Json.Linq.JObject.Add(System.String,Newtonsoft.Json.Linq.JToken)">
|
||||
<summary>
|
||||
@@ -4446,7 +4480,7 @@
|
||||
Removes the property with the specified name.
|
||||
</summary>
|
||||
<param name="propertyName">Name of the property.</param>
|
||||
<returns>true if item was successfully removed; otherwise, false.</returns>
|
||||
<returns><c>true</c> if item was successfully removed; otherwise, <c>false</c>.</returns>
|
||||
</member>
|
||||
<member name="M:Newtonsoft.Json.Linq.JObject.TryGetValue(System.String,Newtonsoft.Json.Linq.JToken@)">
|
||||
<summary>
|
||||
@@ -4454,7 +4488,7 @@
|
||||
</summary>
|
||||
<param name="propertyName">Name of the property.</param>
|
||||
<param name="value">The value.</param>
|
||||
<returns>true if a value was successfully retrieved; otherwise, false.</returns>
|
||||
<returns><c>true</c> if a value was successfully retrieved; otherwise, <c>false</c>.</returns>
|
||||
</member>
|
||||
<member name="M:Newtonsoft.Json.Linq.JObject.GetEnumerator">
|
||||
<summary>
|
||||
@@ -4643,7 +4677,7 @@
|
||||
</summary>
|
||||
<param name="t1">The first <see cref="T:Newtonsoft.Json.Linq.JToken"/> to compare.</param>
|
||||
<param name="t2">The second <see cref="T:Newtonsoft.Json.Linq.JToken"/> to compare.</param>
|
||||
<returns>true if the tokens are equal; otherwise false.</returns>
|
||||
<returns><c>true</c> if the tokens are equal; otherwise <c>false</c>.</returns>
|
||||
</member>
|
||||
<member name="P:Newtonsoft.Json.Linq.JToken.Next">
|
||||
<summary>
|
||||
@@ -5499,7 +5533,7 @@
|
||||
<param name="x">The first object of type <see cref="T:Newtonsoft.Json.Linq.JToken"/> to compare.</param>
|
||||
<param name="y">The second object of type <see cref="T:Newtonsoft.Json.Linq.JToken"/> to compare.</param>
|
||||
<returns>
|
||||
true if the specified objects are equal; otherwise, false.
|
||||
<c>true</c> if the specified objects are equal; otherwise, <c>false</c>.
|
||||
</returns>
|
||||
</member>
|
||||
<member name="M:Newtonsoft.Json.Linq.JTokenEqualityComparer.GetHashCode(Newtonsoft.Json.Linq.JToken)">
|
||||
@@ -5531,7 +5565,7 @@
|
||||
Reads the next JSON token from the stream.
|
||||
</summary>
|
||||
<returns>
|
||||
true if the next token was read successfully; false if there are no more tokens to read.
|
||||
<c>true</c> if the next token was read successfully; <c>false</c> if there are no more tokens to read.
|
||||
</returns>
|
||||
</member>
|
||||
<member name="P:Newtonsoft.Json.Linq.JTokenReader.Path">
|
||||
@@ -6001,7 +6035,7 @@
|
||||
Indicates whether the current object is equal to another object of the same type.
|
||||
</summary>
|
||||
<returns>
|
||||
true if the current object is equal to the <paramref name="other"/> parameter; otherwise, false.
|
||||
<c>true</c> if the current object is equal to the <paramref name="other"/> parameter; otherwise, <c>false</c>.
|
||||
</returns>
|
||||
<param name="other">An object to compare with this object.</param>
|
||||
</member>
|
||||
@@ -6011,7 +6045,7 @@
|
||||
</summary>
|
||||
<param name="obj">The <see cref="T:System.Object"/> to compare with the current <see cref="T:System.Object"/>.</param>
|
||||
<returns>
|
||||
true if the specified <see cref="T:System.Object"/> is equal to the current <see cref="T:System.Object"/>; otherwise, false.
|
||||
<c>true</c> if the specified <see cref="T:System.Object"/> is equal to the current <see cref="T:System.Object"/>; otherwise, <c>false</c>.
|
||||
</returns>
|
||||
<exception cref="T:System.NullReferenceException">
|
||||
The <paramref name="obj"/> parameter is null.
|
||||
@@ -6881,6 +6915,35 @@
|
||||
<param name="assemblyName">Specifies the <see cref="T:System.Reflection.Assembly"/> name of the serialized object.</param>
|
||||
<param name="typeName">Specifies the <see cref="T:System.Type"/> name of the serialized object.</param>
|
||||
</member>
|
||||
<member name="T:Newtonsoft.Json.Serialization.CamelCaseNamingStrategy">
|
||||
<summary>
|
||||
A camel case naming strategy.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:Newtonsoft.Json.Serialization.CamelCaseNamingStrategy.#ctor(System.Boolean,System.Boolean)">
|
||||
<summary>
|
||||
Initializes a new instance of the <see cref="T:Newtonsoft.Json.Serialization.CamelCaseNamingStrategy"/> class.
|
||||
</summary>
|
||||
<param name="processDictionaryKeys">
|
||||
A flag indicating whether dictionary keys should be processed.
|
||||
</param>
|
||||
<param name="overrideSpecifiedNames">
|
||||
A flag indicating whether explicitly specified property names should be processed,
|
||||
e.g. a property name customized with a <see cref="T:Newtonsoft.Json.JsonPropertyAttribute"/>.
|
||||
</param>
|
||||
</member>
|
||||
<member name="M:Newtonsoft.Json.Serialization.CamelCaseNamingStrategy.#ctor">
|
||||
<summary>
|
||||
Initializes a new instance of the <see cref="T:Newtonsoft.Json.Serialization.CamelCaseNamingStrategy"/> class.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:Newtonsoft.Json.Serialization.CamelCaseNamingStrategy.ResolvePropertyName(System.String)">
|
||||
<summary>
|
||||
Resolves the specified property name.
|
||||
</summary>
|
||||
<param name="name">The property name to resolve.</param>
|
||||
<returns>The resolved property name.</returns>
|
||||
</member>
|
||||
<member name="T:Newtonsoft.Json.Serialization.CamelCasePropertyNamesContractResolver">
|
||||
<summary>
|
||||
Resolves member mappings for a type, camel casing property names.
|
||||
@@ -6891,13 +6954,6 @@
|
||||
Initializes a new instance of the <see cref="T:Newtonsoft.Json.Serialization.CamelCasePropertyNamesContractResolver"/> class.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:Newtonsoft.Json.Serialization.CamelCasePropertyNamesContractResolver.ResolvePropertyName(System.String)">
|
||||
<summary>
|
||||
Resolves the name of the property.
|
||||
</summary>
|
||||
<param name="propertyName">Name of the property.</param>
|
||||
<returns>The property name camel cased.</returns>
|
||||
</member>
|
||||
<member name="T:Newtonsoft.Json.Serialization.DefaultContractResolver">
|
||||
<summary>
|
||||
Used by <see cref="T:Newtonsoft.Json.JsonSerializer"/> to resolves a <see cref="T:Newtonsoft.Json.Serialization.JsonContract"/> for a given <see cref="T:System.Type"/>.
|
||||
@@ -6926,6 +6982,12 @@
|
||||
<c>true</c> if serialized compiler generated members; otherwise, <c>false</c>.
|
||||
</value>
|
||||
</member>
|
||||
<member name="P:Newtonsoft.Json.Serialization.DefaultContractResolver.NamingStrategy">
|
||||
<summary>
|
||||
Gets or sets the naming strategy used to resolve how property names and dictionary keys are serialized.
|
||||
</summary>
|
||||
<value>The naming strategy used to resolve how property names and dictionary keys are serialized.</value>
|
||||
</member>
|
||||
<member name="M:Newtonsoft.Json.Serialization.DefaultContractResolver.#ctor">
|
||||
<summary>
|
||||
Initializes a new instance of the <see cref="T:Newtonsoft.Json.Serialization.DefaultContractResolver"/> class.
|
||||
@@ -7072,6 +7134,18 @@
|
||||
<param name="propertyName">Name of the property.</param>
|
||||
<returns>Name of the property.</returns>
|
||||
</member>
|
||||
<member name="T:Newtonsoft.Json.Serialization.DefaultNamingStrategy">
|
||||
<summary>
|
||||
The default naming strategy. Property names and dictionary keys are unchanged.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:Newtonsoft.Json.Serialization.DefaultNamingStrategy.ResolvePropertyName(System.String)">
|
||||
<summary>
|
||||
Resolves the specified property name.
|
||||
</summary>
|
||||
<param name="name">The property name to resolve.</param>
|
||||
<returns>The resolved property name.</returns>
|
||||
</member>
|
||||
<member name="T:Newtonsoft.Json.Serialization.DefaultSerializationBinder">
|
||||
<summary>
|
||||
The default serialization binder used when resolving and loading classes from type names.
|
||||
@@ -7890,13 +7964,6 @@
|
||||
<param name="converterArgs">Optional arguments to pass to an initializing constructor of the JsonConverter.
|
||||
If null, the default constructor is used.</param>
|
||||
</member>
|
||||
<member name="M:Newtonsoft.Json.Serialization.JsonTypeReflector.GetJsonConverterCreator(System.Type)">
|
||||
<summary>
|
||||
Create a factory function that can be used to create instances of a JsonConverter described by the
|
||||
argument type. The returned function can then be used to either invoke the converter's default ctor, or any
|
||||
parameterized constructors by way of an object array.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:Newtonsoft.Json.Serialization.MemoryTraceWriter">
|
||||
<summary>
|
||||
Represents a trace writer that writes to memory. When the trace message limit is
|
||||
@@ -7940,6 +8007,46 @@
|
||||
A <see cref="T:System.String"/> of the most recent trace messages.
|
||||
</returns>
|
||||
</member>
|
||||
<member name="T:Newtonsoft.Json.Serialization.NamingStrategy">
|
||||
<summary>
|
||||
A base class for resolving how property names and dictionary keys are serialized.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:Newtonsoft.Json.Serialization.NamingStrategy.ProcessDictionaryKeys">
|
||||
<summary>
|
||||
A flag indicating whether dictionary keys should be processed.
|
||||
Defaults to <c>false</c>.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:Newtonsoft.Json.Serialization.NamingStrategy.OverrideSpecifiedNames">
|
||||
<summary>
|
||||
A flag indicating whether explicitly specified property names,
|
||||
e.g. a property name customized with a <see cref="T:Newtonsoft.Json.JsonPropertyAttribute"/>, should be processed.
|
||||
Defaults to <c>false</c>.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:Newtonsoft.Json.Serialization.NamingStrategy.GetPropertyName(System.String,System.Boolean)">
|
||||
<summary>
|
||||
Gets the serialized name for a given property name.
|
||||
</summary>
|
||||
<param name="name">The initial property name.</param>
|
||||
<param name="hasSpecifiedName">A flag indicating whether the property has had a name explicitly specfied.</param>
|
||||
<returns>The serialized property name.</returns>
|
||||
</member>
|
||||
<member name="M:Newtonsoft.Json.Serialization.NamingStrategy.GetDictionaryKey(System.String)">
|
||||
<summary>
|
||||
Gets the serialized key for a given dictionary key.
|
||||
</summary>
|
||||
<param name="key">The initial dictionary key.</param>
|
||||
<returns>The serialized dictionary key.</returns>
|
||||
</member>
|
||||
<member name="M:Newtonsoft.Json.Serialization.NamingStrategy.ResolvePropertyName(System.String)">
|
||||
<summary>
|
||||
Resolves the specified property name.
|
||||
</summary>
|
||||
<param name="name">The property name to resolve.</param>
|
||||
<returns>The resolved property name.</returns>
|
||||
</member>
|
||||
<member name="T:Newtonsoft.Json.Serialization.ObjectConstructor`1">
|
||||
<summary>
|
||||
Represents a method that constructs an object.
|
||||
@@ -8002,6 +8109,35 @@
|
||||
<param name="target">The target to get the value from.</param>
|
||||
<returns>The value.</returns>
|
||||
</member>
|
||||
<member name="T:Newtonsoft.Json.Serialization.SnakeCaseNamingStrategy">
|
||||
<summary>
|
||||
A snake case naming strategy.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:Newtonsoft.Json.Serialization.SnakeCaseNamingStrategy.#ctor(System.Boolean,System.Boolean)">
|
||||
<summary>
|
||||
Initializes a new instance of the <see cref="T:Newtonsoft.Json.Serialization.SnakeCaseNamingStrategy"/> class.
|
||||
</summary>
|
||||
<param name="processDictionaryKeys">
|
||||
A flag indicating whether dictionary keys should be processed.
|
||||
</param>
|
||||
<param name="overrideSpecifiedNames">
|
||||
A flag indicating whether explicitly specified property names should be processed,
|
||||
e.g. a property name customized with a <see cref="T:Newtonsoft.Json.JsonPropertyAttribute"/>.
|
||||
</param>
|
||||
</member>
|
||||
<member name="M:Newtonsoft.Json.Serialization.SnakeCaseNamingStrategy.#ctor">
|
||||
<summary>
|
||||
Initializes a new instance of the <see cref="T:Newtonsoft.Json.Serialization.SnakeCaseNamingStrategy"/> class.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:Newtonsoft.Json.Serialization.SnakeCaseNamingStrategy.ResolvePropertyName(System.String)">
|
||||
<summary>
|
||||
Resolves the specified property name.
|
||||
</summary>
|
||||
<param name="name">The property name to resolve.</param>
|
||||
<returns>The resolved property name.</returns>
|
||||
</member>
|
||||
<member name="T:Newtonsoft.Json.StringEscapeHandling">
|
||||
<summary>
|
||||
Specifies how strings are escaped when writing JSON text.
|
||||
@@ -8103,16 +8239,6 @@
|
||||
<param name="initial">The list to add to.</param>
|
||||
<param name="collection">The collection of elements to add.</param>
|
||||
</member>
|
||||
<member name="M:Newtonsoft.Json.Utilities.CollectionUtils.IndexOf``1(System.Collections.Generic.IEnumerable{``0},``0,System.Collections.Generic.IEqualityComparer{``0})">
|
||||
<summary>
|
||||
Returns the index of the first occurrence in a sequence by using a specified IEqualityComparer{TSource}.
|
||||
</summary>
|
||||
<typeparam name="TSource">The type of the elements of source.</typeparam>
|
||||
<param name="list">A sequence in which to locate a value.</param>
|
||||
<param name="value">The object to locate in the sequence</param>
|
||||
<param name="comparer">An equality comparer to compare values.</param>
|
||||
<returns>The zero-based index of the first occurrence of value within the entire sequence, if found; otherwise, –1.</returns>
|
||||
</member>
|
||||
<member name="M:Newtonsoft.Json.Utilities.ConvertUtils.ConvertOrCast(System.Object,System.Globalization.CultureInfo,System.Type)">
|
||||
<summary>
|
||||
Converts the value to the specified type. If the value is unable to be converted, the
|
||||
@@ -8222,13 +8348,6 @@
|
||||
<c>true</c> if the string is all white space; otherwise, <c>false</c>.
|
||||
</returns>
|
||||
</member>
|
||||
<member name="M:Newtonsoft.Json.Utilities.StringUtils.NullEmptyString(System.String)">
|
||||
<summary>
|
||||
Nulls an empty string.
|
||||
</summary>
|
||||
<param name="s">The string.</param>
|
||||
<returns>Null if the string was null, otherwise the string unchanged.</returns>
|
||||
</member>
|
||||
<member name="T:Newtonsoft.Json.WriteState">
|
||||
<summary>
|
||||
Specifies the state of the <see cref="T:Newtonsoft.Json.JsonWriter"/>.
|
||||
Binary file not shown.
File diff suppressed because it is too large
Load Diff
34
run.sh
Executable file
34
run.sh
Executable file
@@ -0,0 +1,34 @@
|
||||
#!/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
|
||||
|
||||
if [[ "$BUILD" = "Debug" ]]; then
|
||||
MONO_ARGS+=("--debug")
|
||||
fi
|
||||
|
||||
cd "$(dirname "$(readlink -f "$0")")"
|
||||
|
||||
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.
BIN
tools/ILRepack/ILRepack.exe
Normal file
BIN
tools/ILRepack/ILRepack.exe
Normal file
Binary file not shown.
BIN
tools/ILRepack/Mono.Cecil.Mdb.dll
Normal file
BIN
tools/ILRepack/Mono.Cecil.Mdb.dll
Normal file
Binary file not shown.
BIN
tools/ILRepack/Mono.Cecil.Pdb.dll
Normal file
BIN
tools/ILRepack/Mono.Cecil.Pdb.dll
Normal file
Binary file not shown.
BIN
tools/ILRepack/Mono.Cecil.dll
Normal file
BIN
tools/ILRepack/Mono.Cecil.dll
Normal file
Binary file not shown.
BIN
tools/ILRepack/Mono.Posix.dll
Normal file
BIN
tools/ILRepack/Mono.Posix.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