Compare commits

...

80 Commits

Author SHA1 Message Date
JustArchi
85dea3ab70 Mono: Prefer performance over memory
Every user can further fine-tune it however he wishes with https://github.com/JustArchi/ArchiSteamFarm/wiki/Low-memory-setup
2016-06-03 00:16:31 +02:00
JustArchi
aa9d78af95 Misc 2016-06-03 00:06:13 +02:00
JustArchi
550effd7c1 EXPERIMENTAL: Base key on classID only
I've just received trade offer from Endorlight game which used different combinations of classID/instanceID for the same items, such as <1450080555, 246376127> and <1450080555, 0> for Birdy trading card.
This is the first time I've seen something like that, as up to this point all classID + instanceID matched nicely. It's not good because it results in possibly wrong results regarding numbers of the same cards.
It's not any major problem scamming-wise, as ASF does other checks (including appID checks) so in worst case we could accept a trade that is not neutral+ for us, such as 1 -> 2 dupes one.

This commit fixes wrong logic for that particular trade I've encountered, and many similar ones, but I have no idea if we can really base key on classID only.
Number seems big enough to fit all steam items, but if there ever happens item that will have same classID as other one, we'll be in deep sh*t.

I ran a test on my Steam account with 7.5k+ items and didn't find any item which could cause such conflict, so I can at least assume that the issue doesn't exist for majority of Steam users.
Sadly there doesn't seem to be any good way to solve it either, as if such conflicts happens, then we will have 3 items such as <7, 1>, <7, 4> and <7, 0>. We can't know if 0 should be 1 or 4 (thanks GabeN).
This seems to be best solution for that problem, and until we find clasID conflict, we can sleep in peace.
2016-06-02 23:56:59 +02:00
JustArchi
548146cb65 Closes #240 2016-06-02 08:21:44 +02:00
JustArchi
4ca39da1f2 Misc 2016-06-01 22:45:51 +02:00
JustArchi
f406034c63 Mono: Prefer more aggressive GC 2016-06-01 22:43:11 +02:00
JustArchi
2b5b38aa07 Packages update 2016-06-01 14:37:50 +02:00
JustArchi
b8dbddd6f4 Misc 2016-06-01 02:34:38 +02:00
JustArchi
8ce70889d7 Misc 2016-06-01 02:19:22 +02:00
JustArchi
93d235c1b2 Bump 2016-05-30 23:30:00 +02:00
JustArchi
73af6b369a Fix ASF accidentally dismissing profile notifications 2016-05-30 23:25:50 +02:00
JustArchi
2d91a1ed26 Misc 2016-05-30 13:13:24 +02:00
JustArchi
7af0027c66 Correct custom games played while idle with new event-based mechanism 2016-05-30 13:12:22 +02:00
JustArchi
2ce54d9d0a Correct debug leftovers 2016-05-30 13:11:29 +02:00
JustArchi
88d722c14b Fix mono quirks
At least it already works on nightly...
2016-05-30 02:24:56 +02:00
JustArchi
5c46069c67 Bump 2016-05-30 02:11:23 +02:00
JustArchi
c2a1c160e0 Misc 2016-05-30 02:06:04 +02:00
JustArchi
ff971f7615 Misc 2016-05-30 02:03:33 +02:00
JustArchi
cdcaa9b06c Code review 2016-05-30 01:57:06 +02:00
JustArchi
9403985b14 LoggedInElsewhere improvements
Previously we had rather half-blind mechanism of trying to play given games, expecting a disconnect, and reconnecting in AccountPlayingDelay minutes. Now instead we have proper event-based handling - ASF listens on each PlayingSessionState event and updates availability of farming accordingly, not only resuming farming immediately after it's possible, but also limiting number of reconnects and other issues which could be caused by previous approach.

I bet this can be even further improved to not receive LoggedInElsewhere and disconnect error when user starts playing a game, but that's misc compared to gigantic improvement in this commit
2016-05-30 00:09:42 +02:00
JustArchi
a0215d2ac4 Misc 2016-05-28 13:20:42 +02:00
JustArchi
2ef99461d6 Packages update 2016-05-28 13:10:32 +02:00
JustArchi
8e91031510 Slightly improve logic of games played while idle 2016-05-28 13:08:53 +02:00
Łukasz Domeradzki
254cd3843e Mono doesn't support Windows XP anymore 2016-05-25 10:11:41 +02:00
Łukasz Domeradzki
450fc579f7 Update README.md 2016-05-23 07:32:58 +02:00
JustArchi
98f9e716d2 Readme update 2016-05-22 12:25:30 +02:00
JustArchi
86c8aa9b74 Bump 2016-05-18 05:03:51 +02:00
JustArchi
33e0675177 Skip first shutdown in ShutdownOnFarmingFinished, #229 2016-05-18 04:33:17 +02:00
JustArchi
f840f28657 Run debug version with Mono debug 2016-05-18 02:46:29 +02:00
JustArchi
64eb4a51b6 Misc 2016-05-18 02:26:29 +02:00
JustArchi
97affa7b54 Closes #229 2016-05-18 02:25:31 +02:00
JustArchi
65f1d790da Misc 2016-05-16 21:40:20 +02:00
JustArchi
0107185f2a Misc optimization 2016-05-16 03:14:57 +02:00
JustArchi
b8e98f58ac Misc 2016-05-14 00:11:41 +02:00
JustArchi
be9217f493 Bump 2016-05-13 19:51:44 +02:00
JustArchi
b60b864aca Misc 2016-05-13 19:43:48 +02:00
JustArchi
4c64141462 Misc 2016-05-13 19:40:55 +02:00
JustArchi
4b50596709 Enhance concurrent access with ArchiBoT concurrent hashset 2016-05-13 19:39:54 +02:00
JustArchi
622f060575 Prefer flags over comments 2016-05-13 19:20:24 +02:00
JustArchi
20038e8c86 Derp 2016-05-13 06:33:25 +02:00
JustArchi
b8faca2517 Gigantic code review (with ReSharper) 2016-05-13 06:32:42 +02:00
JustArchi
6f93139a18 Bump 2016-05-13 01:43:21 +02:00
JustArchi
50b5c7b87f Correct STM algorithm when overpaying with cards from the same game
us: X X Y
them: Y Y Z

trade:
Y -> X + Z

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

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

Old:
toGive: 1
toReceive: 2

1 > 2 ? False
2016-05-13 01:35:17 +02:00
JustArchi
b60448ef4c Bump 2016-05-12 19:00:26 +02:00
JustArchi
fad08a1fa9 Fix linking new authenticator with null password 2016-05-12 16:32:04 +02:00
JustArchi
a180c100c6 Make use of CellID, closes #223 2016-05-08 15:52:57 +02:00
JustArchi
9d97ca16e8 Misc WCF code review 2016-05-07 15:24:09 +02:00
JustArchi
e833415718 Closes #221 2016-05-07 15:08:24 +02:00
JustArchi
6bb296a674 Bump 2016-05-06 23:58:50 +02:00
JustArchi
f1e5874868 Misc 2016-05-06 23:54:47 +02:00
JustArchi
38e2088d09 Misc 2016-05-06 23:48:33 +02:00
JustArchi
8447e07aa0 Allow overpaying also in steam cards 2016-05-06 23:38:22 +02:00
JustArchi
fbe4e4bc6d Allow STM overpaying 2016-05-06 23:31:00 +02:00
JustArchi
f1213607ce Don't react in any way to failed commands sent by non-owner 2016-05-06 18:07:03 +02:00
JustArchi
de832c530b Misc 2016-05-04 16:43:16 +02:00
JustArchi
0c872b17e2 Misc 2016-05-04 16:41:00 +02:00
JustArchi
5fcbb85b4c Bump 2016-05-03 15:54:26 +02:00
JustArchi
3cdc93d373 Cut SendOnFarmingFinished spam
Allow only one trade to be sent if we didn't farm anything
2016-05-03 15:37:11 +02:00
JustArchi
36e99d9139 Code review 2016-05-03 07:26:41 +02:00
JustArchi
7bee2d468b Bump 2016-04-29 16:52:57 +02:00
JustArchi
8630cc40c8 Small WebBrowser enhancements, closes #212 2016-04-29 16:37:42 +02:00
JustArchi
3683195a0e Misc 2016-04-29 15:47:07 +02:00
JustArchi
7f5b946645 Use API is possible in GetOwnedGames, closes #213 2016-04-29 15:44:11 +02:00
JustArchi
fdb194fe67 Misc 2016-04-27 20:28:36 +02:00
JustArchi
9063b9206b Derp 2016-04-27 20:06:49 +02:00
JustArchi
8d300894e5 Add add proper notice if it still fails 2016-04-27 20:06:17 +02:00
JustArchi
3a0d3c444e Make ASF 2FA less prone to steam fuckups 2016-04-27 20:03:48 +02:00
JustArchi
8118fe0690 Misc 2016-04-26 22:05:58 +02:00
JustArchi
344c2ad23d Misc 2016-04-26 18:01:19 +02:00
JustArchi
d1a6613541 Use asterisks for password field 2016-04-26 14:23:44 +02:00
JustArchi
3dc88c65aa Revert recent trades
When steam is going crazy we're also forgetting trades that simply failed to accept
Also, trade that is not valid currently, might be valid in future, especially STM
2016-04-25 14:34:21 +02:00
JustArchi
46384829c9 Misc 2016-04-25 11:42:46 +02:00
JustArchi
415ee8cc57 Misc 2016-04-25 11:10:39 +02:00
JustArchi
351d45e049 Fix more regressions 2016-04-25 10:46:29 +02:00
JustArchi
f81bbc60c5 Fix regression 2016-04-25 10:40:36 +02:00
JustArchi
eb6e93a172 Code review 2016-04-24 23:32:23 +02:00
JustArchi
e17c3ecf2a Enhance status, closes #207 2016-04-23 19:14:31 +02:00
JustArchi
048b0fb538 Misc 2016-04-23 16:36:43 +02:00
JustArchi
ac7ecb6bb4 Misc 2016-04-23 16:34:00 +02:00
JustArchi
fcaf038dac Bump 2016-04-23 16:24:39 +02:00
67 changed files with 13391 additions and 3259 deletions

View File

@@ -26,7 +26,9 @@ 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;
@@ -36,7 +38,7 @@ namespace ArchiSteamFarm {
internal ArchiHandler(Bot bot) {
if (bot == null) {
throw new ArgumentNullException("bot");
throw new ArgumentNullException(nameof(bot));
}
Bot = bot;
@@ -52,67 +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 HashSet<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 HashSet<Notification>();
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 HashSet<Notification>() {
new Notification(Notification.ENotificationType.Items)
Notifications = new HashSet<ENotification> {
ENotification.Items
};
}
}
}
internal sealed class OfflineMessageCallback : CallbackMsg {
internal readonly uint OfflineMessages;
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;
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,
@@ -123,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"].Value;
gameName = WebUtility.HtmlDecode(gameName); // Apparently steam expects client to decode sent HTML
Items.Add(appID, gameName);
Items[appID] = gameName;
}
}
}
@@ -170,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)
});
}
@@ -254,11 +223,16 @@ 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()
};
@@ -282,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;
@@ -315,6 +292,7 @@ namespace ArchiSteamFarm {
public override void HandleMsg(IPacketMsg packetMsg) {
if (packetMsg == null) {
Logging.LogNullError(nameof(packetMsg), Bot.BotName);
return;
}
@@ -325,6 +303,9 @@ namespace ArchiSteamFarm {
case EMsg.ClientItemAnnouncements:
HandleItemAnnouncements(packetMsg);
break;
case EMsg.ClientPlayingSessionState:
HandlePlayingSessionState(packetMsg);
break;
case EMsg.ClientPurchaseResponse:
HandlePurchaseResponse(packetMsg);
break;
@@ -336,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));
}
}

View File

@@ -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">
@@ -99,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" />
@@ -169,7 +170,7 @@
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/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>

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -28,6 +28,8 @@ using System.Collections.Generic;
using System.IO;
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;
@@ -36,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";
@@ -99,15 +101,21 @@ 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 filePath) {
if (string.IsNullOrEmpty(filePath) || !File.Exists(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(filePath));
} catch (Exception e) {

View File

@@ -25,6 +25,7 @@
using Newtonsoft.Json;
using SteamAuth;
using System;
using System.Diagnostics.CodeAnalysis;
using System.IO;
namespace ArchiSteamFarm {
@@ -67,6 +68,7 @@ namespace ArchiSteamFarm {
internal static BotDatabase Load(string filePath) {
if (string.IsNullOrEmpty(filePath)) {
Logging.LogNullError(nameof(filePath));
return null;
}
@@ -75,6 +77,7 @@ namespace ArchiSteamFarm {
}
BotDatabase botDatabase;
try {
botDatabase = JsonConvert.DeserializeObject<BotDatabase>(File.ReadAllText(filePath));
} catch (Exception e) {
@@ -83,6 +86,7 @@ namespace ArchiSteamFarm {
}
if (botDatabase == null) {
Logging.LogNullError(nameof(botDatabase));
return null;
}
@@ -93,7 +97,7 @@ namespace ArchiSteamFarm {
// This constructor is used when creating new database
private BotDatabase(string filePath) {
if (string.IsNullOrEmpty(filePath)) {
throw new ArgumentNullException("filePath");
throw new ArgumentNullException(nameof(filePath));
}
FilePath = filePath;
@@ -101,6 +105,7 @@ namespace ArchiSteamFarm {
}
// This constructor is used only by deserializer
[SuppressMessage("ReSharper", "UnusedMember.Local")]
private BotDatabase() { }
internal void Save() {

View File

@@ -35,10 +35,10 @@ 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 ManualResetEventSlim FarmResetEvent = new ManualResetEventSlim(false);
private readonly SemaphoreSlim Semaphore = new SemaphoreSlim(1);
private readonly SemaphoreSlim FarmingSemaphore = new SemaphoreSlim(1);
private readonly Bot Bot;
private readonly Timer Timer;
@@ -48,12 +48,12 @@ namespace ArchiSteamFarm {
internal CardsFarmer(Bot bot) {
if (bot == null) {
throw new ArgumentNullException("bot");
throw new ArgumentNullException(nameof(bot));
}
Bot = bot;
if (Timer == null && Program.GlobalConfig.IdleFarmingPeriod > 0) {
if ((Timer == null) && (Program.GlobalConfig.IdleFarmingPeriod > 0)) {
Timer = new Timer(
async e => await CheckGamesForFarming().ConfigureAwait(false),
null,
@@ -80,27 +80,35 @@ namespace ArchiSteamFarm {
}
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().ConfigureAwait(false);
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
do {
// Now the algorithm used for farming depends on whether account is restricted or not
@@ -132,20 +140,21 @@ namespace ArchiSteamFarm {
Logging.LogGenericInfo("Chosen farming algorithm: Simple", Bot.BotName);
while (GamesToFarm.Count > 0) {
uint appID = GamesToFarm.Keys.FirstOrDefault();
if (!await FarmSolo(appID).ConfigureAwait(false)) {
NowFarming = false;
return;
if (await FarmSolo(appID).ConfigureAwait(false)) {
continue;
}
NowFarming = false;
return;
}
}
} while (await IsAnythingToFarm().ConfigureAwait(false));
CurrentGamesFarming.Clear();
CurrentGamesFarming.TrimExcess();
CurrentGamesFarming.ClearAndTrim();
NowFarming = false;
Logging.LogGenericInfo("Farming finished!", Bot.BotName);
await Bot.OnFarmingFinished().ConfigureAwait(false);
await Bot.OnFarmingFinished(true).ConfigureAwait(false);
}
internal async Task StopFarming() {
@@ -153,10 +162,10 @@ namespace ArchiSteamFarm {
return;
}
await Semaphore.WaitAsync().ConfigureAwait(false);
await FarmingSemaphore.WaitAsync().ConfigureAwait(false);
if (!NowFarming) {
Semaphore.Release();
FarmingSemaphore.Release();
return;
}
@@ -164,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);
}
@@ -174,7 +183,7 @@ namespace ArchiSteamFarm {
FarmResetEvent.Reset();
Logging.LogGenericInfo("Farming stopped!", Bot.BotName);
Semaphore.Release();
FarmingSemaphore.Release();
}
internal async Task RestartFarming() {
@@ -184,14 +193,13 @@ 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;
@@ -210,7 +218,7 @@ 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];
string lastPage = htmlNode.InnerText;
if (!string.IsNullOrEmpty(lastPage)) {
@@ -224,26 +232,31 @@ namespace ArchiSteamFarm {
CheckPage(htmlDocument);
if (maxPages > 1) {
Logging.LogGenericInfo("Checking other pages...", Bot.BotName);
List<Task> tasks = new List<Task>(maxPages - 1);
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 (maxPages <= 1) {
return GamesToFarm.Count > 0;
}
Logging.LogGenericInfo("Checking other pages...", Bot.BotName);
List<Task> tasks = new List<Task>(maxPages - 1);
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);
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;
}
@@ -255,32 +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;
}
int index = steamLink.LastIndexOf('/');
if (index < 0) {
Logging.LogNullError("index", Bot.BotName);
Logging.LogNullError(nameof(index), Bot.BotName);
continue;
}
index++;
if (steamLink.Length <= index) {
Logging.LogNullError("length", Bot.BotName);
Logging.LogNullError(nameof(steamLink.Length), Bot.BotName);
continue;
}
steamLink = steamLink.Substring(index);
uint appID;
if (!uint.TryParse(steamLink, out appID)) {
Logging.LogNullError("appID", Bot.BotName);
continue;
}
if (appID == 0) {
Logging.LogNullError("appID", Bot.BotName);
if (!uint.TryParse(steamLink, out appID) || (appID == 0)) {
Logging.LogNullError(nameof(appID), Bot.BotName);
continue;
}
@@ -290,13 +298,13 @@ namespace ArchiSteamFarm {
HtmlNode timeNode = htmlNode.SelectSingleNode(".//div[@class='badge_title_stats_playtime']");
if (timeNode == null) {
Logging.LogNullError("timeNode", Bot.BotName);
Logging.LogNullError(nameof(timeNode), Bot.BotName);
continue;
}
string hoursString = timeNode.InnerText;
if (string.IsNullOrEmpty(hoursString)) {
Logging.LogNullError("hoursString", Bot.BotName);
Logging.LogNullError(nameof(hoursString), Bot.BotName);
continue;
}
@@ -304,7 +312,10 @@ namespace ArchiSteamFarm {
Match match = Regex.Match(hoursString, @"[0-9\.,]+");
if (match.Success) {
float.TryParse(match.Value, NumberStyles.Number, CultureInfo.InvariantCulture, out hours);
if (!float.TryParse(match.Value, NumberStyles.Number, CultureInfo.InvariantCulture, out hours)) {
Logging.LogNullError(nameof(hours), Bot.BotName);
continue;
}
}
GamesToFarm[appID] = hours;
@@ -313,6 +324,7 @@ namespace ArchiSteamFarm {
private async Task CheckPage(byte page) {
if (page == 0) {
Logging.LogNullError(nameof(page), Bot.BotName);
return;
}
@@ -334,6 +346,7 @@ namespace ArchiSteamFarm {
private async Task<bool?> ShouldFarm(uint appID) {
if (appID == 0) {
Logging.LogNullError(nameof(appID), Bot.BotName);
return false;
}
@@ -343,11 +356,12 @@ namespace ArchiSteamFarm {
}
HtmlNode htmlNode = htmlDocument.DocumentNode.SelectSingleNode("//span[@class='progress_info_bold']");
if (htmlNode == null) {
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() {
@@ -364,49 +378,47 @@ namespace ArchiSteamFarm {
}
if (maxHour >= 2) {
CurrentGamesFarming.Clear();
CurrentGamesFarming.TrimExcess();
CurrentGamesFarming.ClearAndTrim();
return true;
}
Logging.LogGenericInfo("Now farming: " + string.Join(", ", CurrentGamesFarming), Bot.BotName);
if (FarmHours(maxHour, CurrentGamesFarming)) {
CurrentGamesFarming.Clear();
CurrentGamesFarming.TrimExcess();
return true;
} else {
CurrentGamesFarming.Clear();
CurrentGamesFarming.TrimExcess();
return false;
}
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 hours;
if (GamesToFarm.TryRemove(appID, out hours)) {
TimeSpan timeSpan = TimeSpan.FromHours(hours);
Logging.LogGenericInfo("Done farming: " + appID + " after " + timeSpan.ToString(@"hh\:mm") + " hours of playtime!", Bot.BotName);
}
return true;
} else {
CurrentGamesFarming.Clear();
CurrentGamesFarming.TrimExcess();
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;
}
@@ -415,7 +427,7 @@ 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) {
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;
@@ -429,13 +441,13 @@ namespace ArchiSteamFarm {
Logging.LogGenericInfo("Still farming: " + appID, Bot.BotName);
}
Bot.ResetGamesPlayed();
Logging.LogGenericInfo("Stopped farming: " + appID, Bot.BotName);
return success;
}
private bool FarmHours(float maxHour, HashSet<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;
}
@@ -462,7 +474,6 @@ namespace ArchiSteamFarm {
Logging.LogGenericInfo("Still farming: " + string.Join(", ", appIDs), Bot.BotName);
}
Bot.ResetGamesPlayed();
Logging.LogGenericInfo("Stopped farming: " + string.Join(", ", appIDs), Bot.BotName);
return success;
}

View File

@@ -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();
}
}
}

View 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();
}
}

View File

@@ -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;

View File

@@ -25,11 +25,14 @@
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,
@@ -76,9 +79,6 @@ namespace ArchiSteamFarm {
[JsonProperty(Required = Required.DisallowNull)]
internal byte FarmingDelay { get; private set; } = DefaultFarmingDelay;
[JsonProperty(Required = Required.DisallowNull)]
internal byte AccountPlayingDelay { get; private set; } = 5;
[JsonProperty(Required = Required.DisallowNull)]
internal byte LoginLimiterDelay { get; private set; } = 7;
@@ -112,6 +112,7 @@ namespace ArchiSteamFarm {
internal static GlobalConfig Load(string filePath) {
if (string.IsNullOrEmpty(filePath)) {
Logging.LogNullError(nameof(filePath));
return null;
}
@@ -120,6 +121,7 @@ namespace ArchiSteamFarm {
}
GlobalConfig globalConfig;
try {
globalConfig = JsonConvert.DeserializeObject<GlobalConfig>(File.ReadAllText(filePath));
} catch (Exception e) {
@@ -128,6 +130,7 @@ namespace ArchiSteamFarm {
}
if (globalConfig == null) {
Logging.LogNullError(nameof(globalConfig));
return null;
}
@@ -160,11 +163,13 @@ namespace ArchiSteamFarm {
globalConfig.HttpTimeout = DefaultHttpTimeout;
}
if (globalConfig.WCFPort == 0) {
Logging.LogGenericWarning("Configured WCFPort is invalid: " + globalConfig.WCFPort + ". Value of " + DefaultWCFPort + " will be used instead");
globalConfig.WCFPort = DefaultWCFPort;
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;
}

View File

@@ -24,6 +24,7 @@
using Newtonsoft.Json;
using System;
using System.Diagnostics.CodeAnalysis;
using System.IO;
namespace ArchiSteamFarm {
@@ -49,6 +50,7 @@ namespace ArchiSteamFarm {
internal static GlobalDatabase Load(string filePath) {
if (string.IsNullOrEmpty(filePath)) {
Logging.LogNullError(nameof(filePath));
return null;
}
@@ -57,6 +59,7 @@ namespace ArchiSteamFarm {
}
GlobalDatabase globalDatabase;
try {
globalDatabase = JsonConvert.DeserializeObject<GlobalDatabase>(File.ReadAllText(filePath));
} catch (Exception e) {
@@ -65,6 +68,7 @@ namespace ArchiSteamFarm {
}
if (globalDatabase == null) {
Logging.LogNullError(nameof(globalDatabase));
return null;
}
@@ -75,7 +79,7 @@ namespace ArchiSteamFarm {
// This constructor is used when creating new database
private GlobalDatabase(string filePath) {
if (string.IsNullOrEmpty(filePath)) {
throw new ArgumentNullException("filePath");
throw new ArgumentNullException(nameof(filePath));
}
FilePath = filePath;
@@ -83,6 +87,7 @@ namespace ArchiSteamFarm {
}
// This constructor is used only by deserializer
[SuppressMessage("ReSharper", "UnusedMember.Local")]
private GlobalDatabase() { }
private void Save() {

View File

@@ -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; }

View File

@@ -22,11 +22,13 @@
*/
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
internal const ushort SteamAppID = 753;
@@ -46,13 +48,14 @@ namespace ArchiSteamFarm {
TradingCard
}
internal uint AppID;
internal uint AppID { get; set; }
[JsonProperty(PropertyName = "appid", Required = Required.DisallowNull)]
internal string AppIDString {
[JsonProperty(PropertyName = "appid", Required = Required.DisallowNull), SuppressMessage("ReSharper", "UnusedMember.Local")]
private string AppIDString {
get {
return AppID.ToString();
}
set {
if (string.IsNullOrEmpty(value)) {
return;
@@ -67,13 +70,14 @@ namespace ArchiSteamFarm {
}
}
internal ulong ContextID;
internal ulong ContextID { get; set; }
[JsonProperty(PropertyName = "contextid", Required = Required.DisallowNull)]
internal string ContextIDString {
[JsonProperty(PropertyName = "contextid", Required = Required.DisallowNull), SuppressMessage("ReSharper", "UnusedMember.Local")]
private string ContextIDString {
get {
return ContextID.ToString();
}
set {
if (string.IsNullOrEmpty(value)) {
return;
@@ -88,13 +92,14 @@ namespace ArchiSteamFarm {
}
}
internal ulong AssetID;
internal ulong AssetID { get; set; }
[JsonProperty(PropertyName = "assetid", Required = Required.DisallowNull)]
internal string AssetIDString {
private string AssetIDString {
get {
return AssetID.ToString();
}
set {
if (string.IsNullOrEmpty(value)) {
return;
@@ -109,19 +114,20 @@ namespace ArchiSteamFarm {
}
}
[JsonProperty(PropertyName = "id", Required = Required.DisallowNull)]
internal string ID {
[JsonProperty(PropertyName = "id", Required = Required.DisallowNull), SuppressMessage("ReSharper", "UnusedMember.Local")]
private string ID {
get { return AssetIDString; }
set { AssetIDString = value; }
}
internal ulong ClassID;
internal ulong ClassID { get; set; }
[JsonProperty(PropertyName = "classid", Required = Required.DisallowNull)]
internal string ClassIDString {
[JsonProperty(PropertyName = "classid", Required = Required.DisallowNull), SuppressMessage("ReSharper", "UnusedMember.Local")]
private string ClassIDString {
get {
return ClassID.ToString();
}
set {
if (string.IsNullOrEmpty(value)) {
return;
@@ -136,13 +142,14 @@ namespace ArchiSteamFarm {
}
}
internal ulong InstanceID;
internal ulong InstanceID { get; set; }
[JsonProperty(PropertyName = "instanceid", Required = Required.DisallowNull)]
internal string InstanceIDString {
[JsonProperty(PropertyName = "instanceid", Required = Required.DisallowNull), SuppressMessage("ReSharper", "UnusedMember.Local")]
private string InstanceIDString {
get {
return InstanceID.ToString();
}
set {
if (string.IsNullOrEmpty(value)) {
return;
@@ -157,13 +164,14 @@ namespace ArchiSteamFarm {
}
}
internal uint Amount;
internal uint Amount { get; set; }
[JsonProperty(PropertyName = "amount", Required = Required.Always)]
internal string AmountString {
[JsonProperty(PropertyName = "amount", Required = Required.Always), SuppressMessage("ReSharper", "UnusedMember.Local")]
private string AmountString {
get {
return Amount.ToString();
}
set {
if (string.IsNullOrEmpty(value)) {
return;
@@ -183,6 +191,7 @@ namespace ArchiSteamFarm {
}
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,
@@ -198,13 +207,14 @@ namespace ArchiSteamFarm {
OnHold
}
internal ulong TradeOfferID;
internal ulong TradeOfferID { get; set; }
[JsonProperty(PropertyName = "tradeofferid", Required = Required.Always)]
internal string TradeOfferIDString {
[JsonProperty(PropertyName = "tradeofferid", Required = Required.Always), SuppressMessage("ReSharper", "UnusedMember.Local")]
private string TradeOfferIDString {
get {
return TradeOfferID.ToString();
}
set {
if (string.IsNullOrEmpty(value)) {
return;
@@ -220,7 +230,7 @@ namespace ArchiSteamFarm {
}
[JsonProperty(PropertyName = "accountid_other", Required = Required.Always)]
internal uint OtherSteamID3 { get; set; }
internal uint OtherSteamID3 { private get; set; }
[JsonProperty(PropertyName = "trade_offer_state", Required = Required.Always)]
internal ETradeOfferState State { get; set; }
@@ -232,88 +242,57 @@ namespace ArchiSteamFarm {
internal HashSet<Item> ItemsToReceive { get; } = new HashSet<Item>();
// Extra
internal ulong OtherSteamID64 {
get {
if (OtherSteamID3 == 0) {
return 0;
}
internal ulong OtherSteamID64 => OtherSteamID3 == 0 ? 0 : new SteamID(OtherSteamID3, EUniverse.Public, EAccountType.Individual);
return new SteamID(OtherSteamID3, EUniverse.Public, EAccountType.Individual);
}
set {
if (value == 0) {
return;
}
internal bool IsSteamCardsOnlyTradeForUs() => ItemsToGive.All(item => (item.AppID == Item.SteamAppID) && (item.ContextID == Item.SteamContextID) && ((item.Type == Item.EType.FoilTradingCard) || (item.Type == Item.EType.TradingCard)));
OtherSteamID3 = new SteamID(value).AccountID;
}
}
internal bool IsSteamCardsOnlyTrade() {
internal bool IsPotentiallyDupesTradeForUs() {
Dictionary<uint, Dictionary<Item.EType, uint>> itemsToGivePerGame = new Dictionary<uint, Dictionary<Item.EType, uint>>();
foreach (Item item in ItemsToGive) {
if (item.AppID != Item.SteamAppID || item.ContextID != Item.SteamContextID || (item.Type != Item.EType.FoilTradingCard && item.Type != Item.EType.TradingCard)) {
return false;
}
}
foreach (Item item in ItemsToReceive) {
if (item.AppID != Item.SteamAppID || item.ContextID != Item.SteamContextID || (item.Type != Item.EType.FoilTradingCard && item.Type != Item.EType.TradingCard)) {
return false;
}
}
return true;
}
internal bool IsPotentiallyDupesTrade() {
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>();
ItemsPerType[item.Type] = item.Amount;
ItemsToGivePerGame[item.RealAppID] = ItemsPerType;
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;
if (itemsPerType.TryGetValue(item.Type, out amount)) {
itemsPerType[item.Type] = amount + item.Amount;
} else {
ItemsPerType[item.Type] = item.Amount;
itemsPerType[item.Type] = item.Amount;
}
}
}
Dictionary<uint, Dictionary<Item.EType, uint>> ItemsToReceivePerGame = new Dictionary<uint, Dictionary<Item.EType, uint>>();
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>();
ItemsPerType[item.Type] = item.Amount;
ItemsToReceivePerGame[item.RealAppID] = ItemsPerType;
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;
if (itemsPerType.TryGetValue(item.Type, out amount)) {
itemsPerType[item.Type] = amount + item.Amount;
} else {
ItemsPerType[item.Type] = item.Amount;
itemsPerType[item.Type] = item.Amount;
}
}
}
// Ensure that amount per type and per game matches
foreach (KeyValuePair<uint, Dictionary<Item.EType, uint>> ItemsPerGame in ItemsToGivePerGame) {
// 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)) {
if (!itemsToReceivePerGame.TryGetValue(itemsPerGame.Key, out otherItemsPerType)) {
return false;
}
foreach (KeyValuePair<Item.EType, uint> ItemsPerType in ItemsPerGame.Value) {
foreach (KeyValuePair<Item.EType, uint> itemsPerType in itemsPerGame.Value) {
uint otherAmount;
if (!otherItemsPerType.TryGetValue(ItemsPerType.Key, out otherAmount)) {
if (!otherItemsPerType.TryGetValue(itemsPerType.Key, out otherAmount)) {
return false;
}
if (ItemsPerType.Value != otherAmount) {
if (itemsPerType.Value > otherAmount) {
return false;
}
}
@@ -323,6 +302,7 @@ namespace ArchiSteamFarm {
}
}
[SuppressMessage("ReSharper", "UnusedMember.Global")]
internal sealed class TradeOfferRequest {
internal sealed class ItemList {
[JsonProperty(PropertyName = "assets", Required = Required.Always)]

View File

@@ -24,6 +24,7 @@
using System;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Runtime.CompilerServices;
@@ -36,73 +37,96 @@ namespace ArchiSteamFarm {
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);
}
}
}

View File

@@ -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 {
@@ -48,27 +50,27 @@ namespace ArchiSteamFarm {
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 GithubRepo = "JustArchi/ArchiSteamFarm";
internal const string GlobalConfigFile = ASF + ".json";
internal const string GlobalDatabaseFile = ASF + ".db";
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";
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 ManualResetEventSlim ShutdownResetEvent = new ManualResetEventSlim(false);
private static readonly string ExecutableFile = Assembly.GetEntryAssembly().Location;
private static readonly string ExecutableName = Path.GetFileName(ExecutableFile);
@@ -77,13 +79,13 @@ namespace ArchiSteamFarm {
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
@@ -108,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;
@@ -136,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;
}
@@ -154,19 +153,23 @@ 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);
@@ -184,15 +187,7 @@ namespace ArchiSteamFarm {
return;
}
GitHub.Asset binaryAsset = null;
foreach (var asset in releaseResponse.Assets) {
if (string.IsNullOrEmpty(asset.Name) || !asset.Name.Equals(ExecutableName, StringComparison.OrdinalIgnoreCase)) {
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!");
@@ -204,14 +199,8 @@ namespace ArchiSteamFarm {
return;
}
byte[] result = null;
for (byte i = 0; i < WebBrowser.MaxRetries && result == null; i++) {
Logging.LogGenericInfo("Downloading new version...");
result = await WebBrowser.UrlGetToBytes(binaryAsset.DownloadURL).ConfigureAwait(false);
}
byte[] result = await WebBrowser.UrlGetToBytesRetry(binaryAsset.DownloadURL).ConfigureAwait(false);
if (result == null) {
Logging.LogGenericWTF("Request failed even after " + WebBrowser.MaxRetries + " tries");
return;
}
@@ -233,7 +222,9 @@ namespace ArchiSteamFarm {
try {
// Cleanup
File.Delete(newExeFile);
} catch { }
} catch {
// Ignored
}
return;
}
@@ -246,7 +237,9 @@ namespace ArchiSteamFarm {
// Cleanup
File.Move(oldExeFile, ExecutableFile);
File.Delete(newExeFile);
} catch { }
} catch {
// Ignored
}
return;
}
@@ -278,15 +271,7 @@ namespace ArchiSteamFarm {
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(EUserInputType userInputType, string botName = null, string extraInformation = null) {
internal static string GetUserInput(EUserInputType userInputType, string botName = "Main", string extraInformation = null) {
if (userInputType == EUserInputType.Unknown) {
return null;
}
@@ -301,55 +286,56 @@ namespace ArchiSteamFarm {
ConsoleIsBusy = true;
switch (userInputType) {
case EUserInputType.DeviceID:
Console.Write((string.IsNullOrEmpty(botName) ? "" : "<" + botName + "> ") + "Please enter your Device ID (including \"android:\"): ");
Console.Write("<" + botName + "> Please enter your Device ID (including \"android:\"): ");
break;
case EUserInputType.Login:
Console.Write((string.IsNullOrEmpty(botName) ? "" : "<" + botName + "> ") + "Please enter your login: ");
Console.Write("<" + botName + "> Please enter your login: ");
break;
case EUserInputType.Password:
Console.Write((string.IsNullOrEmpty(botName) ? "" : "<" + botName + "> ") + "Please enter your password: ");
Console.Write("<" + botName + "> Please enter your password: ");
break;
case EUserInputType.PhoneNumber:
Console.Write((string.IsNullOrEmpty(botName) ? "" : "<" + botName + "> ") + "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((string.IsNullOrEmpty(botName) ? "" : "<" + botName + "> ") + "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((string.IsNullOrEmpty(botName) ? "" : "<" + botName + "> ") + "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((string.IsNullOrEmpty(botName) ? "" : "<" + botName + "> ") + "Please enter steam parental PIN: ");
Console.Write("<" + botName + "> Please enter steam parental PIN: ");
break;
case EUserInputType.RevocationCode:
Console.WriteLine((string.IsNullOrEmpty(botName) ? "" : "<" + botName + "> ") + "PLEASE WRITE DOWN YOUR REVOCATION CODE: " + extraInformation);
Console.Write("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((string.IsNullOrEmpty(botName) ? "" : "<" + botName + "> ") + "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((string.IsNullOrEmpty(botName) ? "" : "<" + botName + "> ") + "Please enter your WCF hostname: ");
Console.Write("<" + botName + "> Please enter your WCF hostname: ");
break;
default:
Console.Write((string.IsNullOrEmpty(botName) ? "" : "<" + botName + "> ") + "Please enter not documented yet value of \"" + userInputType + "\": ");
Console.Write("<" + botName + "> Please enter not documented yet value of \"" + userInputType + "\": ");
break;
}
result = Console.ReadLine();
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()) {
@@ -383,9 +369,16 @@ namespace ArchiSteamFarm {
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;
@@ -394,7 +387,7 @@ namespace ArchiSteamFarm {
WCF.StartServer();
break;
default:
if (arg.StartsWith("--")) {
if (arg.StartsWith("--", StringComparison.Ordinal)) {
Logging.LogGenericWarning("Unrecognized parameter: " + arg);
continue;
}
@@ -419,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;
}
@@ -427,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;
@@ -446,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;
@@ -467,12 +462,14 @@ 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) {
@@ -495,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":
@@ -505,10 +501,12 @@ namespace ArchiSteamFarm {
}
Bot bot = new Bot(botName);
if (bot.BotConfig != null && bot.BotConfig.Enabled) {
if ((bot.BotConfig == null) || !bot.BotConfig.Enabled) {
continue;
}
if (bot.BotConfig.StartOnLaunch) {
isRunning = true;
} else {
Logging.LogGenericInfo("Not starting this instance because it's disabled in config file", botName);
}
}

View File

@@ -1,5 +1,4 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
@@ -32,5 +31,5 @@ using System.Runtime.InteropServices;
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("2.0.4.0")]
[assembly: AssemblyFileVersion("2.0.4.0")]
[assembly: AssemblyVersion("2.0.5.0")]
[assembly: AssemblyFileVersion("2.0.5.0")]

View File

@@ -25,8 +25,10 @@
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 {
@@ -37,7 +39,6 @@ namespace ArchiSteamFarm {
private readonly Bot Bot;
private readonly SemaphoreSlim TradesSemaphore = new SemaphoreSlim(1);
private readonly HashSet<ulong> RecentlyParsedTrades = new HashSet<ulong>();
private byte ParsingTasks;
@@ -51,23 +52,19 @@ namespace ArchiSteamFarm {
internal Trading(Bot bot) {
if (bot == null) {
throw new ArgumentNullException("bot");
throw new ArgumentNullException(nameof(bot));
}
Bot = bot;
}
internal async Task CheckTrades() {
bool shouldRun = false;
lock (TradesSemaphore) {
if (ParsingTasks < 2) {
ParsingTasks++;
shouldRun = true;
if (ParsingTasks >= 2) {
return;
}
}
if (!shouldRun) {
return;
ParsingTasks++;
}
await TradesSemaphore.WaitAsync().ConfigureAwait(false);
@@ -80,42 +77,30 @@ namespace ArchiSteamFarm {
TradesSemaphore.Release();
}
private async Task ForgetRecentTrade(ulong tradeID) {
await Utilities.SleepAsync(24 * 60 * 60 * 1000).ConfigureAwait(false);
lock (RecentlyParsedTrades) {
RecentlyParsedTrades.Remove(tradeID);
RecentlyParsedTrades.TrimExcess();
}
}
private async Task ParseActiveTrades() {
HashSet<Steam.TradeOffer> tradeOffers = Bot.ArchiWebHandler.GetTradeOffers();
if (tradeOffers == null || tradeOffers.Count == 0) {
if ((tradeOffers == null) || (tradeOffers.Count == 0)) {
return;
}
lock (RecentlyParsedTrades) {
tradeOffers.RemoveWhere(trade => RecentlyParsedTrades.Contains(trade.TradeOfferID));
}
tradeOffers.RemoveWhere(tradeoffer => tradeoffer.State != Steam.TradeOffer.ETradeOfferState.Active);
tradeOffers.TrimExcess();
if (tradeOffers.Count == 0) {
return;
}
foreach (Steam.TradeOffer tradeOffer in tradeOffers) {
lock (RecentlyParsedTrades) {
RecentlyParsedTrades.Add(tradeOffer.TradeOfferID);
}
ForgetRecentTrade(tradeOffer.TradeOfferID).Forget();
}
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 || tradeOffer.State != Steam.TradeOffer.ETradeOfferState.Active) {
if (tradeOffer == null) {
Logging.LogNullError(nameof(tradeOffer), Bot.BotName);
return;
}
if (tradeOffer.State != Steam.TradeOffer.ETradeOfferState.Active) {
return;
}
@@ -129,6 +114,7 @@ namespace ArchiSteamFarm {
private async Task<bool> ShouldAcceptTrade(Steam.TradeOffer tradeOffer) {
if (tradeOffer == null) {
Logging.LogNullError(nameof(tradeOffer), Bot.BotName);
return false;
}
@@ -139,7 +125,7 @@ namespace ArchiSteamFarm {
}
// Always accept trades from SteamMasterID
if (tradeOffer.OtherSteamID64 != 0 && tradeOffer.OtherSteamID64 == Bot.BotConfig.SteamMasterID) {
if ((tradeOffer.OtherSteamID64 != 0) && (tradeOffer.OtherSteamID64 == Bot.BotConfig.SteamMasterID)) {
return true;
}
@@ -148,31 +134,29 @@ namespace ArchiSteamFarm {
return false;
}
// Rule 1 - We always trade the same amount of items
if (tradeOffer.ItemsToGive.Count != tradeOffer.ItemsToReceive.Count) {
// Decline trade if we're giving more count-wise
if (tradeOffer.ItemsToGive.Count > tradeOffer.ItemsToReceive.Count) {
return false;
}
// Rule 2 - We always trade steam cards and only for the same set
if (!tradeOffer.IsSteamCardsOnlyTrade() || !tradeOffer.IsPotentiallyDupesTrade()) {
// Decline trade if we're losing anything but steam cards, or if it's non-dupes trade
if (!tradeOffer.IsSteamCardsOnlyTradeForUs() || !tradeOffer.IsPotentiallyDupesTradeForUs()) {
return false;
}
// 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) {
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>();
foreach (Steam.Item item in tradeOffer.ItemsToGive) {
appIDs.Add(item.RealAppID);
}
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) {
@@ -180,47 +164,51 @@ namespace ArchiSteamFarm {
}
// Now let's create a map which maps items to their amount in our EQ
Dictionary<Tuple<ulong, ulong>, uint> amountMap = new Dictionary<Tuple<ulong, ulong>, uint>();
Dictionary<ulong, uint> amountMap = new Dictionary<ulong, uint>();
foreach (Steam.Item item in inventory) {
Tuple<ulong, ulong> key = new Tuple<ulong, ulong>(item.ClassID, item.InstanceID);
uint amount;
if (amountMap.TryGetValue(key, out amount)) {
amountMap[key] = amount + item.Amount;
if (amountMap.TryGetValue(item.ClassID, out amount)) {
amountMap[item.ClassID] = amount + item.Amount;
} else {
amountMap[key] = item.Amount;
amountMap[item.ClassID] = item.Amount;
}
}
// Calculate our value of items to give
uint itemsToGiveDupesValue = 0;
foreach (Steam.Item item in tradeOffer.ItemsToGive) {
Tuple<ulong, ulong> key = new Tuple<ulong, ulong>(item.ClassID, item.InstanceID);
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;
}
itemsToGiveDupesValue += amount;
amountsToGive.Add(amount);
}
// Sort it ascending
amountsToGive.Sort();
// Calculate our value of items to receive
uint itemsToReceiveDupesValue = 0;
foreach (Steam.Item item in tradeOffer.ItemsToReceive) {
Tuple<ulong, ulong> key = new Tuple<ulong, ulong>(item.ClassID, item.InstanceID);
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;
}
itemsToReceiveDupesValue += amount;
amountsToReceive.Add(amount);
}
// Trade is worth for us if we're in total trading more of our dupes for less of our dupes (or at least same amount)
// Which means that itemsToGiveDupesValue should be greater than itemsToReceiveDupesValue
return itemsToGiveDupesValue > itemsToReceiveDupesValue;
// Sort it ascending
amountsToReceive.Sort();
// Check actual difference
int difference = amountsToGive.Select((t, i) => (int) (t - amountsToReceive[i])).Sum();
// Trade is worth for us if the difference is greater than 0
return difference > 0;
}
}
}

View File

@@ -24,49 +24,51 @@
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 Task ForEachAsync<T>(this IEnumerable<T> sequence, Func<T, Task> action) {
if (action == null) {
return Task.FromResult(true);
if (action != null) {
return Task.WhenAll(sequence.Select(action));
}
return Task.WhenAll(sequence.Select(action));
Logging.LogNullError(nameof(action));
return Task.FromResult(true);
}
internal static string GetCookieValue(this CookieContainer cookieContainer, string URL, string name) {
if (string.IsNullOrEmpty(URL) || string.IsNullOrEmpty(name)) {
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;
}
CookieCollection cookies = cookieContainer.GetCookies(new Uri(URL));
if (cookies == null || cookies.Count == 0) {
Uri uri;
try {
uri = new Uri(url);
} catch (UriFormatException e) {
Logging.LogGenericException(e);
return null;
}
foreach (Cookie cookie in cookies) {
if (!cookie.Name.Equals(name, StringComparison.Ordinal)) {
continue;
}
return cookie.Value;
}
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 Task SleepAsync(int miliseconds) {
if (miliseconds < 0) {
return Task.FromResult(true);
if (miliseconds >= 0) {
return Task.Delay(miliseconds);
}
return Task.Delay(miliseconds);
Logging.LogNullError(nameof(miliseconds));
return Task.FromResult(true);
}
}
}

View File

@@ -52,9 +52,7 @@ namespace ArchiSteamFarm {
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) {
@@ -89,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));
}
@@ -98,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);
@@ -134,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) {

View File

@@ -27,7 +27,6 @@ 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.Threading.Tasks;
@@ -65,7 +64,7 @@ namespace ArchiSteamFarm {
internal WebBrowser(string identifier) {
if (string.IsNullOrEmpty(identifier)) {
throw new ArgumentNullException("identifier");
throw new ArgumentNullException(nameof(identifier));
}
Identifier = identifier;
@@ -83,42 +82,161 @@ namespace ArchiSteamFarm {
HttpClient.DefaultRequestHeaders.UserAgent.ParseAdd(DefaultUserAgent);
}
internal async Task<bool> UrlGet(string request, string referer = null) {
internal async Task<bool> UrlHeadRetry(string request, string referer = null) {
if (string.IsNullOrEmpty(request)) {
Logging.LogNullError(nameof(request));
return false;
}
using (HttpResponseMessage response = await UrlGetToResponse(request, referer).ConfigureAwait(false)) {
return response != null;
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 async Task<bool> UrlPost(string request, Dictionary<string, string> data = null, string referer = null) {
if (string.IsNullOrEmpty(request)) {
return false;
}
using (HttpResponseMessage response = await UrlPostToResponse(request, data, referer).ConfigureAwait(false)) {
return response != null;
}
}
internal async Task<string> UrlGetToContent(string request, string referer = null) {
internal async Task<Uri> UrlHeadToUriRetry(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);
Uri result = null;
for (byte i = 0; (i < MaxRetries) && (result == null); i++) {
result = await UrlHeadToUri(request, referer).ConfigureAwait(false);
}
if (result != null) {
return result;
}
Logging.LogGenericWTF("Request failed even after " + MaxRetries + " tries", Identifier);
return null;
}
internal async Task<byte[]> UrlGetToBytes(string request, string referer = null) {
internal async Task<byte[]> UrlGetToBytesRetry(string request, string referer = null) {
if (string.IsNullOrEmpty(request)) {
Logging.LogNullError(nameof(request));
return null;
}
byte[] result = null;
for (byte i = 0; (i < MaxRetries) && (result == null); i++) {
result = await UrlGetToBytes(request, referer).ConfigureAwait(false);
}
if (result != null) {
return result;
}
Logging.LogGenericWTF("Request failed even after " + MaxRetries + " tries", Identifier);
return null;
}
internal async Task<string> UrlGetToContentRetry(string request, string referer = null) {
if (string.IsNullOrEmpty(request)) {
Logging.LogNullError(nameof(request));
return null;
}
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;
}
@@ -131,8 +249,24 @@ namespace ArchiSteamFarm {
}
}
internal async Task<HtmlDocument> UrlGetToHtmlDocument(string request, string referer = null) {
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;
}
@@ -146,8 +280,9 @@ namespace ArchiSteamFarm {
return htmlDocument;
}
internal async Task<JObject> UrlGetToJObject(string request, string referer = null) {
private async Task<JObject> UrlGetToJObject(string request, string referer = null) {
if (string.IsNullOrEmpty(request)) {
Logging.LogNullError(nameof(request));
return null;
}
@@ -168,8 +303,18 @@ namespace ArchiSteamFarm {
return jObject;
}
internal async Task<XmlDocument> UrlGetToXML(string request, 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;
}
@@ -190,24 +335,60 @@ namespace ArchiSteamFarm {
return xmlDocument;
}
private async Task<HttpResponseMessage> UrlGetToResponse(string request, string referer = 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;
}
return await UrlRequest(request, HttpMethod.Get, null, referer).ConfigureAwait(false);
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 null;
if (!string.IsNullOrEmpty(request)) {
return await UrlRequest(request, HttpMethod.Post, data, referer).ConfigureAwait(false);
}
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) {
if (string.IsNullOrEmpty(request) || (httpMethod == null)) {
Logging.LogNullError(nameof(request) + " || " + nameof(httpMethod));
return null;
}
@@ -217,7 +398,7 @@ namespace ArchiSteamFarm {
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) {
@@ -241,17 +422,18 @@ namespace ArchiSteamFarm {
return null;
}
if (!responseMessage.IsSuccessStatusCode) {
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;
if (responseMessage.IsSuccessStatusCode) {
return responseMessage;
}
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;
}
}
}

View File

@@ -9,7 +9,6 @@
"MaxFarmingTime": 10,
"IdleFarmingPeriod": 3,
"FarmingDelay": 5,
"AccountPlayingDelay": 5,
"LoginLimiterDelay": 7,
"InventoryLimiterDelay": 3,
"ForceHttp": false,

View File

@@ -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>

View File

@@ -28,7 +28,7 @@ using System.Collections.Generic;
using System.IO;
namespace ConfigGenerator {
internal class ASFConfig {
internal abstract class ASFConfig {
internal static readonly HashSet<ASFConfig> ASFConfigs = new HashSet<ASFConfig>();
internal string FilePath { get; set; }
@@ -39,13 +39,13 @@ namespace ConfigGenerator {
protected ASFConfig(string filePath) : this() {
if (string.IsNullOrEmpty(filePath)) {
throw new ArgumentNullException("filePath");
throw new ArgumentNullException(nameof(filePath));
}
FilePath = filePath;
}
internal virtual void Save() {
internal void Save() {
lock (FilePath) {
try {
File.WriteAllText(FilePath, JsonConvert.SerializeObject(this, Formatting.Indented));
@@ -55,7 +55,7 @@ namespace ConfigGenerator {
}
}
internal virtual void Remove() {
internal void Remove() {
string queryPath = Path.GetFileNameWithoutExtension(FilePath);
lock (FilePath) {
foreach (string botFile in Directory.EnumerateFiles(Program.ConfigDirectory, queryPath + ".*")) {
@@ -66,11 +66,13 @@ namespace ConfigGenerator {
}
}
}
ASFConfigs.Remove(this);
}
internal virtual void Rename(string botName) {
internal void Rename(string botName) {
if (string.IsNullOrEmpty(botName)) {
Logging.LogNullError(nameof(botName));
return;
}
@@ -83,6 +85,7 @@ namespace ConfigGenerator {
Logging.LogGenericException(e);
}
}
FilePath = Path.Combine(Program.ConfigDirectory, botName + ".json");
}
}

View File

@@ -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]
@@ -103,6 +106,7 @@ namespace ConfigGenerator {
internal static BotConfig Load(string filePath) {
if (string.IsNullOrEmpty(filePath)) {
Logging.LogNullError(nameof(filePath));
return null;
}
@@ -111,6 +115,7 @@ namespace ConfigGenerator {
}
BotConfig botConfig;
try {
botConfig = JsonConvert.DeserializeObject<BotConfig>(File.ReadAllText(filePath));
} catch (Exception e) {
@@ -127,12 +132,12 @@ namespace ConfigGenerator {
return botConfig;
}
// This constructor is used only by deserializer
[SuppressMessage("ReSharper", "UnusedMember.Local")]
private BotConfig() { }
private BotConfig(string filePath) : base(filePath) {
if (string.IsNullOrEmpty(filePath)) {
throw new ArgumentNullException("filePath");
throw new ArgumentNullException(nameof(filePath));
}
GamesPlayedWhileIdle.Add(0);

View File

@@ -38,8 +38,8 @@
<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" />
@@ -83,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">
@@ -108,7 +109,7 @@
del "$(SolutionDir)out\ASF-ConfigGenerator.exe.config"
</PostBuildEvent>
<PostBuildEvent Condition=" '$(OS)' == 'Unix' AND '$(ConfigurationName)' == 'Release' ">
mono -O=all "$(SolutionDir)tools/ILRepack/ILRepack.exe" /ndebug /internalize /parallel /targetplatform:v4 /wildcards /out:"$(SolutionDir)out/ASF-ConfigGenerator.exe" "$(TargetDir)$(TargetName).exe" "$(TargetDir)*.dll"
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>

View File

@@ -22,16 +22,17 @@
*/
using System;
using System.IO;
using System.Windows.Forms;
namespace ConfigGenerator {
internal class ConfigPage : TabPage {
internal sealed class ConfigPage : TabPage {
internal readonly ASFConfig ASFConfig;
internal ConfigPage(ASFConfig config) {
if (config == null) {
return;
throw new ArgumentNullException(nameof(config));
}
ASFConfig = config;
@@ -42,8 +43,6 @@ namespace ConfigGenerator {
Controls.Add(enhancedPropertyGrid);
}
internal void RefreshText() {
Text = Path.GetFileNameWithoutExtension(ASFConfig.FilePath);
}
internal void RefreshText() => Text = Path.GetFileNameWithoutExtension(ASFConfig.FilePath);
}
}

View File

@@ -22,14 +22,16 @@
*/
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;
}
}

View File

@@ -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;

View File

@@ -31,7 +31,7 @@ namespace ConfigGenerator {
internal EnhancedPropertyGrid(ASFConfig config) {
if (config == null) {
throw new ArgumentNullException("config");
throw new ArgumentNullException(nameof(config));
}
ASFConfig = config;
@@ -43,39 +43,45 @@ 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);
}
}
}
protected override void OnGotFocus(EventArgs e) {
if (e == null) {
if (globalConfig == null) {
return;
}
base.OnGotFocus(e);
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();
}
}

View File

@@ -25,11 +25,14 @@
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,
@@ -43,7 +46,7 @@ namespace ConfigGenerator {
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;
@@ -75,9 +78,6 @@ namespace ConfigGenerator {
[JsonProperty(Required = Required.DisallowNull)]
public byte FarmingDelay { get; set; } = DefaultFarmingDelay;
[JsonProperty(Required = Required.DisallowNull)]
public byte AccountPlayingDelay { get; set; } = 5;
[JsonProperty(Required = Required.DisallowNull)]
public byte LoginLimiterDelay { get; set; } = 7;
@@ -102,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;
@@ -111,6 +110,7 @@ namespace ConfigGenerator {
internal static GlobalConfig Load(string filePath) {
if (string.IsNullOrEmpty(filePath)) {
Logging.LogNullError(nameof(filePath));
return null;
}
@@ -119,6 +119,7 @@ namespace ConfigGenerator {
}
GlobalConfig globalConfig;
try {
globalConfig = JsonConvert.DeserializeObject<GlobalConfig>(File.ReadAllText(filePath));
} catch (Exception e) {
@@ -161,20 +162,22 @@ namespace ConfigGenerator {
globalConfig.HttpTimeout = DefaultHttpTimeout;
}
if (globalConfig.WCFPort == 0) {
Logging.LogGenericWarning("Configured WCFPort is invalid: " + globalConfig.WCFPort + ". Value of " + DefaultWCFPort + " will be used instead");
globalConfig.WCFPort = DefaultWCFPort;
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
[SuppressMessage("ReSharper", "UnusedMember.Local")]
private GlobalConfig() { }
private GlobalConfig(string filePath) : base(filePath) {
if (string.IsNullOrEmpty(filePath)) {
throw new ArgumentNullException("filePath");
throw new ArgumentNullException(nameof(filePath));
}
Blacklist.AddRange(GlobalBlacklist);

View File

@@ -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);
}
}
}

View File

@@ -26,26 +26,28 @@ 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 readonly TabPage NewTab = new TabPage { Text = @"+" };
private readonly TabPage RemoveTab = new TabPage { Text = @"-" };
private readonly TabPage RenameTab = new TabPage { Text = @"~" };
private ConfigPage ASFTab;
private TabPage OldTab;
public MainForm() {
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;
}
@@ -53,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:
@@ -70,12 +72,13 @@ namespace ConfigGenerator {
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;
@@ -84,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;
}
@@ -97,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;
@@ -106,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;
}
@@ -118,7 +121,7 @@ namespace ConfigGenerator {
}
if (string.IsNullOrEmpty(input)) {
Logging.LogGenericError("Your bot name is empty!");
Logging.LogGenericErrorWithoutStacktrace("Your bot name is empty!");
return;
}
@@ -127,7 +130,7 @@ namespace ConfigGenerator {
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;
@@ -144,18 +147,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+", "");
foreach (ASFConfig config in ASFConfig.ASFConfigs) {
if (Path.GetFileNameWithoutExtension(config.FilePath).Equals(input)) {
Logging.LogGenericError("Bot with such name exists already!");
return;
}
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");
@@ -164,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, 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);

View File

@@ -61,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
@@ -73,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;
}
@@ -88,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;
}

View File

@@ -1,5 +1,4 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following

View File

@@ -9,54 +9,127 @@
//------------------------------------------------------------------------------
namespace ConfigGenerator.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 {
/// <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.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture;
private static global::System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal Resources() {
}
[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>
/// 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>
/// 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);
}
}
}
}

View File

@@ -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>

View File

@@ -38,12 +38,12 @@ namespace ConfigGenerator {
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("Well done! 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("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.");
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("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!");
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 [-]. 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;
}

View File

@@ -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>

View File

@@ -135,16 +135,6 @@
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<PropertyGroup>
<!--
<PostBuildEvent Condition=" '$(OS)' != 'Unix' AND '$(ConfigurationName)' == 'Release' ">
"$(SolutionDir)tools\ILRepack\ILRepack.exe" /ndebug /internalize /parallel /targetplatform:v4 /wildcards /out:"$(SolutionDir)out\ASF-GUI.exe" "$(TargetDir)$(TargetName).exe" "$(TargetDir)*.dll"
del "$(SolutionDir)out\ASF-GUI.exe.config"
</PostBuildEvent>
<PostBuildEvent Condition=" '$(OS)' == 'Unix' AND '$(ConfigurationName)' == 'Release' ">
mono -O=all "$(SolutionDir)tools/ILRepack/ILRepack.exe" /ndebug /internalize /parallel /targetplatform:v4 /wildcards /out:"$(SolutionDir)out/ASF-GUI.exe" "$(TargetDir)$(TargetName).exe" "$(TargetDir)*.dll"
rm "$(SolutionDir)out/ASF-GUI.exe.config"
</PostBuildEvent>
-->
</PropertyGroup>
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.

View File

@@ -10,44 +10,41 @@ ArchiSteamFarm
---
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.
- 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)
**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)
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).

View File

@@ -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" />

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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"/>.

View File

@@ -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"/>.

6
run.sh
View File

@@ -18,6 +18,12 @@ for ARG in "$@"; do
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