Compare commits

...

51 Commits

Author SHA1 Message Date
JustArchi
6a12a26612 WCF: Make it possible to launch also non-targetted commands 2016-01-07 22:29:55 +01:00
JustArchi
533058aa3f Always initialize CM list from SteamDirectory, closes #65, thanks to @xPaw 2016-01-07 22:08:06 +01:00
JustArchi
804d1260f2 Misc 2016-01-07 05:46:31 +01:00
JustArchi
78fcf53606 Improve config help a little 2016-01-07 04:18:06 +01:00
JustArchi
ceb641d1fa WCF 2/2 2016-01-04 00:02:18 +01:00
JustArchi
47fdff2993 WCF 1.5/2 2016-01-03 22:23:30 +01:00
JustArchi
1a96a975f9 WCF 1/2
Server part done
2016-01-03 20:36:13 +01:00
JustArchi
cd460c5ec5 Sync more code with ArchiBoT 2016-01-02 17:31:55 +01:00
JustArchi
70b7f9d5dd Misc 2016-01-02 17:23:30 +01:00
JustArchi
f236d6c33f Sync with ArchiBoT, closes #58 2016-01-02 17:22:35 +01:00
JustArchi
356df9098e Update packages 2016-01-02 17:05:39 +01:00
JustArchi
9a8aa1e10d Misc 2016-01-01 12:49:41 +01:00
JustArchi
7aa985154f Always navigate to executable location first 2016-01-01 12:46:49 +01:00
JustArchi
d287674d69 Fix crash 2015-12-28 15:52:58 +01:00
JustArchi
40b1e8f4c2 Update packages 2015-12-28 11:35:14 +01:00
JustArchi
d38fde0359 Fix ASF not farming accounts with more than 6 pages 2015-12-28 11:30:48 +01:00
JustArchi
e6015ca999 Bump 2015-12-25 17:49:15 +01:00
JustArchi
3bcecc6256 Keep reconnecting if logging in to ISteamUserAuth fails 2015-12-25 17:49:00 +01:00
JustArchi
6cf264dcf7 Misc 2015-12-23 16:34:57 +01:00
JustArchi
b12db11956 Bump to 1.2.1 2015-12-23 11:02:54 +01:00
JustArchi
591d665d56 Fix #47 2015-12-23 10:58:14 +01:00
Łukasz Domeradzki
327cae955a Update README.md 2015-12-23 09:45:12 +01:00
JustArchi
9fa23ecddf Use Global Blacklist 2015-12-23 09:40:42 +01:00
JustArchi
ab3bfe2460 Misc 2015-12-22 19:13:04 +01:00
JustArchi
465ca2d4f9 Misc 2015-12-22 18:32:48 +01:00
JustArchi
21e892c042 Misc 2015-12-22 18:24:26 +01:00
JustArchi
98be9e1efd Rewrite core CF module 2015-12-22 16:51:37 +01:00
JustArchi
3081bfe814 Fix my fuckup 2015-12-22 12:44:14 +01:00
JustArchi
61e4461bc4 1.2 bump 2015-12-22 12:29:31 +01:00
JustArchi
5c2bcd551c Try to hunt down a bug 2015-12-22 12:29:14 +01:00
JustArchi
15f9eb4e80 Add support for chatrooms and invites 2015-12-21 19:28:59 +01:00
JustArchi
5038527c90 Handle offline messages, closes #42 2015-12-21 10:55:55 +01:00
JustArchi
e8370987ea State the origin of 0xBAADF00D clearly 2015-12-21 10:24:29 +01:00
JustArchi
3f7660526d Add internal logging, closes #44 2015-12-21 10:19:47 +01:00
JustArchi
f484b50ab3 Get rid of HackedLogOn, set shared LoginID, closes #35, closes #37 2015-12-21 10:06:37 +01:00
JustArchi
55000c7653 Remove debugging 2015-12-21 10:02:05 +01:00
JustArchi
4cd2444a1a SK2 1.7.0 2015-12-21 10:00:29 +01:00
JustArchi
4f23d2e874 Misc 2015-12-21 09:31:05 +01:00
JustArchi
76bdd898e1 Add extra logging 2015-12-21 09:28:59 +01:00
JustArchi
a45cf02d52 OCD 2015-12-20 19:50:54 +01:00
JustArchi
828c76e201 Prepare for offline messages 2015-12-20 19:48:58 +01:00
JustArchi
32e68f2be3 Add offline farming, closes #41 2015-12-20 19:01:05 +01:00
JustArchi
de3f3cd93b ILMerge 2.14.1208 2015-12-19 10:08:53 +01:00
JustArchi
31fb6fec08 ILMerge cleanup 2015-12-19 09:58:58 +01:00
JustArchi
cf2473a3d5 Revert "Get rid of ILMerge, use more friendly ILBundle"
This reverts commit 43264e77b2.

Doesn't work on Mono, sigh...
2015-12-19 08:58:31 +01:00
JustArchi
0d44379948 Bump to 1.1 2015-12-19 08:22:40 +01:00
JustArchi
43264e77b2 Get rid of ILMerge, use more friendly ILBundle 2015-12-19 08:22:17 +01:00
JustArchi
c09af9b937 Misc 2015-12-19 07:07:08 +01:00
JustArchi
c84565f091 Misc code review 2015-12-18 15:50:10 +01:00
JustArchi
d07f1c6852 Internal ASF modules should be readonly 2015-12-18 14:54:14 +01:00
JustArchi
754b52647b Do not attempt farming if steam client is not connected, closes #36 2015-12-18 14:46:28 +01:00
49 changed files with 12555 additions and 11910 deletions

3
.gitignore vendored
View File

@@ -7,6 +7,9 @@ ArchiSteamFarm/config/*
!ArchiSteamFarm/config/example.xml
!ArchiSteamFarm/config/minimal.xml
# Ignore local debugging log file
ArchiSteamFarm/log.txt
#################
## Eclipse
#################

View File

@@ -24,12 +24,63 @@
using SteamKit2;
using SteamKit2.Internal;
using System;
using System.Collections.Generic;
using System.IO;
namespace ArchiSteamFarm {
internal sealed class ArchiHandler : ClientMsgHandler {
/*
____ _ _ _ _
/ ___| __ _ | || || |__ __ _ ___ | | __ ___
| | / _` || || || '_ \ / _` | / __|| |/ // __|
| |___| (_| || || || |_) || (_| || (__ | < \__ \
\____|\__,_||_||_||_.__/ \__,_| \___||_|\_\|___/
*/
internal sealed class NotificationsCallback : CallbackMsg {
internal class Notification {
internal enum ENotificationType {
Unknown = 0,
Trading = 1,
}
internal ENotificationType NotificationType { get; set; }
}
internal List<Notification> Notifications { get; private set; }
internal NotificationsCallback(JobID jobID, CMsgClientUserNotifications msg) {
JobID = jobID;
if (msg == null) {
return;
}
Notifications = new List<Notification>();
foreach (var notification in msg.notifications) {
Notifications.Add(new Notification {
NotificationType = (Notification.ENotificationType) notification.user_notification_type
});
}
}
}
internal sealed class OfflineMessageCallback : CallbackMsg {
internal uint OfflineMessages { get; private set; }
internal List<uint> Users { get; private set; }
internal OfflineMessageCallback(JobID jobID, CMsgClientOfflineMessageNotification msg) {
JobID = jobID;
if (msg == null) {
return;
}
OfflineMessages = msg.offline_messages;
Users = msg.friends_with_offline_messages;
}
}
internal sealed class PurchaseResponseCallback : CallbackMsg {
internal enum EPurchaseResult {
@@ -45,14 +96,23 @@ namespace ArchiSteamFarm {
internal EResult Result { get; private set; }
internal EPurchaseResult PurchaseResult { get; private set; }
internal KeyValue ReceiptInfo { get; private set; } = new KeyValue();
internal Dictionary<uint, string> Items { get; private set; } = new Dictionary<uint, string>();
internal KeyValue ReceiptInfo { get; private set; }
internal Dictionary<uint, string> Items { get; private set; }
internal PurchaseResponseCallback(CMsgClientPurchaseResponse body) {
Result = (EResult) body.eresult;
PurchaseResult = (EPurchaseResult) body.purchase_result_details;
internal PurchaseResponseCallback(JobID jobID, CMsgClientPurchaseResponse msg) {
JobID = jobID;
using (MemoryStream ms = new MemoryStream(body.purchase_receipt_info)) {
if (msg == null) {
return;
}
ReceiptInfo = new KeyValue();
Items = new Dictionary<uint, string>();
Result = (EResult) msg.eresult;
PurchaseResult = (EPurchaseResult) msg.purchase_result_details;
using (MemoryStream ms = new MemoryStream(msg.purchase_receipt_info)) {
if (!ReceiptInfo.TryReadAsBinary(ms)) {
return;
}
@@ -64,30 +124,36 @@ namespace ArchiSteamFarm {
}
}
internal sealed class NotificationCallback : CallbackMsg {
internal enum ENotificationType {
Unknown = 0,
Trading = 1,
}
/*
__ __ _ _ _
| \/ | ___ | |_ | |__ ___ __| | ___
| |\/| | / _ \| __|| '_ \ / _ \ / _` |/ __|
| | | || __/| |_ | | | || (_) || (_| |\__ \
|_| |_| \___| \__||_| |_| \___/ \__,_||___/
internal ENotificationType NotificationType { get; private set; }
internal NotificationCallback(CMsgClientUserNotifications.Notification body) {
NotificationType = (ENotificationType) body.user_notification_type;
}
}
*/
internal void AcceptClanInvite(ulong clanID) {
if (clanID == 0) {
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) {
return;
}
var request = new ClientMsg<CMsgClientClanInviteAction>((int) EMsg.ClientAcknowledgeClanInvite);
request.Body.GroupID = clanID;
request.Body.AcceptInvite = false;
Client.Send(request);
}
@@ -102,6 +168,7 @@ namespace ArchiSteamFarm {
game_id = new GameID(gameID),
});
}
Client.Send(request);
}
@@ -116,22 +183,41 @@ namespace ArchiSteamFarm {
game_id = new GameID(gameID),
});
}
Client.Send(request);
}
// Will provide result in ClientPurchaseResponse, regardless if success or not
internal void RedeemKey(string key) {
var request = new ClientMsgProtobuf<CMsgClientRegisterKey>(EMsg.ClientRegisterKey);
request.Body.key = key;
Client.Send(request);
internal AsyncJob<PurchaseResponseCallback> RedeemKey(string key) {
if (string.IsNullOrEmpty(key)) {
return null;
}
var request = new ClientMsgProtobuf<CMsgClientRegisterKey>(EMsg.ClientRegisterKey);
request.SourceJobID = Client.GetNextJobID();
request.Body.key = key;
Client.Send(request);
return new AsyncJob<PurchaseResponseCallback>(Client, request.SourceJobID);
}
/*
_ _ _ _
| | | | __ _ _ __ __| || | ___ _ __ ___
| |_| | / _` || '_ \ / _` || | / _ \| '__|/ __|
| _ || (_| || | | || (_| || || __/| | \__ \
|_| |_| \__,_||_| |_| \__,_||_| \___||_| |___/
*/
public sealed override void HandleMsg(IPacketMsg packetMsg) {
if (packetMsg == null) {
return;
}
switch (packetMsg.MsgType) {
case EMsg.ClientFSOfflineMessageNotification:
HandleFSOfflineMessageNotification(packetMsg);
break;
case EMsg.ClientPurchaseResponse:
HandlePurchaseResponse(packetMsg);
break;
@@ -141,71 +227,43 @@ namespace ArchiSteamFarm {
}
}
private void HandlePurchaseResponse(IPacketMsg packetMsg) {
var response = new ClientMsgProtobuf<CMsgClientPurchaseResponse>(packetMsg);
Client.PostCallback(new PurchaseResponseCallback(response.Body));
}
private void HandleUserNotifications(IPacketMsg packetMsg) {
var response = new ClientMsgProtobuf<CMsgClientUserNotifications>(packetMsg);
foreach (var notification in response.Body.notifications) {
Client.PostCallback(new NotificationCallback(notification));
}
}
// TODO: Please remove me entirely once https://github.com/SteamRE/SteamKit/pull/217 gets merged
internal void HackedLogOn(uint id, SteamUser.LogOnDetails details) {
if (details == null) {
throw new ArgumentNullException("details");
}
if (string.IsNullOrEmpty(details.Username) || (string.IsNullOrEmpty(details.Password) && string.IsNullOrEmpty(details.LoginKey))) {
throw new ArgumentException("LogOn requires a username and password to be set in 'details'.");
}
if (!string.IsNullOrEmpty(details.LoginKey) && !details.ShouldRememberPassword) {
// Prevent consumers from screwing this up.
// If should_remember_password is false, the login_key is ignored server-side.
// The inverse is not applicable (you can log in with should_remember_password and no login_key).
throw new ArgumentException("ShouldRememberPassword is required to be set to true in order to use LoginKey.");
}
if (!Client.IsConnected) {
private void HandleFSOfflineMessageNotification(IPacketMsg packetMsg) {
if (packetMsg == null) {
return;
}
var logon = new ClientMsgProtobuf<CMsgClientLogon>(EMsg.ClientLogon);
var response = new ClientMsgProtobuf<CMsgClientOfflineMessageNotification>(packetMsg);
if (response == null) {
return;
}
SteamID steamId = new SteamID(details.AccountID, details.AccountInstance, Client.ConnectedUniverse, EAccountType.Individual);
Client.PostCallback(new OfflineMessageCallback(packetMsg.TargetJobID, response.Body));
}
logon.ProtoHeader.client_sessionid = 0;
logon.ProtoHeader.steamid = steamId.ConvertToUInt64();
private void HandlePurchaseResponse(IPacketMsg packetMsg) {
if (packetMsg == null) {
return;
}
logon.Body.obfustucated_private_ip = id;
var response = new ClientMsgProtobuf<CMsgClientPurchaseResponse>(packetMsg);
if (response == null) {
return;
}
logon.Body.account_name = details.Username;
logon.Body.password = details.Password;
logon.Body.should_remember_password = details.ShouldRememberPassword;
Client.PostCallback(new PurchaseResponseCallback(packetMsg.TargetJobID, response.Body));
}
logon.Body.protocol_version = MsgClientLogon.CurrentProtocol;
logon.Body.client_os_type = (uint) details.ClientOSType;
logon.Body.client_language = details.ClientLanguage;
logon.Body.cell_id = details.CellID;
private void HandleUserNotifications(IPacketMsg packetMsg) {
if (packetMsg == null) {
return;
}
logon.Body.steam2_ticket_request = details.RequestSteam2Ticket;
var response = new ClientMsgProtobuf<CMsgClientUserNotifications>(packetMsg);
if (response == null) {
return;
}
logon.Body.client_package_version = 1771;
// steam guard
logon.Body.auth_code = details.AuthCode;
logon.Body.two_factor_code = details.TwoFactorCode;
logon.Body.login_key = details.LoginKey;
logon.Body.sha_sentryfile = details.SentryFileHash;
logon.Body.eresult_sentryfile = (int) (details.SentryFileHash != null ? EResult.OK : EResult.FileNotFound);
Client.Send(logon);
Client.PostCallback(new NotificationsCallback(packetMsg.TargetJobID, response.Body));
}
}
}

View File

@@ -66,19 +66,20 @@
<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.1-beta3\lib\net45\Newtonsoft.Json.dll</HintPath>
<HintPath>..\packages\Newtonsoft.Json.8.0.1\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">
<HintPath>..\packages\protobuf-net.2.0.0.668\lib\net40\protobuf-net.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="SteamKit2, Version=1.6.5.29095, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\SteamKit2.1.6.5\lib\net40\SteamKit2.dll</HintPath>
<Reference Include="SteamKit2, Version=1.7.0.33680, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\SteamKit2.1.7.0\lib\net45\SteamKit2.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.ServiceModel" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
@@ -100,6 +101,7 @@
<Compile Include="SteamTradeOffer.cs" />
<Compile Include="Trading.cs" />
<Compile Include="Utilities.cs" />
<Compile Include="WCF.cs" />
<Compile Include="WebBrowser.cs" />
</ItemGroup>
<ItemGroup>
@@ -143,8 +145,7 @@
mkdir "$(TargetDir)out" "$(TargetDir)out\config"
copy "$(TargetDir)config\example.xml" "$(TargetDir)out\config"
copy "$(TargetDir)config\minimal.xml" "$(TargetDir)out\config"
"$(SolutionDir)tools\ILMerge.exe" /out:"$(TargetDir)out\ASF.exe" "$(TargetDir)$(TargetName).exe" "$(TargetDir)*.dll" /target:exe /targetplatform:v4,C:\Windows\Microsoft.NET\Framework64\v4.0.30319 /wildcards
del "$(TargetDir)out\ASF.pdb"
"$(SolutionDir)tools\ILMerge.exe" /ndebug /internalize /out:"$(TargetDir)out\ASF.exe" "$(TargetDir)$(TargetName).exe" "$(TargetDir)*.dll" /target:exe /targetplatform:v4,"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5.2" /wildcards
)</PostBuildEvent>
</PropertyGroup>
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.

View File

@@ -38,7 +38,7 @@ namespace ArchiSteamFarm {
private readonly Bot Bot;
private readonly string ApiKey;
private readonly Dictionary<string, string> SteamCookieDictionary = new Dictionary<string, string>();
private readonly Dictionary<string, string> Cookie = new Dictionary<string, string>();
private ulong SteamID;
private string VanityURL;
@@ -46,14 +46,49 @@ namespace ArchiSteamFarm {
// This is required because home_process request must be done on final URL
private string GetHomeProcess() {
if (!string.IsNullOrEmpty(VanityURL)) {
return "http://steamcommunity.com/id/" + VanityURL + "/home_process";
return "https://steamcommunity.com/id/" + VanityURL + "/home_process";
} else if (SteamID != 0) {
return "http://steamcommunity.com/profiles/" + SteamID + "/home_process";
return "https://steamcommunity.com/profiles/" + SteamID + "/home_process";
} else {
return null;
}
}
private async Task UnlockParentalAccount(string parentalPin) {
if (string.IsNullOrEmpty(parentalPin) || parentalPin.Equals("0")) {
return;
}
Logging.LogGenericInfo(Bot.BotName, "Unlocking parental account...");
Dictionary<string, string> postData = new Dictionary<string, string>() {
{ "pin", parentalPin }
};
HttpResponseMessage response = await WebBrowser.UrlPost("https://steamcommunity.com/parental/ajaxunlock", postData, Cookie, "https://steamcommunity.com/").ConfigureAwait(false);
if (response == null) {
Logging.LogGenericInfo(Bot.BotName, "Failed!");
return;
}
IEnumerable<string> setCookieValues;
if (!response.Headers.TryGetValues("Set-Cookie", out setCookieValues)) {
Logging.LogGenericInfo(Bot.BotName, "Failed!");
return;
}
foreach (string setCookieValue in setCookieValues) {
if (setCookieValue.Contains("steamparental=")) {
string setCookie = setCookieValue.Substring(setCookieValue.IndexOf("steamparental=") + 14);
setCookie = setCookie.Substring(0, setCookie.IndexOf(';'));
Cookie.Add("steamparental", setCookie);
Logging.LogGenericInfo(Bot.BotName, "Success!");
return;
}
}
Logging.LogGenericInfo(Bot.BotName, "Failed!");
}
internal ArchiWebHandler(Bot bot, string apiKey) {
Bot = bot;
@@ -62,9 +97,9 @@ namespace ArchiSteamFarm {
}
}
internal async Task Init(SteamClient steamClient, string webAPIUserNonce, string vanityURL, string parentalPin) {
internal async Task<bool> Init(SteamClient steamClient, string webAPIUserNonce, string vanityURL, string parentalPin) {
if (steamClient == null || steamClient.SteamID == null || string.IsNullOrEmpty(webAPIUserNonce)) {
return;
return false;
}
SteamID = steamClient.SteamID;
@@ -104,14 +139,12 @@ namespace ArchiSteamFarm {
);
} catch (Exception e) {
Logging.LogGenericException(Bot.BotName, e);
steamClient.Disconnect(); // We may get 403 if we use the same webAPIUserNonce twice
return;
return false;
}
}
if (authResult == null) {
steamClient.Disconnect(); // Try again
return;
return false;
}
Logging.LogGenericInfo(Bot.BotName, "Success!");
@@ -119,35 +152,14 @@ namespace ArchiSteamFarm {
string steamLogin = authResult["token"].AsString();
string steamLoginSecure = authResult["tokensecure"].AsString();
SteamCookieDictionary.Clear();
SteamCookieDictionary.Add("sessionid", sessionID);
SteamCookieDictionary.Add("steamLogin", steamLogin);
SteamCookieDictionary.Add("steamLoginSecure", steamLoginSecure);
SteamCookieDictionary.Add("birthtime", "-473356799"); // ( ͡° ͜ʖ ͡°)
Cookie.Clear();
Cookie.Add("sessionid", sessionID);
Cookie.Add("steamLogin", steamLogin);
Cookie.Add("steamLoginSecure", steamLoginSecure);
Cookie.Add("birthtime", "-473356799"); // ( ͡° ͜ʖ ͡°)
if (!string.IsNullOrEmpty(parentalPin) && !parentalPin.Equals("0")) {
Logging.LogGenericInfo(Bot.BotName, "Unlocking parental account...");
Dictionary<string, string> postData = new Dictionary<string, string>() {
{"pin", parentalPin}
};
HttpResponseMessage response = await WebBrowser.UrlPost("https://steamcommunity.com/parental/ajaxunlock", postData, SteamCookieDictionary, "https://steamcommunity.com/").ConfigureAwait(false);
if (response != null && response.IsSuccessStatusCode) {
Logging.LogGenericInfo(Bot.BotName, "Success!");
var setCookieValues = response.Headers.GetValues("Set-Cookie");
foreach (string setCookieValue in setCookieValues) {
if (setCookieValue.Contains("steamparental=")) {
string setCookie = setCookieValue.Substring(setCookieValue.IndexOf("steamparental=") + 14);
setCookie = setCookie.Substring(0, setCookie.IndexOf(';'));
SteamCookieDictionary.Add("steamparental", setCookie);
break;
}
}
} else {
Logging.LogGenericInfo(Bot.BotName, "Failed!");
}
}
await UnlockParentalAccount(parentalPin).ConfigureAwait(false);
return true;
}
internal async Task<bool?> IsLoggedIn() {
@@ -155,7 +167,7 @@ namespace ArchiSteamFarm {
return false;
}
HtmlDocument htmlDocument = await WebBrowser.UrlGetToHtmlDocument("http://steamcommunity.com/my/profile", SteamCookieDictionary).ConfigureAwait(false);
HtmlDocument htmlDocument = await WebBrowser.UrlGetToHtmlDocument("https://steamcommunity.com/my/profile", Cookie).ConfigureAwait(false);
if (htmlDocument == null) {
return null;
}
@@ -168,7 +180,7 @@ namespace ArchiSteamFarm {
bool? isLoggedIn = await IsLoggedIn().ConfigureAwait(false);
if (isLoggedIn.HasValue && !isLoggedIn.Value) {
Logging.LogGenericInfo(Bot.BotName, "Reconnecting because our sessionID expired!");
Bot.SteamClient.Disconnect(); // Bot will handle reconnect
var restart = Task.Run(async () => await Bot.Restart().ConfigureAwait(false));
return true;
}
@@ -209,7 +221,7 @@ namespace ArchiSteamFarm {
accountid_other = trade["accountid_other"].AsInteger(),
message = trade["message"].AsString(),
expiration_time = trade["expiration_time"].AsInteger(),
trade_offer_state = (SteamTradeOffer.ETradeOfferState) trade["trade_offer_state"].AsInteger(),
trade_offer_state = trade["trade_offer_state"].AsEnum<SteamTradeOffer.ETradeOfferState>(),
items_to_give = new List<SteamItem>(),
items_to_receive = new List<SteamItem>(),
is_our_offer = trade["is_our_offer"].AsBoolean(),
@@ -217,7 +229,7 @@ namespace ArchiSteamFarm {
time_updated = trade["time_updated"].AsInteger(),
from_real_time_trade = trade["from_real_time_trade"].AsBoolean(),
escrow_end_date = trade["escrow_end_date"].AsInteger(),
confirmation_method = (SteamTradeOffer.ETradeOfferConfirmationMethod) trade["confirmation_method"].AsInteger()
confirmation_method = trade["confirmation_method"].AsEnum<SteamTradeOffer.ETradeOfferConfirmationMethod>()
};
foreach (KeyValue item in trade["items_to_give"].Children) {
tradeOffer.items_to_give.Add(new SteamItem {
@@ -255,18 +267,18 @@ namespace ArchiSteamFarm {
}
string sessionID;
if (!SteamCookieDictionary.TryGetValue("sessionid", out sessionID)) {
if (!Cookie.TryGetValue("sessionid", out sessionID)) {
return;
}
string request = "http://steamcommunity.com/gid/" + clanID;
string request = "https://steamcommunity.com/gid/" + clanID;
Dictionary<string, string> postData = new Dictionary<string, string>() {
{"sessionID", sessionID},
{"action", "join"}
};
await WebBrowser.UrlPost(request, postData, SteamCookieDictionary).ConfigureAwait(false);
await WebBrowser.UrlPost(request, postData, Cookie).ConfigureAwait(false);
}
internal async Task LeaveClan(ulong clanID) {
@@ -275,7 +287,7 @@ namespace ArchiSteamFarm {
}
string sessionID;
if (!SteamCookieDictionary.TryGetValue("sessionid", out sessionID)) {
if (!Cookie.TryGetValue("sessionid", out sessionID)) {
return;
}
@@ -286,7 +298,7 @@ namespace ArchiSteamFarm {
{"groupId", clanID.ToString()}
};
await WebBrowser.UrlPost(request, postData, SteamCookieDictionary).ConfigureAwait(false);
await WebBrowser.UrlPost(request, postData, Cookie).ConfigureAwait(false);
}
internal async Task<bool> AcceptTradeOffer(ulong tradeID) {
@@ -295,7 +307,7 @@ namespace ArchiSteamFarm {
}
string sessionID;
if (!SteamCookieDictionary.TryGetValue("sessionid", out sessionID)) {
if (!Cookie.TryGetValue("sessionid", out sessionID)) {
return false;
}
@@ -308,7 +320,7 @@ namespace ArchiSteamFarm {
{"tradeofferid", tradeID.ToString()}
};
HttpResponseMessage result = await WebBrowser.UrlPost(request, postData, SteamCookieDictionary, referer).ConfigureAwait(false);
HttpResponseMessage result = await WebBrowser.UrlPost(request, postData, Cookie, referer).ConfigureAwait(false);
if (result == null) {
return false;
}
@@ -364,7 +376,7 @@ namespace ArchiSteamFarm {
return null;
}
return await WebBrowser.UrlGetToHtmlDocument("http://steamcommunity.com/profiles/" + SteamID + "/badges?p=" + page, SteamCookieDictionary).ConfigureAwait(false);
return await WebBrowser.UrlGetToHtmlDocument("https://steamcommunity.com/profiles/" + SteamID + "/badges?l=english&p=" + page, Cookie).ConfigureAwait(false);
}
internal async Task<HtmlDocument> GetGameCardsPage(ulong appID) {
@@ -372,7 +384,7 @@ namespace ArchiSteamFarm {
return null;
}
return await WebBrowser.UrlGetToHtmlDocument("http://steamcommunity.com/profiles/" + SteamID + "/gamecards/" + appID, SteamCookieDictionary).ConfigureAwait(false);
return await WebBrowser.UrlGetToHtmlDocument("https://steamcommunity.com/profiles/" + SteamID + "/gamecards/" + appID + "?l=english", Cookie).ConfigureAwait(false);
}
}
}

View File

@@ -25,6 +25,7 @@
using Newtonsoft.Json;
using SteamAuth;
using SteamKit2;
using SteamKit2.Internal;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
@@ -35,27 +36,32 @@ using System.Xml;
namespace ArchiSteamFarm {
internal sealed class Bot {
private const ulong ArchiSCFarmGroup = 103582791440160998;
private const ushort CallbackSleep = 500; // In miliseconds
private static readonly ConcurrentDictionary<string, Bot> Bots = new ConcurrentDictionary<string, Bot>();
private static readonly uint LoginID = MsgClientLogon.ObfuscationMask; // This must be the same for all ASF bots and all ASF processes
internal static readonly ConcurrentDictionary<string, Bot> Bots = new ConcurrentDictionary<string, Bot>();
internal static readonly HashSet<uint> GlobalBlacklist = new HashSet<uint> { 303700, 335590, 368020, 425280 };
private readonly string ConfigFile, LoginKeyFile, MobileAuthenticatorFile, SentryFile;
internal readonly string BotName;
internal readonly ArchiHandler ArchiHandler;
internal readonly ArchiWebHandler ArchiWebHandler;
internal readonly CallbackManager CallbackManager;
internal readonly CardsFarmer CardsFarmer;
internal readonly SteamClient SteamClient;
internal readonly SteamFriends SteamFriends;
internal readonly SteamUser SteamUser;
internal readonly Trading Trading;
private bool KeepRunning = true;
private bool InvalidPassword = false;
private bool LoggedInElsewhere = false;
private bool IsRunning = false;
private string AuthCode, LoginKey, TwoFactorAuth;
internal ArchiHandler ArchiHandler { get; private set; }
internal ArchiWebHandler ArchiWebHandler { get; private set; }
internal CallbackManager CallbackManager { get; private set; }
internal CardsFarmer CardsFarmer { get; private set; }
internal SteamClient SteamClient { get; private set; }
internal SteamFriends SteamFriends { get; private set; }
internal SteamGuardAccount SteamGuardAccount { get; private set; }
internal SteamUser SteamUser { get; private set; }
internal Trading Trading { get; private set; }
// Config variables
internal bool Enabled { get; private set; } = false;
@@ -67,9 +73,11 @@ namespace ArchiSteamFarm {
internal ulong SteamMasterID { get; private set; } = 0;
internal ulong SteamMasterClanID { get; private set; } = 0;
internal bool CardDropsRestricted { get; private set; } = false;
internal bool FarmOffline { get; private set; } = false;
internal bool HandleOfflineMessages { get; private set; } = false;
internal bool UseAsfAsMobileAuthenticator { get; private set; } = false;
internal bool ShutdownOnFarmingFinished { get; private set; } = false;
internal HashSet<uint> Blacklist { get; private set; } = new HashSet<uint> { 303700, 335590, 368020, 425280 };
internal HashSet<uint> Blacklist { get; private set; } = new HashSet<uint>();
internal bool Statistics { get; private set; } = true;
private static bool IsValidCdKey(string key) {
@@ -90,6 +98,14 @@ namespace ArchiSteamFarm {
return true;
}
internal static string GetAnyBotName() {
foreach (string botName in Bots.Keys) {
return botName;
}
return null;
}
internal static int GetRunningBotsCount() {
return Bots.Count;
}
@@ -109,10 +125,10 @@ namespace ArchiSteamFarm {
BotName = botName;
ConfigFile = Path.Combine(Program.ConfigDirectoryPath, BotName + ".xml");
LoginKeyFile = Path.Combine(Program.ConfigDirectoryPath, BotName + ".key");
MobileAuthenticatorFile = Path.Combine(Program.ConfigDirectoryPath, BotName + ".auth");
SentryFile = Path.Combine(Program.ConfigDirectoryPath, BotName + ".bin");
ConfigFile = Path.Combine(Program.ConfigDirectory, BotName + ".xml");
LoginKeyFile = Path.Combine(Program.ConfigDirectory, BotName + ".key");
MobileAuthenticatorFile = Path.Combine(Program.ConfigDirectory, BotName + ".auth");
SentryFile = Path.Combine(Program.ConfigDirectory, BotName + ".bin");
if (!ReadConfig()) {
return;
@@ -135,8 +151,11 @@ namespace ArchiSteamFarm {
CallbackManager.Subscribe<SteamClient.DisconnectedCallback>(OnDisconnected);
SteamFriends = SteamClient.GetHandler<SteamFriends>();
CallbackManager.Subscribe<SteamFriends.ChatInviteCallback>(OnChatInvite);
CallbackManager.Subscribe<SteamFriends.ChatMsgCallback>(OnChatMsg);
CallbackManager.Subscribe<SteamFriends.FriendsListCallback>(OnFriendsList);
CallbackManager.Subscribe<SteamFriends.FriendMsgCallback>(OnFriendMsg);
CallbackManager.Subscribe<SteamFriends.FriendMsgHistoryCallback>(OnFriendMsgHistory);
if (UseAsfAsMobileAuthenticator && File.Exists(MobileAuthenticatorFile)) {
SteamGuardAccount = JsonConvert.DeserializeObject<SteamGuardAccount>(File.ReadAllText(MobileAuthenticatorFile));
@@ -149,15 +168,20 @@ namespace ArchiSteamFarm {
CallbackManager.Subscribe<SteamUser.LoginKeyCallback>(OnLoginKey);
CallbackManager.Subscribe<SteamUser.UpdateMachineAuthCallback>(OnMachineAuth);
CallbackManager.Subscribe<ArchiHandler.NotificationCallback>(OnNotification);
CallbackManager.Subscribe<ArchiHandler.NotificationsCallback>(OnNotifications);
CallbackManager.Subscribe<ArchiHandler.OfflineMessageCallback>(OnOfflineMessage);
CallbackManager.Subscribe<ArchiHandler.PurchaseResponseCallback>(OnPurchaseResponse);
ArchiWebHandler = new ArchiWebHandler(this, SteamApiKey);
CardsFarmer = new CardsFarmer(this);
Trading = new Trading(this);
// Before attempting to connect, initialize our list of CMs
SteamDirectory.Initialize().Wait();
// Start
var fireAndForget = Task.Run(async () => await Start().ConfigureAwait(false));
var handleCallbacks = Task.Run(() => HandleCallbacks());
var start = Task.Run(async () => await Start().ConfigureAwait(false));
}
internal async Task AcceptAllConfirmations() {
@@ -301,6 +325,12 @@ namespace ArchiSteamFarm {
case "CardDropsRestricted":
CardDropsRestricted = bool.Parse(value);
break;
case "FarmOffline":
FarmOffline = bool.Parse(value);
break;
case "HandleOfflineMessages":
HandleOfflineMessages = bool.Parse(value);
break;
case "ShutdownOnFarmingFinished":
ShutdownOnFarmingFinished = bool.Parse(value);
break;
@@ -328,12 +358,15 @@ namespace ArchiSteamFarm {
return true;
}
internal async Task Start() {
if (IsRunning) {
return;
internal async Task Restart() {
await Stop().ConfigureAwait(false);
await Start().ConfigureAwait(false);
}
IsRunning = true;
internal async Task Start() {
if (SteamClient.IsConnected) {
return;
}
Logging.LogGenericInfo(BotName, "Starting...");
@@ -343,35 +376,39 @@ namespace ArchiSteamFarm {
}
SteamClient.Connect();
var fireAndForget = Task.Run(() => HandleCallbacks());
}
internal async Task Stop() {
if (!IsRunning) {
if (!SteamClient.IsConnected) {
return;
}
await CardsFarmer.StopFarming().ConfigureAwait(false);
IsRunning = false;
await Utilities.SleepAsync(0); // TODO: This is here only to make VS happy, for now
Logging.LogGenericInfo(BotName, "Stopping...");
SteamClient.Disconnect();
}
internal async Task<bool> Shutdown(string botName = null) {
internal async Task Shutdown() {
KeepRunning = false;
await Stop().ConfigureAwait(false);
Bot bot;
Bots.TryRemove(BotName, out bot);
Program.OnBotShutdown();
}
internal static async Task<bool> Shutdown(string botName) {
if (string.IsNullOrEmpty(botName)) {
bot = this;
} else {
return false;
}
Bot bot;
if (!Bots.TryGetValue(botName, out bot)) {
return false;
}
}
await bot.Stop().ConfigureAwait(false);
Bots.TryRemove(bot.BotName, out bot);
Program.OnBotShutdown();
await bot.Shutdown().ConfigureAwait(false);
return true;
}
@@ -383,133 +420,203 @@ namespace ArchiSteamFarm {
private void HandleCallbacks() {
TimeSpan timeSpan = TimeSpan.FromMilliseconds(CallbackSleep);
while (IsRunning) {
while (KeepRunning) {
CallbackManager.RunWaitCallbacks(timeSpan);
}
}
private void SendMessageToUser(ulong steamID, string message) {
private void SendMessage(ulong steamID, string message) {
if (steamID == 0 || string.IsNullOrEmpty(message)) {
return;
}
// TODO: I really need something better
if (steamID < 110300000000000000) {
SteamFriends.SendChatMessage(steamID, EChatEntryType.ChatMsg, message);
} else {
SteamFriends.SendChatRoomMessage(steamID, EChatEntryType.ChatMsg, message);
}
}
private void ResponseStatus(ulong steamID, string botName = null) {
if (steamID == 0) {
return;
internal static string ResponseStatus(string botName) {
if (string.IsNullOrEmpty(botName)) {
return null;
}
Bot bot;
if (string.IsNullOrEmpty(botName)) {
bot = this;
} else {
if (!Bots.TryGetValue(botName, out bot)) {
SendMessageToUser(steamID, "Couldn't find any bot named " + botName + "!");
return;
}
return "Couldn't find any bot named " + botName + "!";
}
if (bot.CardsFarmer.CurrentGamesFarming.Count > 0) {
SendMessageToUser(steamID, "Bot " + bot.BotName + " is currently farming appIDs: " + string.Join(", ", bot.CardsFarmer.CurrentGamesFarming) + " and has a total of " + bot.CardsFarmer.GamesToFarm.Count + " games left to farm");
}
SendMessageToUser(steamID, "Currently " + Bots.Count + " bots are running");
return "Bot " + bot.BotName + " is currently farming appIDs: " + string.Join(", ", bot.CardsFarmer.CurrentGamesFarming) + " and has a total of " + bot.CardsFarmer.GamesToFarm.Count + " games left to farm";
}
private void Response2FA(ulong steamID, string botName = null) {
if (steamID == 0) {
return;
internal static string Response2FA(string botName) {
if (string.IsNullOrEmpty(botName)) {
return null;
}
Bot bot;
if (string.IsNullOrEmpty(botName)) {
bot = this;
} else {
if (!Bots.TryGetValue(botName, out bot)) {
SendMessageToUser(steamID, "Couldn't find any bot named " + botName + "!");
return;
}
return "Couldn't find any bot named " + botName + "!";
}
if (bot.SteamGuardAccount == null) {
SendMessageToUser(steamID, "That bot doesn't have ASF 2FA enabled!");
return;
return "That bot doesn't have ASF 2FA enabled!";
}
long timeLeft = 30 - TimeAligner.GetSteamTime() % 30;
SendMessageToUser(steamID, "2FA Token: " + bot.SteamGuardAccount.GenerateSteamGuardCode() + " (expires in " + timeLeft + " seconds)");
return "2FA Token: " + bot.SteamGuardAccount.GenerateSteamGuardCode() + " (expires in " + timeLeft + " seconds)";
}
private void Response2FAOff(ulong steamID, string botName = null) {
if (steamID == 0) {
return;
internal static string Response2FAOff(string botName) {
if (string.IsNullOrEmpty(botName)) {
return null;
}
Bot bot;
if (string.IsNullOrEmpty(botName)) {
bot = this;
} else {
if (!Bots.TryGetValue(botName, out bot)) {
SendMessageToUser(steamID, "Couldn't find any bot named " + botName + "!");
return;
}
return "Couldn't find any bot named " + botName + "!";
}
if (bot.SteamGuardAccount == null) {
SendMessageToUser(steamID, "That bot doesn't have ASF 2FA enabled!");
return;
return "That bot doesn't have ASF 2FA enabled!";
}
if (bot.DelinkMobileAuthenticator()) {
SendMessageToUser(steamID, "Done! Bot is no longer using ASF 2FA");
return "Done! Bot is no longer using ASF 2FA";
} else {
SendMessageToUser(steamID, "Something went wrong!");
return "Something went wrong during delinking mobile authenticator!";
}
}
private void ResponseStart(ulong steamID, string botName) {
if (steamID == 0 || string.IsNullOrEmpty(botName)) {
return;
internal static async Task<string> ResponseRedeem(string botName, string key) {
if (string.IsNullOrEmpty(botName) || string.IsNullOrEmpty(key)) {
return null;
}
Bot bot;
if (!Bots.TryGetValue(botName, out bot)) {
return "Couldn't find any bot named " + botName + "!";
}
ArchiHandler.PurchaseResponseCallback result;
try {
result = await bot.ArchiHandler.RedeemKey(key);
} catch (Exception e) {
Logging.LogGenericException(botName, e);
return null;
}
if (result == null) {
return null;
}
var purchaseResult = result.PurchaseResult;
var items = result.Items;
return "Status: " + purchaseResult + " | Items: " + string.Join("", items);
}
internal static string ResponseStart(string botName) {
if (string.IsNullOrEmpty(botName)) {
return null;
}
if (Bots.ContainsKey(botName)) {
SendMessageToUser(steamID, "That bot instance is already running!");
return;
return "That bot instance is already running!";
}
new Bot(botName);
if (Bots.ContainsKey(botName)) {
SendMessageToUser(steamID, "Done!");
return "Done!";
} else {
SendMessageToUser(steamID, "That bot instance failed to start, make sure that XML config exists and bot is active!");
return "That bot instance failed to start, make sure that XML config exists and bot is active!";
}
}
private async Task ResponseStop(ulong steamID, string botName) {
if (steamID == 0 || string.IsNullOrEmpty(botName)) {
return;
internal static async Task<string> ResponseStop(string botName) {
if (string.IsNullOrEmpty(botName)) {
return null;
}
if (!Bots.ContainsKey(botName)) {
SendMessageToUser(steamID, "That bot instance is already inactive!");
return;
Bot bot;
if (!Bots.TryGetValue(botName, out bot)) {
return "That bot instance is already inactive!";
}
if (await Shutdown(botName).ConfigureAwait(false)) {
SendMessageToUser(steamID, "Done!");
return "Done!";
} else {
SendMessageToUser(steamID, "That bot instance failed to shutdown!");
return "That bot instance failed to shutdown!";
}
}
internal async Task<string> HandleMessage(string message) {
if (string.IsNullOrEmpty(message)) {
return null;
}
if (IsValidCdKey(message)) {
return await ResponseRedeem(BotName, message).ConfigureAwait(false);
}
if (!message.Contains(" ")) {
switch (message) {
case "!2fa":
return Response2FA(BotName);
case "!2faoff":
return Response2FAOff(BotName);
case "!exit":
await ShutdownAllBots().ConfigureAwait(false);
return "Done";
case "!restart":
await Program.Restart().ConfigureAwait(false);
return "Done";
case "!status":
return ResponseStatus(BotName);
case "!stop":
return await ResponseStop(BotName).ConfigureAwait(false);
default:
return "Unrecognized command: " + message;
}
} else {
string[] args = message.Split(' ');
switch (args[0]) {
case "!2fa":
return Response2FA(args[1]);
case "!2faoff":
return Response2FAOff(args[1]);
case "!redeem":
string botName;
string key;
if (args.Length > 2) {
botName = args[1];
key = args[2];
} else {
botName = BotName;
key = args[1];
}
return await ResponseRedeem(botName, key).ConfigureAwait(false);
case "!start":
return ResponseStart(args[1]);
case "!stop":
return await ResponseStop(args[1]).ConfigureAwait(false);
case "!status":
return ResponseStatus(args[1]);
default:
return "Unrecognized command: " + args[0];
}
}
}
private async Task HandleMessage(ulong steamID, string message) {
if (steamID == 0 || string.IsNullOrEmpty(message)) {
return;
}
SendMessage(steamID, await HandleMessage(message).ConfigureAwait(false));
}
private void OnConnected(SteamClient.ConnectedCallback callback) {
if (callback == null) {
@@ -541,11 +648,11 @@ namespace ArchiSteamFarm {
SteamPassword = Program.GetUserInput(BotName, Program.EUserInputType.Password);
}
// TODO: We should use SteamUser.LogOn with proper LoginID once https://github.com/SteamRE/SteamKit/pull/217 gets merged
ArchiHandler.HackedLogOn(Program.UniqueID, new SteamUser.LogOnDetails {
SteamUser.LogOn(new SteamUser.LogOnDetails {
Username = SteamLogin,
Password = SteamPassword,
AuthCode = AuthCode,
LoginID = LoginID,
LoginKey = LoginKey,
TwoFactorCode = TwoFactorAuth,
SentryFileHash = sentryHash,
@@ -558,30 +665,72 @@ namespace ArchiSteamFarm {
return;
}
if (!IsRunning) {
return;
}
if (SteamClient == null) {
return;
}
Logging.LogGenericInfo(BotName, "Disconnected from Steam!");
await CardsFarmer.StopFarming().ConfigureAwait(false);
Logging.LogGenericWarning(BotName, "Disconnected from Steam, reconnecting...");
if (!KeepRunning) {
return;
}
// If we initiated disconnect, do not attempt to reconnect
if (callback.UserInitiated) {
return;
}
if (InvalidPassword) {
InvalidPassword = false;
if (!string.IsNullOrEmpty(LoginKey)) { // InvalidPassword means usually that login key has expired, if we used it
LoginKey = null;
File.Delete(LoginKeyFile);
Logging.LogGenericInfo(BotName, "Removed expired login key");
} else { // If we didn't use login key, InvalidPassword usually means we got captcha or other network-based throttling
Logging.LogGenericInfo(BotName, "Will retry after 25 minutes...");
await Utilities.SleepAsync(25 * 60 * 1000).ConfigureAwait(false); // Captcha disappears after around 20 minutes, so we make it 25
}
} else if (LoggedInElsewhere) {
LoggedInElsewhere = false;
Logging.LogGenericWarning(BotName, "Account is being used elsewhere, will try reconnecting in 30 minutes...");
await Utilities.SleepAsync(30 * 60 * 1000).ConfigureAwait(false);
}
Logging.LogGenericInfo(BotName, "Reconnecting...");
// 2FA tokens are expiring soon, use limiter only when we don't have any pending
if (TwoFactorAuth == null) {
await Program.LimitSteamRequestsAsync().ConfigureAwait(false);
}
if (LoggedInElsewhere) {
LoggedInElsewhere = false;
Logging.LogGenericWarning(BotName, "Account is being used elsewhere, will try reconnecting in 5 minutes...");
await Utilities.SleepAsync(5 * 60 * 1000).ConfigureAwait(false);
SteamClient.Connect();
}
SteamClient.Connect();
private void OnChatInvite(SteamFriends.ChatInviteCallback callback) {
if (callback == null) {
return;
}
ulong steamID = callback.PatronID;
if (steamID != SteamMasterID) {
return;
}
SteamFriends.JoinChat(callback.ChatRoomID);
}
private async void OnChatMsg(SteamFriends.ChatMsgCallback callback) {
if (callback == null) {
return;
}
if (callback.ChatMsgType != EChatEntryType.ChatMsg) {
return;
}
ulong steamID = callback.ChatterID;
if (steamID != SteamMasterID) {
return;
}
await HandleMessage(callback.ChatRoomID, callback.Message).ConfigureAwait(false);
}
private void OnFriendsList(SteamFriends.FriendsListCallback callback) {
@@ -622,69 +771,44 @@ namespace ArchiSteamFarm {
return;
}
string message = callback.Message;
if (string.IsNullOrEmpty(message)) {
await HandleMessage(steamID, callback.Message).ConfigureAwait(false);
}
private async void OnFriendMsgHistory(SteamFriends.FriendMsgHistoryCallback callback) {
if (callback == null) {
return;
}
if (IsValidCdKey(message)) {
ArchiHandler.RedeemKey(message);
if (callback.Result != EResult.OK) {
return;
}
if (!message.StartsWith("!")) {
ulong steamID = callback.SteamID;
if (steamID != SteamMasterID) {
return;
}
if (!message.Contains(" ")) {
switch (message) {
case "!2fa":
Response2FA(steamID);
break;
case "!2faoff":
Response2FAOff(steamID);
break;
case "!exit":
await ShutdownAllBots().ConfigureAwait(false);
break;
case "!farm":
SendMessageToUser(steamID, "Please wait...");
await CardsFarmer.StartFarming().ConfigureAwait(false);
SendMessageToUser(steamID, "Done!");
break;
case "!restart":
await Program.Restart().ConfigureAwait(false);
break;
case "!status":
ResponseStatus(steamID);
break;
case "!stop":
await Shutdown().ConfigureAwait(false);
break;
var messages = callback.Messages;
if (messages.Count == 0) {
return;
}
} else {
string[] args = message.Split(' ');
switch (args[0]) {
case "!2fa":
Response2FA(steamID, args[1]);
break;
case "!2faoff":
Response2FAOff(steamID, args[1]);
break;
case "!redeem":
ArchiHandler.RedeemKey(args[1]);
break;
case "!start":
ResponseStart(steamID, args[1]);
break;
case "!stop":
await ResponseStop(steamID, args[1]).ConfigureAwait(false);
break;
case "!status":
ResponseStatus(steamID, args[1]);
break;
// Get last message
var lastMessage = messages[messages.Count - 1];
// If message is read already, return
if (!lastMessage.Unread) {
return;
}
// If message is too old, return
if (DateTime.UtcNow.Subtract(lastMessage.Timestamp).TotalMinutes > 1) {
return;
}
// Handle the message
await HandleMessage(steamID, lastMessage.Message).ConfigureAwait(false);
}
private void OnAccountInfo(SteamUser.AccountInfoCallback callback) {
@@ -692,8 +816,10 @@ namespace ArchiSteamFarm {
return;
}
if (!FarmOffline) {
SteamFriends.SetPersonaState(EPersonaState.Online);
}
}
private void OnLoggedOff(SteamUser.LoggedOffCallback callback) {
if (callback == null) {
@@ -729,21 +855,8 @@ namespace ArchiSteamFarm {
}
break;
case EResult.InvalidPassword:
InvalidPassword = true;
Logging.LogGenericWarning(BotName, "Unable to login to Steam: " + result);
await Stop().ConfigureAwait(false);
// InvalidPassword means usually that login key has expired, if we used it
if (!string.IsNullOrEmpty(LoginKey)) {
LoginKey = null;
File.Delete(LoginKeyFile);
Logging.LogGenericInfo(BotName, "Removed expired login key, reconnecting...");
} else { // If we didn't use login key, InvalidPassword usually means we got captcha or other network-based throttling
Logging.LogGenericInfo(BotName, "Will retry after 25 minutes...");
await Utilities.SleepAsync(25 * 60 * 1000).ConfigureAwait(false); // Captcha disappears after around 20 minutes, so we make it 25
}
// After all of that, try again
await Start().ConfigureAwait(false);
break;
case EResult.OK:
Logging.LogGenericInfo(BotName, "Successfully logged on!");
@@ -757,14 +870,17 @@ namespace ArchiSteamFarm {
TwoFactorAuth = null;
if (!SteamNickname.Equals("null")) {
SteamFriends.SetPersonaName(SteamNickname);
await SteamFriends.SetPersonaName(SteamNickname);
}
if (SteamParentalPIN.Equals("null")) {
SteamParentalPIN = Program.GetUserInput(BotName, Program.EUserInputType.SteamParentalPIN);
}
await ArchiWebHandler.Init(SteamClient, callback.WebAPIUserNonce, callback.VanityURL, SteamParentalPIN).ConfigureAwait(false);
if (!await ArchiWebHandler.Init(SteamClient, callback.WebAPIUserNonce, callback.VanityURL, SteamParentalPIN).ConfigureAwait(false)) {
await Restart().ConfigureAwait(false);
return;
}
if (SteamMasterClanID != 0) {
await ArchiWebHandler.JoinClan(SteamMasterClanID).ConfigureAwait(false);
@@ -772,22 +888,21 @@ namespace ArchiSteamFarm {
}
if (Statistics) {
await ArchiWebHandler.JoinClan(Program.ArchiSCFarmGroup).ConfigureAwait(false);
SteamFriends.JoinChat(Program.ArchiSCFarmGroup);
await ArchiWebHandler.JoinClan(ArchiSCFarmGroup).ConfigureAwait(false);
SteamFriends.JoinChat(ArchiSCFarmGroup);
}
Trading.CheckTrades();
await CardsFarmer.StartFarming().ConfigureAwait(false);
break;
case EResult.NoConnection:
case EResult.ServiceUnavailable:
case EResult.Timeout:
case EResult.TryAnotherCM:
Logging.LogGenericWarning(BotName, "Unable to login to Steam: " + result + ", retrying...");
await Stop().ConfigureAwait(false);
await Start().ConfigureAwait(false);
Logging.LogGenericWarning(BotName, "Unable to login to Steam: " + result);
break;
default:
default: // Unexpected result, shutdown immediately
Logging.LogGenericWarning(BotName, "Unable to login to Steam: " + result);
await Shutdown().ConfigureAwait(false);
break;
@@ -808,8 +923,6 @@ namespace ArchiSteamFarm {
return;
}
Logging.LogGenericInfo(BotName, "Updating sentryfile...");
int fileSize;
byte[] sentryHash;
@@ -837,33 +950,48 @@ namespace ArchiSteamFarm {
OneTimePassword = callback.OneTimePassword,
SentryFileHash = sentryHash,
});
Logging.LogGenericInfo(BotName, "Sentryfile updated successfully!");
}
private void OnNotification(ArchiHandler.NotificationCallback callback) {
private void OnNotifications(ArchiHandler.NotificationsCallback callback) {
if (callback == null) {
return;
}
switch (callback.NotificationType) {
case ArchiHandler.NotificationCallback.ENotificationType.Trading:
Trading.CheckTrades();
bool checkTrades = false;
foreach (var notification in callback.Notifications) {
switch (notification.NotificationType) {
case ArchiHandler.NotificationsCallback.Notification.ENotificationType.Trading:
checkTrades = true;
break;
}
}
if (checkTrades) {
Trading.CheckTrades();
}
}
private void OnOfflineMessage(ArchiHandler.OfflineMessageCallback callback) {
if (callback == null) {
return;
}
if (!HandleOfflineMessages) {
return;
}
SteamFriends.RequestOfflineMessages();
}
private async void OnPurchaseResponse(ArchiHandler.PurchaseResponseCallback callback) {
if (callback == null) {
return;
}
var purchaseResult = callback.PurchaseResult;
var items = callback.Items;
SendMessageToUser(SteamMasterID, "Status: " + purchaseResult + " | Items: " + string.Join("", items));
if (purchaseResult == ArchiHandler.PurchaseResponseCallback.EPurchaseResult.OK) {
await CardsFarmer.StartFarming().ConfigureAwait(false);
// We will restart CF module to recalculate current status and decide about new optimal approach
await CardsFarmer.RestartFarming().ConfigureAwait(false);
}
}
}

View File

@@ -45,7 +45,7 @@ namespace ArchiSteamFarm {
internal readonly ConcurrentDictionary<uint, double> GamesToFarm = new ConcurrentDictionary<uint, double>();
internal readonly List<uint> CurrentGamesFarming = new List<uint>();
private volatile bool NowFarming = false;
private bool NowFarming = false;
internal CardsFarmer(Bot bot) {
Bot = bot;
@@ -85,30 +85,30 @@ namespace ArchiSteamFarm {
return 0;
}
internal bool FarmMultiple() {
if (GamesToFarm.Count == 0) {
internal bool FarmMultiple(ConcurrentDictionary<uint, double> appIDs) {
if (appIDs.Count == 0) {
return true;
}
double maxHour = -1;
foreach (double hour in GamesToFarm.Values) {
foreach (double hour in appIDs.Values) {
if (hour > maxHour) {
maxHour = hour;
}
}
CurrentGamesFarming.Clear();
foreach (uint appID in GamesToFarm.Keys) {
foreach (uint appID in appIDs.Keys) {
CurrentGamesFarming.Add(appID);
}
Logging.LogGenericInfo(Bot.BotName, "Now farming: " + string.Join(", ", GamesToFarm.Keys));
if (Farm(maxHour, GamesToFarm.Keys)) {
Logging.LogGenericInfo(Bot.BotName, "Now farming: " + string.Join(", ", appIDs.Keys));
if (Farm(maxHour, appIDs.Keys)) {
CurrentGamesFarming.Clear();
return true;
} else {
CurrentGamesFarming.Clear();
NowFarming = false;
return false;
}
}
@@ -128,14 +128,16 @@ namespace ArchiSteamFarm {
return true;
} else {
CurrentGamesFarming.Clear();
NowFarming = false;
return false;
}
}
internal async Task StartFarming() {
internal async Task RestartFarming() {
await StopFarming().ConfigureAwait(false);
await StartFarming().ConfigureAwait(false);
}
internal async Task StartFarming() {
await Semaphore.WaitAsync().ConfigureAwait(false);
if (NowFarming) {
@@ -143,23 +145,6 @@ namespace ArchiSteamFarm {
return;
}
// Check if farming is possible
Logging.LogGenericInfo(Bot.BotName, "Checking possibility to farm...");
NowFarming = true;
Semaphore.Release();
Bot.ArchiHandler.PlayGames(1337);
// We'll now either receive OnLoggedOff() with LoggedInElsewhere, or nothing happens
if (await Task.Run(() => FarmResetEvent.WaitOne(5000)).ConfigureAwait(false)) { // If LoggedInElsewhere happens in 5 seconds from now, abort farming
NowFarming = false;
return;
}
NowFarming = false;
Logging.LogGenericInfo(Bot.BotName, "Farming is possible!");
await Semaphore.WaitAsync().ConfigureAwait(false);
if (await Bot.ArchiWebHandler.ReconnectIfNeeded().ConfigureAwait(false)) {
Semaphore.Release();
return;
@@ -168,38 +153,42 @@ namespace ArchiSteamFarm {
Logging.LogGenericInfo(Bot.BotName, "Checking badges...");
// Find the number of badge pages
HtmlDocument badgesDocument = await Bot.ArchiWebHandler.GetBadgePage(1).ConfigureAwait(false);
if (badgesDocument == null) {
Logging.LogGenericWarning(Bot.BotName, "Could not get badges information, farming is stopped!");
Logging.LogGenericInfo(Bot.BotName, "Checking page: 1/?");
HtmlDocument htmlDocument = await Bot.ArchiWebHandler.GetBadgePage(1).ConfigureAwait(false);
if (htmlDocument == null) {
Logging.LogGenericWarning(Bot.BotName, "Could not get badges information, will try again later!");
Semaphore.Release();
return;
}
var maxPages = 1;
HtmlNodeCollection badgesPagesNodeCollection = badgesDocument.DocumentNode.SelectNodes("//a[@class='pagelink']");
if (badgesPagesNodeCollection != null) {
maxPages = (badgesPagesNodeCollection.Count / 2) + 1; // Don't do this at home
HtmlNodeCollection htmlNodeCollection = htmlDocument.DocumentNode.SelectNodes("//a[@class='pagelink']");
if (htmlNodeCollection != null && htmlNodeCollection.Count > 0) {
HtmlNode htmlNode = htmlNodeCollection[htmlNodeCollection.Count - 1];
if (!int.TryParse(htmlNode.InnerText, out maxPages)) {
maxPages = 1; // Should never happen
}
}
GamesToFarm.Clear();
// Find APPIDs we need to farm
for (var page = 1; page <= maxPages; page++) {
Logging.LogGenericInfo(Bot.BotName, "Checking page: " + page + "/" + maxPages);
if (page > 1) { // Because we fetched page number 1 already
badgesDocument = await Bot.ArchiWebHandler.GetBadgePage(page).ConfigureAwait(false);
if (badgesDocument == null) {
Logging.LogGenericInfo(Bot.BotName, "Checking page: " + page + "/" + maxPages);
htmlDocument = await Bot.ArchiWebHandler.GetBadgePage(page).ConfigureAwait(false);
if (htmlDocument == null) {
break;
}
}
HtmlNodeCollection badgesPageNodes = badgesDocument.DocumentNode.SelectNodes("//a[@class='btn_green_white_innerfade btn_small_thin']");
if (badgesPageNodes == null) {
htmlNodeCollection = htmlDocument.DocumentNode.SelectNodes("//a[@class='btn_green_white_innerfade btn_small_thin']");
if (htmlNodeCollection == null) {
continue;
}
GamesToFarm.Clear();
foreach (HtmlNode badgesPageNode in badgesPageNodes) {
string steamLink = badgesPageNode.GetAttributeValue("href", null);
foreach (HtmlNode htmlNode in htmlNodeCollection) {
string steamLink = htmlNode.GetAttributeValue("href", null);
if (steamLink == null) {
continue;
}
@@ -209,30 +198,36 @@ namespace ArchiSteamFarm {
continue;
}
if (Bot.Blacklist.Contains(appID)) {
if (Bot.GlobalBlacklist.Contains(appID) || Bot.Blacklist.Contains(appID)) {
continue;
}
// We assume that every game has at least 2 hours played, until we actually check them
GamesToFarm.AddOrUpdate(appID, 2, (key, value) => 2);
GamesToFarm[appID] = 2;
}
}
// If we have restricted card drops, actually do check all games that are left to farm
if (GamesToFarm.Count == 0) {
Logging.LogGenericInfo(Bot.BotName, "No games to farm!");
Semaphore.Release();
return;
}
// If we have restricted card drops, actually do check hours of all games that are left to farm
if (Bot.CardDropsRestricted) {
foreach (uint appID in GamesToFarm.Keys) {
Logging.LogGenericInfo(Bot.BotName, "Checking hours of appID: " + appID);
HtmlDocument appPage = await Bot.ArchiWebHandler.GetGameCardsPage(appID).ConfigureAwait(false);
if (appPage == null) {
htmlDocument = await Bot.ArchiWebHandler.GetGameCardsPage(appID).ConfigureAwait(false);
if (htmlDocument == null) {
continue;
}
HtmlNode appNode = appPage.DocumentNode.SelectSingleNode("//div[@class='badge_title_stats_playtime']");
if (appNode == null) {
HtmlNode htmlNode = htmlDocument.DocumentNode.SelectSingleNode("//div[@class='badge_title_stats_playtime']");
if (htmlNode == null) {
continue;
}
string hoursString = appNode.InnerText;
string hoursString = htmlNode.InnerText;
if (string.IsNullOrEmpty(hoursString)) {
continue;
}
@@ -252,8 +247,8 @@ namespace ArchiSteamFarm {
Logging.LogGenericInfo(Bot.BotName, "Farming in progress...");
NowFarming = GamesToFarm.Count > 0;
Semaphore.Release();
NowFarming = true;
Semaphore.Release(); // From this point we allow other calls to shut us down
// Now the algorithm used for farming depends on whether account is restricted or not
if (Bot.CardDropsRestricted) {
@@ -264,19 +259,19 @@ namespace ArchiSteamFarm {
if (gamesToFarmSolo.Count > 0) {
while (gamesToFarmSolo.Count > 0) {
uint appID = gamesToFarmSolo[0];
bool success = await FarmSolo(appID).ConfigureAwait(false);
if (success) {
if (await FarmSolo(appID).ConfigureAwait(false)) {
Logging.LogGenericInfo(Bot.BotName, "Done farming: " + appID);
gamesToFarmSolo.Remove(appID);
} else {
NowFarming = false;
return;
}
}
} else {
bool success = FarmMultiple();
if (success) {
if (FarmMultiple(GamesToFarm)) {
Logging.LogGenericInfo(Bot.BotName, "Done farming: " + string.Join(", ", GamesToFarm.Keys));
} else {
NowFarming = false;
return;
}
}
@@ -286,10 +281,10 @@ namespace ArchiSteamFarm {
Logging.LogGenericInfo(Bot.BotName, "Chosen farming algorithm: Simple");
while (GamesToFarm.Count > 0) {
uint appID = GetAnyGameToFarm(GamesToFarm);
bool success = await FarmSolo(appID).ConfigureAwait(false);
if (success) {
if (await FarmSolo(appID).ConfigureAwait(false)) {
Logging.LogGenericInfo(Bot.BotName, "Done farming: " + appID);
} else {
NowFarming = false;
return;
}
}
@@ -321,7 +316,7 @@ namespace ArchiSteamFarm {
}
private async Task CheckGamesForFarming() {
if (NowFarming || GamesToFarm.Count > 0) {
if (NowFarming || GamesToFarm.Count > 0 || !Bot.SteamClient.IsConnected) {
return;
}
@@ -384,12 +379,12 @@ namespace ArchiSteamFarm {
// Don't forget to update our GamesToFarm hours
double timePlayed = StatusCheckSleep / 60.0;
foreach (KeyValuePair<uint, double> keyValue in GamesToFarm) {
if (!appIDs.Contains(keyValue.Key)) {
foreach (KeyValuePair<uint, double> gameToFarm in GamesToFarm) {
if (!appIDs.Contains(gameToFarm.Key)) {
continue;
}
GamesToFarm[keyValue.Key] = keyValue.Value + timePlayed;
GamesToFarm[gameToFarm.Key] = gameToFarm.Value + timePlayed;
}
maxHour += timePlayed;

View File

@@ -22,20 +22,14 @@
*/
using System.Diagnostics;
namespace ArchiSteamFarm {
internal static class Debugging {
internal static bool IsDebugBuild { get; private set; } = false;
#if DEBUG
internal static readonly bool IsDebugBuild = true;
#else
internal static readonly bool IsDebugBuild = false;
#endif
internal static bool IsReleaseBuild { get { return !IsDebugBuild; } }
static Debugging() {
MarkIfDebug();
}
[Conditional("DEBUG")]
private static void MarkIfDebug() {
IsDebugBuild = true;
}
}
}

View File

@@ -24,16 +24,36 @@
using System;
using System.Diagnostics;
using System.IO;
using System.Runtime.CompilerServices;
namespace ArchiSteamFarm {
internal static class Logging {
private static readonly object FileLock = new object();
internal static bool LogToFile { get; set; } = false;
internal static void Init() {
File.Delete(Program.LogFile);
}
private static void Log(string message) {
if (Program.ConsoleIsBusy) {
if (string.IsNullOrEmpty(message)) {
return;
}
Console.WriteLine(DateTime.Now + " " + message);
string loggedMessage = DateTime.Now + " " + message + Environment.NewLine;
// Write on console only when not awaiting response from user
if (!Program.ConsoleIsBusy) {
Console.Write(loggedMessage);
}
if (LogToFile) {
lock (FileLock) {
File.AppendAllText(Program.LogFile, loggedMessage);
}
}
}
internal static void LogGenericError(string botName, string message, [CallerMemberName] string previousMethodName = "") {
@@ -60,10 +80,5 @@ namespace ArchiSteamFarm {
internal static void LogGenericDebug(string botName, string message, [CallerMemberName] string previousMethodName = "") {
Log("[#] DEBUG: " + previousMethodName + "() <" + botName + "> " + message);
}
[Conditional("DEBUG")]
internal static void LogGenericDebug(string message, [CallerMemberName] string previousMethodName = "") {
LogGenericDebug("DEBUG", message, previousMethodName);
}
}
}

View File

@@ -31,7 +31,7 @@ using System.Threading.Tasks;
namespace ArchiSteamFarm {
internal static class Program {
internal enum EUserInputType {
internal enum EUserInputType : byte {
Login,
Password,
PhoneNumber,
@@ -42,23 +42,29 @@ namespace ArchiSteamFarm {
TwoFactorAuthentication,
}
internal enum EMode : byte {
Normal, // Standard most common usage
Client, // WCF client only
Server // Normal + WCF server
}
private const string LatestGithubReleaseURL = "https://api.github.com/repos/JustArchi/ArchiSteamFarm/releases/latest";
internal const string ConfigDirectory = "config";
internal const string LogFile = "log.txt";
internal const ulong ArchiSCFarmGroup = 103582791440160998;
internal const string ConfigDirectoryPath = "config";
private static readonly object ConsoleLock = new object();
private static readonly SemaphoreSlim SteamSemaphore = new SemaphoreSlim(1);
private static readonly ManualResetEvent ShutdownResetEvent = new ManualResetEvent(false);
private static readonly Assembly Assembly = Assembly.GetExecutingAssembly();
private static readonly string ExecutablePath = Assembly.Location;
private static readonly AssemblyName AssemblyName = Assembly.GetName();
private static readonly object ConsoleLock = new object();
//private static readonly string ExeName = AssemblyName.Name + ".exe";
private static readonly string ExecutableFile = Assembly.Location;
private static readonly string ExecutableDirectory = Path.GetDirectoryName(ExecutableFile);
private static readonly WCF WCF = new WCF();
internal static readonly uint UniqueID = (uint) Utilities.Random.Next();
internal static readonly string Version = AssemblyName.Version.ToString();
internal static readonly string Version = Assembly.GetName().Version.ToString();
internal static bool ConsoleIsBusy = false;
private static EMode Mode;
internal static bool ConsoleIsBusy { get; private set; } = false;
private static async Task CheckForUpdate() {
JObject response = await WebBrowser.UrlGetToJObject(LatestGithubReleaseURL).ConfigureAwait(false);
@@ -94,7 +100,7 @@ namespace ArchiSteamFarm {
internal static async Task Restart() {
await Bot.ShutdownAllBots().ConfigureAwait(false);
System.Diagnostics.Process.Start(ExecutablePath);
System.Diagnostics.Process.Start(ExecutableFile, string.Join(" ", Environment.GetCommandLineArgs()));
Environment.Exit(0);
}
@@ -144,42 +150,103 @@ namespace ArchiSteamFarm {
return result.Trim(); // Get rid of all whitespace characters
}
internal static async void OnBotShutdown() {
internal static void OnBotShutdown() {
if (Bot.GetRunningBotsCount() == 0) {
Logging.LogGenericInfo("Main", "No bots are running, exiting");
await Utilities.SleepAsync(5000).ConfigureAwait(false); // This might be the only message user gets, consider giving him some time
ShutdownResetEvent.Set();
}
}
private static void InitServices() {
Logging.Init();
WebBrowser.Init();
}
private static void Main(string[] args) {
Logging.LogGenericInfo("Main", "Archi's Steam Farm, version " + Version);
private static void ParseArgs(string[] args) {
foreach (string arg in args) {
switch (arg) {
case "--client":
Mode = EMode.Client;
Logging.LogToFile = false;
break;
case "--log":
Logging.LogToFile = true;
break;
case "--no-log":
Logging.LogToFile = false;
break;
case "--server":
Mode = EMode.Server;
WCF.StartServer();
break;
default:
if (arg.StartsWith("--")) {
Logging.LogGenericWarning("Main", "Unrecognized parameter: " + arg);
continue;
}
InitServices();
if (Mode != EMode.Client) {
Logging.LogGenericWarning("Main", "Ignoring command because --client wasn't specified: " + arg);
continue;
}
Task.Run(async () => await CheckForUpdate().ConfigureAwait(false)).Wait();
Logging.LogGenericNotice("WCF", "Command sent: \"" + arg + "\"");
// Allow loading configs from source tree if it's a debug build
if (Debugging.IsDebugBuild) {
for (var i = 0; i < 4; i++) {
Directory.SetCurrentDirectory("..");
if (Directory.Exists(ConfigDirectoryPath)) {
// We intentionally execute this async block synchronously
Logging.LogGenericNotice("WCF", "Response received: \"" + WCF.SendCommand(arg) + "\"");
/*
Task.Run(async () => {
Logging.LogGenericNotice("WCF", "Response received: " + await WCF.SendCommand(arg).ConfigureAwait(false));
}).Wait();
*/
break;
}
}
}
if (!Directory.Exists(ConfigDirectoryPath)) {
private static void Main(string[] args) {
Logging.LogGenericInfo("Main", "Archi's Steam Farm, version " + Version);
Directory.SetCurrentDirectory(ExecutableDirectory);
InitServices();
// Allow loading configs from source tree if it's a debug build
if (Debugging.IsDebugBuild) {
// Common structure is bin/(x64/)Debug/ArchiSteamFarm.exe, so we allow up to 4 directories up
for (var i = 0; i < 4; i++) {
Directory.SetCurrentDirectory("..");
if (Directory.Exists(ConfigDirectory)) {
break;
}
}
// If config directory doesn't exist after our adjustment, abort all of that
if (!Directory.Exists(ConfigDirectory)) {
Directory.SetCurrentDirectory(ExecutableDirectory);
}
}
// By default we're operating on normal mode
Mode = EMode.Normal;
Logging.LogToFile = true;
// But that can be overriden by arguments
ParseArgs(args);
// If we ran ASF as a client, we're done by now
if (Mode == EMode.Client) {
return;
}
Task.Run(async () => await CheckForUpdate().ConfigureAwait(false)).Wait();
if (!Directory.Exists(ConfigDirectory)) {
Logging.LogGenericError("Main", "Config directory doesn't exist!");
Console.ReadLine();
Thread.Sleep(5000);
Task.Run(async () => await Exit(1).ConfigureAwait(false)).Wait();
}
foreach (var configFile in Directory.EnumerateFiles(ConfigDirectoryPath, "*.xml")) {
foreach (var configFile in Directory.EnumerateFiles(ConfigDirectory, "*.xml")) {
string botName = Path.GetFileNameWithoutExtension(configFile);
Bot bot = new Bot(botName);
if (!bot.Enabled) {
@@ -190,7 +257,14 @@ namespace ArchiSteamFarm {
// Check if we got any bots running
OnBotShutdown();
// Wait for signal to shutdown
ShutdownResetEvent.WaitOne();
// We got a signal to shutdown, consider giving user some time to read the message
Thread.Sleep(5000);
// This is over, cleanup only now
WCF.StopServer();
}
}
}

View File

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

View File

@@ -24,7 +24,7 @@
namespace ArchiSteamFarm {
internal sealed class SteamItem {
// REF: https://developer.valvesoftware.com/wiki/Steam_Web_API/IEconService
// REF: https://developer.valvesoftware.com/wiki/Steam_Web_API/IEconService#CEcon_Asset
internal string appid { get; set; }
internal string contextid { get; set; }
internal string assetid { get; set; }

View File

@@ -27,7 +27,7 @@ using System.Collections.Generic;
namespace ArchiSteamFarm {
internal sealed class SteamTradeOffer {
// REF: https://developer.valvesoftware.com/wiki/Steam_Web_API/IEconService
// REF: https://developer.valvesoftware.com/wiki/Steam_Web_API/IEconService#CEcon_TradeOffer
internal enum ETradeOfferState {
Unknown,
Invalid,

View File

@@ -28,8 +28,6 @@ using System.Threading.Tasks;
namespace ArchiSteamFarm {
internal static class Utilities {
internal static readonly Random Random = new Random();
internal static async Task SleepAsync(int miliseconds) {
await Task.Delay(miliseconds).ConfigureAwait(false);
}

106
ArchiSteamFarm/WCF.cs Normal file
View File

@@ -0,0 +1,106 @@
using System;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.Threading.Tasks;
namespace ArchiSteamFarm {
[ServiceContract]
internal interface IWCF {
[OperationContract]
string HandleCommand(string input);
}
internal class WCF : IWCF {
private const string URL = "http://localhost:1242/ASF"; // 1242 = 1024 + A(65) + S(83) + F(70)
private ServiceHost ServiceHost;
private Client Client;
internal void StartServer() {
if (ServiceHost != null) {
return;
}
Logging.LogGenericNotice("WCF", "Starting WCF server...");
ServiceHost = new ServiceHost(typeof(WCF));
ServiceHost.AddServiceEndpoint(typeof(IWCF), new BasicHttpBinding(), URL);
try {
ServiceHost.Open();
} catch (AddressAccessDeniedException) {
Logging.LogGenericWarning("WCF", "WCF service could not be started because of AddressAccessDeniedException");
Logging.LogGenericWarning("WCF", "If you want to use WCF service provided by ASF, consider starting ASF as administrator, or giving proper permissions");
return;
} catch (Exception e) {
Logging.LogGenericException("WCF", e);
return;
}
Logging.LogGenericNotice("WCF", "WCF server ready!");
}
internal void StopServer() {
if (ServiceHost == null) {
return;
}
ServiceHost.Close();
ServiceHost = null;
}
internal string SendCommand(string input) {
if (Client == null) {
Client = new Client(new BasicHttpBinding(), new EndpointAddress(URL));
}
return Client.HandleCommand(input);
}
public string HandleCommand(string input) {
if (string.IsNullOrEmpty(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.GetAnyBotName();
}
if (string.IsNullOrEmpty(botName)) {
return "ERROR: Invalid botName: " + botName;
}
Bot bot;
if (!Bot.Bots.TryGetValue(botName, out bot)) {
return "ERROR: Couldn't find any bot named: " + botName;
}
Logging.LogGenericInfo("WCF", "Received command: \"" + input + "\"");
string command = '!' + input;
string output = bot.HandleMessage(command).Result; // TODO: This should be asynchronous
Logging.LogGenericInfo("WCF", "Answered to command: \"" + input + "\" with: \"" + output + "\"");
return output;
}
}
internal class Client : ClientBase<IWCF>, IWCF {
internal Client(Binding binding, EndpointAddress address) : base(binding, address) { }
public string HandleCommand(string input) {
try {
return Channel.HandleCommand(input);
} catch (Exception e) {
Logging.LogGenericException("WCF", e);
return null;
}
}
}
}

View File

@@ -1,7 +1,10 @@
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<!-- This is full-fledged example config, you may be also interested in minimal.xml for bare minimum one -->
<!-- This config includes all user-switchable properties that you may want to change on per-bot basis -->
<!-- Default values used in config match default ASF values when given config property is not found -->
<!-- In other words, if given property is not defined, ASF will assume default pre-programmed value -->
<!-- Notice, if you use special characters reserved for XML, you should escape them -->
<!-- Escape table: [& - &amp;] | [" - &quot;] | [' - &apos;] | [< - &lt;] | [> - &gt;] -->
@@ -15,68 +18,94 @@
<!-- HashSet(uint) - Comma-separated list of unique 32-bit unsigned integers -->
<!-- Master switch to turn account on and off, set to "true" after you're done -->
<!-- TIP: This bot instance won't run unless below switch is set to "true" -->
<!-- This bot instance won't run unless below switch is set to "true" -->
<Enabled type="bool" value="false"/>
<!-- This is your steam login, the one you use for logging in to steam -->
<!-- TIP: You can use "null" if you wish to enter login on every startup -->
<!-- You can use "null" if you wish to enter login on every startup -->
<SteamLogin type="string" value="null"/>
<!-- This is your steam password, the one you use for logging in to steam -->
<!-- TIP: You can use "null" if you wish to enter password on every startup -->
<!-- You can use "null" if you wish to enter password on every startup -->
<SteamPassword type="string" value="null"/>
<!-- This is steam nickname, the one you want to use for bot. Can be anything up to 32 characters -->
<!-- TIP: You can use "null" if you wish to preserve your actual nickname -->
<!-- You can use "null" if you wish to preserve your actual nickname, and this is what you want most likely -->
<SteamNickname type="string" value="null"/>
<!-- This is your bot's API key, get one at https://steamcommunity.com/dev/apikey while logged in as bot, domain doesn't matter -->
<!-- TIP: You can use "null", but it will disable all API-based functionalities such as trading -->
<!-- This is your bot's API key, get one at https://steamcommunity.com/dev/apikey while logged in as a bot, domain doesn't matter -->
<!-- Remember that each account should have unique API key generated through above link, wrong API key will make all API-based functionalities to fail -->
<!-- API key is useless for primary accounts, as they're not using trading feature, you can leave it at "null" if you're configuring a primary account -->
<!-- When at "null", it will disable all ASF API-based functionalities such as trading -->
<SteamApiKey type="string" value="null"/>
<!-- This is your parental PIN if you use steam parental functionality -->
<!-- TIP: Most likely you don't want to change it. You can use "null" if you wish to enter PIN on every startup, 0 means there is no PIN -->
<!-- Most likely you don't want to change it. You can use "null" if you wish to enter PIN on every startup, 0 means there is no PIN, and this is probably what you want -->
<SteamParentalPIN type="string" value="0"/>
<!-- This is steamID64 of the bot-master - you, for example "76561198006963719" -->
<!-- You can get one e.g. by logging in to http://steamrep.com/ -->
<!-- TIP: You can use "0", but bot won't accept steam cd-keys or trades from anybody" -->
<!-- If you're configuring primary account, you can safely leave it at "0", as you're master yourself -->
<!-- When at "0", bot won't accept any commands, including steam cd-keys or trades" -->
<SteamMasterID type="ulong" value="0"/>
<!-- This is steamID64 of the master clan (group). If defined, bot will join the group and the chat automatically after logging in -->
<!-- The easiest way to get one is to check groups on your profile: http://steamcommunity.com/my/profile" -->
<!-- Then copying the URL of "Leave group" link, it will look like this: javascript:leaveGroupPrompt('103582791440160998','Archi\'s SC Farm') -->
<!-- The steamID64 we're looking for is there, in above example: "103582791440160998" -->
<!-- TIP: If you don't have your own farming group, most likely you don't want to change it, 0 means there is no master group defined -->
<!-- Remember that joining a group and the chat requires having non-restricted access to steam community, which is not always the case with alts -->
<!-- If you don't have your own farming group, most likely you don't want to change it, 0 means there is no master group defined -->
<SteamMasterClanID type="ulong" value="0"/>
<!-- This switch defines if you want to use built-in ASF two-factor-authentication (ASF 2FA) for this account -->
<!-- The one and only purpose for this function is automating steam logins and steam trades, so you won't need to enter 2FA codes all the time -->
<!-- This however defeats the whole purpose of two-factor-auth, and should be used on alt accounts ONLY -->
<!-- You should read full documentation, along with explanation here: https://github.com/JustArchi/ArchiSteamFarm/wiki/Escrow -->
<!-- Personally I suggest switching this to "true" ONLY for alts -->
<!-- WARNING, this option can potentially LOCK OUT YOUR ACCOUNT! If you don't fully understand this feature, DON'T USE IT! -->
<UseAsfAsMobileAuthenticator type="bool" value="false"/>
<!-- This switch defines if the account has card drops restricted -->
<!-- Restricted card drops means that the account doesn't receive any steam cards until it plays the game for at least 2 hours -->
<!-- As there is no magical way to detect it by ASF, I made this option config-based switch -->
<!-- TIP: Based on this parameter, ASF will try to choose the most optimal cards farming algorithm for this account -->
<!-- There is no magical way to detect it by ASF, I made this option config-based switch -->
<!-- Based on our observations, it looks like most accounts that never issued a refund have non-restricted card drops, and this is what default value assumes -->
<!-- However, if you noticed that your cards never drop until you hit 2 hours played mark, consider setting it as "true" -->
<!-- Guessing "wrong" won't have any real consequences, ASF will just work in non-optimal way, and everybody wants to drop cards fast, right? -->
<!-- Based on this parameter, ASF will try to choose the most optimal cards farming algorithm for this account -->
<CardDropsRestricted type="bool" value="false"/>
<!-- This switch defines if the account should stay as "Offline" after logging in to Steam. This has several advantages and disadvantages -->
<!-- Personally I find it extremely useful for primary accounts, as your status will remain "Online" and not "In-Game" when ASF is farming -->
<!-- Thanks to that, your friends will never ask you again if you're playing or farming the game. Your status will now nicely reflect that -->
<!-- However, it's less useful for alt accounts, as you won't be able to interact with bots and check what they're doing - they'll appear as "Offline" -->
<!-- Personally I suggest switching this to "true" for primary accounts, and leaving it at "false" for alt accounts -->
<!-- Bot won't be able to receive and answer to your commands, unless you set "HandleOfflineMessages" below to "true" as well -->
<FarmOffline type="bool" value="false"/>
<!-- This switch defines if bot should handle offline messages when it sees them -->
<!-- Basically it should be used only when "FarmOffline" property above is true, so bot can handle offline messages -->
<!-- Reading offline messages will also mark them as received, therefore it should not be used if you want to keep them for later -->
<!-- Personally I suggest keeping this on "false" for primary accounts, and considering switching to "true" for alts, if "FarmOffline" above is set to true as well -->
<HandleOfflineMessages type="bool" value="false"/>
<!-- This switch defines if bot should disconnect once farming is finished -->
<!-- When no bots are active, ASF will shutdown as well -->
<!-- Some people may want to keep their bots 24/7, other disconnect them after job is done -->
<!-- Choose yourself what you prefer -->
<!-- Keep in mind that when no bots are active, ASF will shutdown as well -->
<!-- You may want to disconnect the bot after he's done, if that's the case, set below to "true" -->
<!-- However, you may instead want to keep it online for the whole time, in this case, leave it at "false" -->
<!-- Even when bot is not farming anything, he'll keep checking badges from time to time, if there is anything new to farm -->
<!-- Personally I suggest leaving it at "false", unless you have a reason to close the process after all bots finished farming -->
<ShutdownOnFarmingFinished type="bool" value="false"/>
<!-- Comma-separated list of IDs that should not be considered for farming -->
<!-- Default value includes appIDs that are wrongly appearing on the profile, e.g. Monster Summer Sale -->
<!-- TIP: Most likely you don't want to change it -->
<!-- This is comma-separated list of IDs that should not be considered for farming -->
<!-- Default value includes appIDs that are wrongly appearing on the profile, e.g. Summer Sale, Winter Sale or Monster Summer Game -->
<!-- In addition to blacklist defined here, ASF also has global blacklist, which is being updated on as-needed basis, so you don't need to update this entry -->
<!-- You probably don't want to change anything here -->
<Blacklist type="HashSet(uint)" value="303700,335590,368020,425280"/>
<!-- This switch enables statistics for me - bot will join Archi's SC Farm group and chat -->
<!-- This switch enables statistics for me - bot will join Archi's SC Farm group and chat on steam -->
<!-- Consider leaving it at "true", this way I can check how many running bots are active -->
<!-- That directly affects my willings to work on the project, as I can see how many users are actually using it -->
<!-- TIP: Group link is http://steamcommunity.com/groups/ascfarm -->
<!-- Such information directly affects my willings to work on the project, as I can see how many users are actually using it -->
<!-- So if you want to see new versions coming up, bugs being fixed, and new features getting implemented, consider leaving it at "true" -->
<!-- You can find the group, along with all the statistics here: http://steamcommunity.com/groups/ascfarm -->
<Statistics type="bool" value="true"/>
</configuration>

View File

@@ -1,7 +1,8 @@
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<!-- This is minimalistic config to "just make ASF work" -->
<!-- For full-fledged config, please take a look at example.xml -->
<!-- This is minimalistic config "just to make ASF work". For full-fledged config, please take a look at example.xml -->
<!-- Full-fledged config includes some neat features such as offline farming or cards farming algorithm selection -->
<!-- ASF will use default values for missing properties, check example.xml to see all of them -->
<Enabled type="bool" value="false"/>
<SteamLogin type="string" value="null"/>
<SteamPassword type="string" value="null"/>

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.1-beta3" targetFramework="net45" />
<package id="Newtonsoft.Json" version="8.0.1" targetFramework="net452" />
<package id="protobuf-net" version="2.0.0.668" targetFramework="net45" />
<package id="SteamKit2" version="1.6.5" targetFramework="net45" />
<package id="SteamKit2" version="1.7.0" targetFramework="net452" />
</packages>

View File

@@ -32,7 +32,6 @@ ASF doesn't require and doesn't interfere in any way with Steam client, which me
- `!2faoff` Deactivates 2FA for current bot instance
- `!2faoff <BOT>` Deactivates 2FA for given bot instance
- `!exit` Stops whole ASF
- `!farm` Restarts cards farming module. ASF automatically executes that if any cd-key is successfully claimed
- `!redeem <KEY>` Redeems cd-key on current bot instance. You can also paste cd-key directly to the chat
- `!start <BOT>` Starts given bot instance
- `!status` Prints current status of ASF

View File

@@ -22,16 +22,17 @@
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<DebugType>none</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<DefineConstants>
</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<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.1-beta3\lib\net45\Newtonsoft.Json.dll</HintPath>
<HintPath>..\packages\Newtonsoft.Json.8.0.1\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.1-beta3" targetFramework="net452" />
<package id="Newtonsoft.Json" version="8.0.1" targetFramework="net452" />
</packages>

Binary file not shown.

Binary file not shown.

View File

@@ -76,38 +76,6 @@
<param name="readRootValueAsArray">if set to <c>true</c> the root object will be read as a JSON array.</param>
<param name="dateTimeKindHandling">The <see cref="T:System.DateTimeKind" /> used when reading <see cref="T:System.DateTime"/> values from BSON.</param>
</member>
<member name="M:Newtonsoft.Json.Bson.BsonReader.ReadAsBytes">
<summary>
Reads the next JSON token from the stream as a <see cref="T:System.Byte"/>[].
</summary>
<returns>
A <see cref="T:System.Byte"/>[] or a null reference if the next JSON token is null. This method will return <c>null</c> at the end of an array.
</returns>
</member>
<member name="M:Newtonsoft.Json.Bson.BsonReader.ReadAsDecimal">
<summary>
Reads the next JSON token from the stream as a <see cref="T:System.Nullable`1"/>.
</summary>
<returns>A <see cref="T:System.Nullable`1"/>. This method will return <c>null</c> at the end of an array.</returns>
</member>
<member name="M:Newtonsoft.Json.Bson.BsonReader.ReadAsInt32">
<summary>
Reads the next JSON token from the stream as a <see cref="T:System.Nullable`1"/>.
</summary>
<returns>A <see cref="T:System.Nullable`1"/>. This method will return <c>null</c> at the end of an array.</returns>
</member>
<member name="M:Newtonsoft.Json.Bson.BsonReader.ReadAsString">
<summary>
Reads the next JSON token from the stream as a <see cref="T:System.String"/>.
</summary>
<returns>A <see cref="T:System.String"/>. This method will return <c>null</c> at the end of an array.</returns>
</member>
<member name="M:Newtonsoft.Json.Bson.BsonReader.ReadAsDateTime">
<summary>
Reads the next JSON token from the stream as a <see cref="T:System.Nullable`1"/>.
</summary>
<returns>A <see cref="T:System.Nullable`1"/>. This method will return <c>null</c> at the end of an array.</returns>
</member>
<member name="M:Newtonsoft.Json.Bson.BsonReader.Read">
<summary>
Reads the next JSON token from the stream.
@@ -926,24 +894,24 @@
Causes child objects to be indented according to the <see cref="P:Newtonsoft.Json.JsonTextWriter.Indentation"/> and <see cref="P:Newtonsoft.Json.JsonTextWriter.IndentChar"/> settings.
</summary>
</member>
<member name="T:Newtonsoft.Json.IJsonBufferPool`1">
<member name="T:Newtonsoft.Json.IArrayPool`1">
<summary>
Provides an interface for using pooled buffers.
Provides an interface for using pooled arrays.
</summary>
<typeparam name="T">The buffer type content.</typeparam>
<typeparam name="T">The array type content.</typeparam>
</member>
<member name="M:Newtonsoft.Json.IJsonBufferPool`1.RentBuffer(System.Int32)">
<member name="M:Newtonsoft.Json.IArrayPool`1.Rent(System.Int32)">
<summary>
Rent a buffer from the pool. This buffer must be returned when it is no longer needed.
Rent a array from the pool. This array must be returned when it is no longer needed.
</summary>
<param name="minSize">The minimum required size of the buffer. The returned buffer may be larger.</param>
<returns>The rented buffer from the pool.</returns>
<param name="minimumLength">The minimum required length of the array. The returned array may be longer.</param>
<returns>The rented array from the pool. This array must be returned when it is no longer needed.</returns>
</member>
<member name="M:Newtonsoft.Json.IJsonBufferPool`1.ReturnBuffer(`0[]@)">
<member name="M:Newtonsoft.Json.IArrayPool`1.Return(`0[])">
<summary>
Return a buffer to the pool.
Return an array to the pool.
</summary>
<param name="buffer">The buffer that is being returned.</param>
<param name="array">The array that is being returned.</param>
</member>
<member name="T:Newtonsoft.Json.JsonConstructorAttribute">
<summary>
@@ -2177,38 +2145,6 @@
</summary>
<param name="token">The token to read from.</param>
</member>
<member name="M:Newtonsoft.Json.Linq.JTokenReader.ReadAsBytes">
<summary>
Reads the next JSON token from the stream as a <see cref="T:System.Byte"/>[].
</summary>
<returns>
A <see cref="T:System.Byte"/>[] or a null reference if the next JSON token is null. This method will return <c>null</c> at the end of an array.
</returns>
</member>
<member name="M:Newtonsoft.Json.Linq.JTokenReader.ReadAsDecimal">
<summary>
Reads the next JSON token from the stream as a <see cref="T:System.Nullable`1"/>.
</summary>
<returns>A <see cref="T:System.Nullable`1"/>. This method will return <c>null</c> at the end of an array.</returns>
</member>
<member name="M:Newtonsoft.Json.Linq.JTokenReader.ReadAsInt32">
<summary>
Reads the next JSON token from the stream as a <see cref="T:System.Nullable`1"/>.
</summary>
<returns>A <see cref="T:System.Nullable`1"/>. This method will return <c>null</c> at the end of an array.</returns>
</member>
<member name="M:Newtonsoft.Json.Linq.JTokenReader.ReadAsString">
<summary>
Reads the next JSON token from the stream as a <see cref="T:System.String"/>.
</summary>
<returns>A <see cref="T:System.String"/>. This method will return <c>null</c> at the end of an array.</returns>
</member>
<member name="M:Newtonsoft.Json.Linq.JTokenReader.ReadAsDateTime">
<summary>
Reads the next JSON token from the stream as a <see cref="T:System.Nullable`1"/>.
</summary>
<returns>A <see cref="T:System.Nullable`1"/>. This method will return <c>null</c> at the end of an array.</returns>
</member>
<member name="M:Newtonsoft.Json.Linq.JTokenReader.Read">
<summary>
Reads the next JSON token from the stream.
@@ -4489,9 +4425,9 @@
</member>
<member name="P:Newtonsoft.Json.Serialization.JsonProperty.Order">
<summary>
Gets or sets the order of serialization and deserialization of a member.
Gets or sets the order of serialization of a member.
</summary>
<value>The numeric order of serialization or deserialization.</value>
<value>The numeric order of serialization.</value>
</member>
<member name="P:Newtonsoft.Json.Serialization.JsonProperty.UnderlyingName">
<summary>
@@ -4806,6 +4742,11 @@
Gets or sets the extension data getter.
</summary>
</member>
<member name="P:Newtonsoft.Json.Serialization.JsonObjectContract.ExtensionDataValueType">
<summary>
Gets or sets the extension data value type.
</summary>
</member>
<member name="M:Newtonsoft.Json.Serialization.JsonObjectContract.#ctor(System.Type)">
<summary>
Initializes a new instance of the <see cref="T:Newtonsoft.Json.Serialization.JsonObjectContract"/> class.
@@ -6418,7 +6359,7 @@
</member>
<member name="P:Newtonsoft.Json.JsonSerializerSettings.Converters">
<summary>
Gets or sets a collection <see cref="T:Newtonsoft.Json.JsonConverter"/> that will be used during serialization.
Gets or sets a <see cref="T:Newtonsoft.Json.JsonConverter"/> collection that will be used during serialization.
</summary>
<value>The converters.</value>
</member>
@@ -6432,6 +6373,11 @@
<summary>
Gets or sets how type name writing and reading is handled by the serializer.
</summary>
<remarks>
<see cref="P:Newtonsoft.Json.JsonSerializerSettings.TypeNameHandling"/> should be used with caution when your application deserializes JSON from an external source.
Incoming types should be validated with a custom <see cref="T:System.Runtime.Serialization.SerializationBinder"/>
when deserializing with a value other than <c>TypeNameHandling.None</c>.
</remarks>
<value>The type name handling.</value>
</member>
<member name="P:Newtonsoft.Json.JsonSerializerSettings.MetadataPropertyHandling">
@@ -6655,6 +6601,12 @@
</summary>
<returns>A <see cref="T:System.Nullable`1"/>.</returns>
</member>
<member name="M:Newtonsoft.Json.JsonValidatingReader.ReadAsDouble">
<summary>
Reads the next JSON token from the stream as a <see cref="T:System.Nullable`1"/>.
</summary>
<returns>A <see cref="T:System.Nullable`1"/>.</returns>
</member>
<member name="M:Newtonsoft.Json.JsonValidatingReader.ReadAsString">
<summary>
Reads the next JSON token from the stream as a <see cref="T:System.String"/>.
@@ -6730,7 +6682,7 @@
</summary>
<param name="reader">The <c>TextReader</c> containing the XML data to read.</param>
</member>
<member name="P:Newtonsoft.Json.JsonTextReader.BufferPool">
<member name="P:Newtonsoft.Json.JsonTextReader.ArrayPool">
<summary>
Gets or sets the reader's character buffer pool.
</summary>
@@ -6743,21 +6695,13 @@
true if the next token was read successfully; false if there are no more tokens to read.
</returns>
</member>
<member name="M:Newtonsoft.Json.JsonTextReader.ReadAsBytes">
<summary>
Reads the next JSON token from the stream as a <see cref="T:System.Byte"/>[].
</summary>
<returns>
A <see cref="T:System.Byte"/>[] or a null reference if the next JSON token is null. This method will return <c>null</c> at the end of an array.
</returns>
</member>
<member name="M:Newtonsoft.Json.JsonTextReader.ReadAsDecimal">
<member name="M:Newtonsoft.Json.JsonTextReader.ReadAsInt32">
<summary>
Reads the next JSON token from the stream as a <see cref="T:System.Nullable`1"/>.
</summary>
<returns>A <see cref="T:System.Nullable`1"/>. This method will return <c>null</c> at the end of an array.</returns>
</member>
<member name="M:Newtonsoft.Json.JsonTextReader.ReadAsInt32">
<member name="M:Newtonsoft.Json.JsonTextReader.ReadAsDateTime">
<summary>
Reads the next JSON token from the stream as a <see cref="T:System.Nullable`1"/>.
</summary>
@@ -6769,7 +6713,19 @@
</summary>
<returns>A <see cref="T:System.String"/>. This method will return <c>null</c> at the end of an array.</returns>
</member>
<member name="M:Newtonsoft.Json.JsonTextReader.ReadAsDateTime">
<member name="M:Newtonsoft.Json.JsonTextReader.ReadAsBytes">
<summary>
Reads the next JSON token from the stream as a <see cref="T:System.Byte"/>[].
</summary>
<returns>A <see cref="T:System.Byte"/>[] or a null reference if the next JSON token is null. This method will return <c>null</c> at the end of an array.</returns>
</member>
<member name="M:Newtonsoft.Json.JsonTextReader.ReadAsDecimal">
<summary>
Reads the next JSON token from the stream as a <see cref="T:System.Nullable`1"/>.
</summary>
<returns>A <see cref="T:System.Nullable`1"/>. This method will return <c>null</c> at the end of an array.</returns>
</member>
<member name="M:Newtonsoft.Json.JsonTextReader.ReadAsDouble">
<summary>
Reads the next JSON token from the stream as a <see cref="T:System.Nullable`1"/>.
</summary>
@@ -6864,9 +6820,9 @@
</member>
<member name="P:Newtonsoft.Json.JsonPropertyAttribute.Order">
<summary>
Gets or sets the order of serialization and deserialization of a member.
Gets or sets the order of serialization of a member.
</summary>
<value>The numeric order of serialization or deserialization.</value>
<value>The numeric order of serialization.</value>
</member>
<member name="P:Newtonsoft.Json.JsonPropertyAttribute.Required">
<summary>
@@ -6921,9 +6877,9 @@
Represents a writer that provides a fast, non-cached, forward-only way of generating JSON data.
</summary>
</member>
<member name="P:Newtonsoft.Json.JsonTextWriter.BufferPool">
<member name="P:Newtonsoft.Json.JsonTextWriter.ArrayPool">
<summary>
Gets or sets the writer's character buffer pool.
Gets or sets the writer's character array pool.
</summary>
</member>
<member name="P:Newtonsoft.Json.JsonTextWriter.Indentation">
@@ -7515,6 +7471,12 @@
</summary>
<returns>A <see cref="T:System.Byte"/>[] or a null reference if the next JSON token is null. This method will return <c>null</c> at the end of an array.</returns>
</member>
<member name="M:Newtonsoft.Json.JsonReader.ReadAsDouble">
<summary>
Reads the next JSON token from the stream as a <see cref="T:System.Nullable`1"/>.
</summary>
<returns>A <see cref="T:System.Nullable`1"/>. This method will return <c>null</c> at the end of an array.</returns>
</member>
<member name="M:Newtonsoft.Json.JsonReader.ReadAsDecimal">
<summary>
Reads the next JSON token from the stream as a <see cref="T:System.Nullable`1"/>.
@@ -8121,6 +8083,11 @@
<summary>
Gets or sets how type name writing and reading is handled by the serializer.
</summary>
<remarks>
<see cref="P:Newtonsoft.Json.JsonSerializer.TypeNameHandling"/> should be used with caution when your application deserializes JSON from an external source.
Incoming types should be validated with a custom <see cref="T:System.Runtime.Serialization.SerializationBinder"/>
when deserializing with a value other than <c>TypeNameHandling.None</c>.
</remarks>
</member>
<member name="P:Newtonsoft.Json.JsonSerializer.TypeNameAssemblyFormat">
<summary>
@@ -9036,6 +9003,11 @@
<summary>
Specifies type name handling options for the <see cref="T:Newtonsoft.Json.JsonSerializer"/>.
</summary>
<remarks>
<see cref="T:Newtonsoft.Json.TypeNameHandling"/> should be used with caution when your application deserializes JSON from an external source.
Incoming types should be validated with a custom <see cref="T:System.Runtime.Serialization.SerializationBinder"/>
when deserializing with a value other than <c>TypeNameHandling.None</c>.
</remarks>
</member>
<member name="F:Newtonsoft.Json.TypeNameHandling.None">
<summary>
@@ -9590,6 +9562,12 @@
</summary>
<param name="ws">The string of white space characters.</param>
</member>
<member name="M:Newtonsoft.Json.JsonWriter.Dispose(System.Boolean)">
<summary>
Releases unmanaged and - optionally - managed resources
</summary>
<param name="disposing"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param>
</member>
<member name="M:Newtonsoft.Json.JsonWriter.SetWriteState(Newtonsoft.Json.JsonToken,System.Object)">
<summary>
Sets the state of the JsonWriter,

Binary file not shown.

View File

@@ -59,46 +59,6 @@
<param name="readRootValueAsArray">if set to <c>true</c> the root object will be read as a JSON array.</param>
<param name="dateTimeKindHandling">The <see cref="T:System.DateTimeKind" /> used when reading <see cref="T:System.DateTime"/> values from BSON.</param>
</member>
<member name="M:Newtonsoft.Json.Bson.BsonReader.ReadAsBytes">
<summary>
Reads the next JSON token from the stream as a <see cref="T:System.Byte"/>[].
</summary>
<returns>
A <see cref="T:System.Byte"/>[] or a null reference if the next JSON token is null. This method will return <c>null</c> at the end of an array.
</returns>
</member>
<member name="M:Newtonsoft.Json.Bson.BsonReader.ReadAsDecimal">
<summary>
Reads the next JSON token from the stream as a <see cref="T:System.Nullable`1"/>.
</summary>
<returns>A <see cref="T:System.Nullable`1"/>. This method will return <c>null</c> at the end of an array.</returns>
</member>
<member name="M:Newtonsoft.Json.Bson.BsonReader.ReadAsInt32">
<summary>
Reads the next JSON token from the stream as a <see cref="T:System.Nullable`1"/>.
</summary>
<returns>A <see cref="T:System.Nullable`1"/>. This method will return <c>null</c> at the end of an array.</returns>
</member>
<member name="M:Newtonsoft.Json.Bson.BsonReader.ReadAsString">
<summary>
Reads the next JSON token from the stream as a <see cref="T:System.String"/>.
</summary>
<returns>A <see cref="T:System.String"/>. This method will return <c>null</c> at the end of an array.</returns>
</member>
<member name="M:Newtonsoft.Json.Bson.BsonReader.ReadAsDateTime">
<summary>
Reads the next JSON token from the stream as a <see cref="T:System.Nullable`1"/>.
</summary>
<returns>A <see cref="T:System.Nullable`1"/>. This method will return <c>null</c> at the end of an array.</returns>
</member>
<member name="M:Newtonsoft.Json.Bson.BsonReader.ReadAsDateTimeOffset">
<summary>
Reads the next JSON token from the stream as a <see cref="T:System.Nullable`1"/>.
</summary>
<returns>
A <see cref="T:System.Nullable`1"/>. This method will return <c>null</c> at the end of an array.
</returns>
</member>
<member name="M:Newtonsoft.Json.Bson.BsonReader.Read">
<summary>
Reads the next JSON token from the stream.
@@ -977,24 +937,24 @@
Causes child objects to be indented according to the <see cref="P:Newtonsoft.Json.JsonTextWriter.Indentation"/> and <see cref="P:Newtonsoft.Json.JsonTextWriter.IndentChar"/> settings.
</summary>
</member>
<member name="T:Newtonsoft.Json.IJsonBufferPool`1">
<member name="T:Newtonsoft.Json.IArrayPool`1">
<summary>
Provides an interface for using pooled buffers.
Provides an interface for using pooled arrays.
</summary>
<typeparam name="T">The buffer type content.</typeparam>
<typeparam name="T">The array type content.</typeparam>
</member>
<member name="M:Newtonsoft.Json.IJsonBufferPool`1.RentBuffer(System.Int32)">
<member name="M:Newtonsoft.Json.IArrayPool`1.Rent(System.Int32)">
<summary>
Rent a buffer from the pool. This buffer must be returned when it is no longer needed.
Rent a array from the pool. This array must be returned when it is no longer needed.
</summary>
<param name="minSize">The minimum required size of the buffer. The returned buffer may be larger.</param>
<returns>The rented buffer from the pool.</returns>
<param name="minimumLength">The minimum required length of the array. The returned array may be longer.</param>
<returns>The rented array from the pool. This array must be returned when it is no longer needed.</returns>
</member>
<member name="M:Newtonsoft.Json.IJsonBufferPool`1.ReturnBuffer(`0[]@)">
<member name="M:Newtonsoft.Json.IArrayPool`1.Return(`0[])">
<summary>
Return a buffer to the pool.
Return an array to the pool.
</summary>
<param name="buffer">The buffer that is being returned.</param>
<param name="array">The array that is being returned.</param>
</member>
<member name="T:Newtonsoft.Json.JsonConstructorAttribute">
<summary>
@@ -2239,44 +2199,6 @@
</summary>
<param name="token">The token to read from.</param>
</member>
<member name="M:Newtonsoft.Json.Linq.JTokenReader.ReadAsBytes">
<summary>
Reads the next JSON token from the stream as a <see cref="T:System.Byte"/>[].
</summary>
<returns>
A <see cref="T:System.Byte"/>[] or a null reference if the next JSON token is null. This method will return <c>null</c> at the end of an array.
</returns>
</member>
<member name="M:Newtonsoft.Json.Linq.JTokenReader.ReadAsDecimal">
<summary>
Reads the next JSON token from the stream as a <see cref="T:System.Nullable`1"/>.
</summary>
<returns>A <see cref="T:System.Nullable`1"/>. This method will return <c>null</c> at the end of an array.</returns>
</member>
<member name="M:Newtonsoft.Json.Linq.JTokenReader.ReadAsInt32">
<summary>
Reads the next JSON token from the stream as a <see cref="T:System.Nullable`1"/>.
</summary>
<returns>A <see cref="T:System.Nullable`1"/>. This method will return <c>null</c> at the end of an array.</returns>
</member>
<member name="M:Newtonsoft.Json.Linq.JTokenReader.ReadAsString">
<summary>
Reads the next JSON token from the stream as a <see cref="T:System.String"/>.
</summary>
<returns>A <see cref="T:System.String"/>. This method will return <c>null</c> at the end of an array.</returns>
</member>
<member name="M:Newtonsoft.Json.Linq.JTokenReader.ReadAsDateTime">
<summary>
Reads the next JSON token from the stream as a <see cref="T:System.Nullable`1"/>.
</summary>
<returns>A <see cref="T:System.Nullable`1"/>. This method will return <c>null</c> at the end of an array.</returns>
</member>
<member name="M:Newtonsoft.Json.Linq.JTokenReader.ReadAsDateTimeOffset">
<summary>
Reads the next JSON token from the stream as a <see cref="T:System.Nullable`1"/>.
</summary>
<returns>A <see cref="T:System.Nullable`1"/>. This method will return <c>null</c> at the end of an array.</returns>
</member>
<member name="M:Newtonsoft.Json.Linq.JTokenReader.Read">
<summary>
Reads the next JSON token from the stream.
@@ -4597,9 +4519,9 @@
</member>
<member name="P:Newtonsoft.Json.Serialization.JsonProperty.Order">
<summary>
Gets or sets the order of serialization and deserialization of a member.
Gets or sets the order of serialization of a member.
</summary>
<value>The numeric order of serialization or deserialization.</value>
<value>The numeric order of serialization.</value>
</member>
<member name="P:Newtonsoft.Json.Serialization.JsonProperty.UnderlyingName">
<summary>
@@ -4914,6 +4836,11 @@
Gets or sets the extension data getter.
</summary>
</member>
<member name="P:Newtonsoft.Json.Serialization.JsonObjectContract.ExtensionDataValueType">
<summary>
Gets or sets the extension data value type.
</summary>
</member>
<member name="M:Newtonsoft.Json.Serialization.JsonObjectContract.#ctor(System.Type)">
<summary>
Initializes a new instance of the <see cref="T:Newtonsoft.Json.Serialization.JsonObjectContract"/> class.
@@ -5468,7 +5395,7 @@
</member>
<member name="P:Newtonsoft.Json.JsonSerializerSettings.Converters">
<summary>
Gets or sets a collection <see cref="T:Newtonsoft.Json.JsonConverter"/> that will be used during serialization.
Gets or sets a <see cref="T:Newtonsoft.Json.JsonConverter"/> collection that will be used during serialization.
</summary>
<value>The converters.</value>
</member>
@@ -5482,6 +5409,11 @@
<summary>
Gets or sets how type name writing and reading is handled by the serializer.
</summary>
<remarks>
<see cref="P:Newtonsoft.Json.JsonSerializerSettings.TypeNameHandling"/> should be used with caution when your application deserializes JSON from an external source.
Incoming types should be validated with a custom <see cref="T:System.Runtime.Serialization.SerializationBinder"/>
when deserializing with a value other than <c>TypeNameHandling.None</c>.
</remarks>
<value>The type name handling.</value>
</member>
<member name="P:Newtonsoft.Json.JsonSerializerSettings.MetadataPropertyHandling">
@@ -5705,6 +5637,12 @@
</summary>
<returns>A <see cref="T:System.Nullable`1"/>.</returns>
</member>
<member name="M:Newtonsoft.Json.JsonValidatingReader.ReadAsDouble">
<summary>
Reads the next JSON token from the stream as a <see cref="T:System.Nullable`1"/>.
</summary>
<returns>A <see cref="T:System.Nullable`1"/>.</returns>
</member>
<member name="M:Newtonsoft.Json.JsonValidatingReader.ReadAsString">
<summary>
Reads the next JSON token from the stream as a <see cref="T:System.String"/>.
@@ -5786,7 +5724,7 @@
</summary>
<param name="reader">The <c>TextReader</c> containing the XML data to read.</param>
</member>
<member name="P:Newtonsoft.Json.JsonTextReader.BufferPool">
<member name="P:Newtonsoft.Json.JsonTextReader.ArrayPool">
<summary>
Gets or sets the reader's character buffer pool.
</summary>
@@ -5799,21 +5737,13 @@
true if the next token was read successfully; false if there are no more tokens to read.
</returns>
</member>
<member name="M:Newtonsoft.Json.JsonTextReader.ReadAsBytes">
<summary>
Reads the next JSON token from the stream as a <see cref="T:System.Byte"/>[].
</summary>
<returns>
A <see cref="T:System.Byte"/>[] or a null reference if the next JSON token is null. This method will return <c>null</c> at the end of an array.
</returns>
</member>
<member name="M:Newtonsoft.Json.JsonTextReader.ReadAsDecimal">
<member name="M:Newtonsoft.Json.JsonTextReader.ReadAsInt32">
<summary>
Reads the next JSON token from the stream as a <see cref="T:System.Nullable`1"/>.
</summary>
<returns>A <see cref="T:System.Nullable`1"/>. This method will return <c>null</c> at the end of an array.</returns>
</member>
<member name="M:Newtonsoft.Json.JsonTextReader.ReadAsInt32">
<member name="M:Newtonsoft.Json.JsonTextReader.ReadAsDateTime">
<summary>
Reads the next JSON token from the stream as a <see cref="T:System.Nullable`1"/>.
</summary>
@@ -5825,17 +5755,29 @@
</summary>
<returns>A <see cref="T:System.String"/>. This method will return <c>null</c> at the end of an array.</returns>
</member>
<member name="M:Newtonsoft.Json.JsonTextReader.ReadAsDateTime">
<member name="M:Newtonsoft.Json.JsonTextReader.ReadAsBytes">
<summary>
Reads the next JSON token from the stream as a <see cref="T:System.Nullable`1"/>.
Reads the next JSON token from the stream as a <see cref="T:System.Byte"/>[].
</summary>
<returns>A <see cref="T:System.Nullable`1"/>. This method will return <c>null</c> at the end of an array.</returns>
<returns>A <see cref="T:System.Byte"/>[] or a null reference if the next JSON token is null. This method will return <c>null</c> at the end of an array.</returns>
</member>
<member name="M:Newtonsoft.Json.JsonTextReader.ReadAsDateTimeOffset">
<summary>
Reads the next JSON token from the stream as a <see cref="T:System.Nullable`1"/>.
</summary>
<returns>A <see cref="T:System.DateTimeOffset"/>. This method will return <c>null</c> at the end of an array.</returns>
<returns>A <see cref="T:System.Nullable`1"/>. This method will return <c>null</c> at the end of an array.</returns>
</member>
<member name="M:Newtonsoft.Json.JsonTextReader.ReadAsDecimal">
<summary>
Reads the next JSON token from the stream as a <see cref="T:System.Nullable`1"/>.
</summary>
<returns>A <see cref="T:System.Nullable`1"/>. This method will return <c>null</c> at the end of an array.</returns>
</member>
<member name="M:Newtonsoft.Json.JsonTextReader.ReadAsDouble">
<summary>
Reads the next JSON token from the stream as a <see cref="T:System.Nullable`1"/>.
</summary>
<returns>A <see cref="T:System.Nullable`1"/>. This method will return <c>null</c> at the end of an array.</returns>
</member>
<member name="M:Newtonsoft.Json.JsonTextReader.Close">
<summary>
@@ -5926,9 +5868,9 @@
</member>
<member name="P:Newtonsoft.Json.JsonPropertyAttribute.Order">
<summary>
Gets or sets the order of serialization and deserialization of a member.
Gets or sets the order of serialization of a member.
</summary>
<value>The numeric order of serialization or deserialization.</value>
<value>The numeric order of serialization.</value>
</member>
<member name="P:Newtonsoft.Json.JsonPropertyAttribute.Required">
<summary>
@@ -5983,9 +5925,9 @@
Represents a writer that provides a fast, non-cached, forward-only way of generating JSON data.
</summary>
</member>
<member name="P:Newtonsoft.Json.JsonTextWriter.BufferPool">
<member name="P:Newtonsoft.Json.JsonTextWriter.ArrayPool">
<summary>
Gets or sets the writer's character buffer pool.
Gets or sets the writer's character array pool.
</summary>
</member>
<member name="P:Newtonsoft.Json.JsonTextWriter.Indentation">
@@ -6583,6 +6525,12 @@
</summary>
<returns>A <see cref="T:System.Byte"/>[] or a null reference if the next JSON token is null. This method will return <c>null</c> at the end of an array.</returns>
</member>
<member name="M:Newtonsoft.Json.JsonReader.ReadAsDouble">
<summary>
Reads the next JSON token from the stream as a <see cref="T:System.Nullable`1"/>.
</summary>
<returns>A <see cref="T:System.Nullable`1"/>. This method will return <c>null</c> at the end of an array.</returns>
</member>
<member name="M:Newtonsoft.Json.JsonReader.ReadAsDecimal">
<summary>
Reads the next JSON token from the stream as a <see cref="T:System.Nullable`1"/>.
@@ -7262,6 +7210,11 @@
<summary>
Gets or sets how type name writing and reading is handled by the serializer.
</summary>
<remarks>
<see cref="P:Newtonsoft.Json.JsonSerializer.TypeNameHandling"/> should be used with caution when your application deserializes JSON from an external source.
Incoming types should be validated with a custom <see cref="T:System.Runtime.Serialization.SerializationBinder"/>
when deserializing with a value other than <c>TypeNameHandling.None</c>.
</remarks>
</member>
<member name="P:Newtonsoft.Json.JsonSerializer.TypeNameAssemblyFormat">
<summary>
@@ -8177,6 +8130,11 @@
<summary>
Specifies type name handling options for the <see cref="T:Newtonsoft.Json.JsonSerializer"/>.
</summary>
<remarks>
<see cref="T:Newtonsoft.Json.TypeNameHandling"/> should be used with caution when your application deserializes JSON from an external source.
Incoming types should be validated with a custom <see cref="T:System.Runtime.Serialization.SerializationBinder"/>
when deserializing with a value other than <c>TypeNameHandling.None</c>.
</remarks>
</member>
<member name="F:Newtonsoft.Json.TypeNameHandling.None">
<summary>
@@ -8743,6 +8701,12 @@
</summary>
<param name="ws">The string of white space characters.</param>
</member>
<member name="M:Newtonsoft.Json.JsonWriter.Dispose(System.Boolean)">
<summary>
Releases unmanaged and - optionally - managed resources
</summary>
<param name="disposing"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param>
</member>
<member name="M:Newtonsoft.Json.JsonWriter.SetWriteState(Newtonsoft.Json.JsonToken,System.Object)">
<summary>
Sets the state of the JsonWriter,

Binary file not shown.

Binary file not shown.

View File

@@ -76,46 +76,6 @@
<param name="readRootValueAsArray">if set to <c>true</c> the root object will be read as a JSON array.</param>
<param name="dateTimeKindHandling">The <see cref="T:System.DateTimeKind" /> used when reading <see cref="T:System.DateTime"/> values from BSON.</param>
</member>
<member name="M:Newtonsoft.Json.Bson.BsonReader.ReadAsBytes">
<summary>
Reads the next JSON token from the stream as a <see cref="T:System.Byte"/>[].
</summary>
<returns>
A <see cref="T:System.Byte"/>[] or a null reference if the next JSON token is null. This method will return <c>null</c> at the end of an array.
</returns>
</member>
<member name="M:Newtonsoft.Json.Bson.BsonReader.ReadAsDecimal">
<summary>
Reads the next JSON token from the stream as a <see cref="T:System.Nullable`1"/>.
</summary>
<returns>A <see cref="T:System.Nullable`1"/>. This method will return <c>null</c> at the end of an array.</returns>
</member>
<member name="M:Newtonsoft.Json.Bson.BsonReader.ReadAsInt32">
<summary>
Reads the next JSON token from the stream as a <see cref="T:System.Nullable`1"/>.
</summary>
<returns>A <see cref="T:System.Nullable`1"/>. This method will return <c>null</c> at the end of an array.</returns>
</member>
<member name="M:Newtonsoft.Json.Bson.BsonReader.ReadAsString">
<summary>
Reads the next JSON token from the stream as a <see cref="T:System.String"/>.
</summary>
<returns>A <see cref="T:System.String"/>. This method will return <c>null</c> at the end of an array.</returns>
</member>
<member name="M:Newtonsoft.Json.Bson.BsonReader.ReadAsDateTime">
<summary>
Reads the next JSON token from the stream as a <see cref="T:System.Nullable`1"/>.
</summary>
<returns>A <see cref="T:System.Nullable`1"/>. This method will return <c>null</c> at the end of an array.</returns>
</member>
<member name="M:Newtonsoft.Json.Bson.BsonReader.ReadAsDateTimeOffset">
<summary>
Reads the next JSON token from the stream as a <see cref="T:System.Nullable`1"/>.
</summary>
<returns>
A <see cref="T:System.Nullable`1"/>. This method will return <c>null</c> at the end of an array.
</returns>
</member>
<member name="M:Newtonsoft.Json.Bson.BsonReader.Read">
<summary>
Reads the next JSON token from the stream.
@@ -857,24 +817,24 @@
Causes child objects to be indented according to the <see cref="P:Newtonsoft.Json.JsonTextWriter.Indentation"/> and <see cref="P:Newtonsoft.Json.JsonTextWriter.IndentChar"/> settings.
</summary>
</member>
<member name="T:Newtonsoft.Json.IJsonBufferPool`1">
<member name="T:Newtonsoft.Json.IArrayPool`1">
<summary>
Provides an interface for using pooled buffers.
Provides an interface for using pooled arrays.
</summary>
<typeparam name="T">The buffer type content.</typeparam>
<typeparam name="T">The array type content.</typeparam>
</member>
<member name="M:Newtonsoft.Json.IJsonBufferPool`1.RentBuffer(System.Int32)">
<member name="M:Newtonsoft.Json.IArrayPool`1.Rent(System.Int32)">
<summary>
Rent a buffer from the pool. This buffer must be returned when it is no longer needed.
Rent a array from the pool. This array must be returned when it is no longer needed.
</summary>
<param name="minSize">The minimum required size of the buffer. The returned buffer may be larger.</param>
<returns>The rented buffer from the pool.</returns>
<param name="minimumLength">The minimum required length of the array. The returned array may be longer.</param>
<returns>The rented array from the pool. This array must be returned when it is no longer needed.</returns>
</member>
<member name="M:Newtonsoft.Json.IJsonBufferPool`1.ReturnBuffer(`0[]@)">
<member name="M:Newtonsoft.Json.IArrayPool`1.Return(`0[])">
<summary>
Return a buffer to the pool.
Return an array to the pool.
</summary>
<param name="buffer">The buffer that is being returned.</param>
<param name="array">The array that is being returned.</param>
</member>
<member name="T:Newtonsoft.Json.IJsonLineInfo">
<summary>
@@ -1719,9 +1679,9 @@
</member>
<member name="P:Newtonsoft.Json.JsonPropertyAttribute.Order">
<summary>
Gets or sets the order of serialization and deserialization of a member.
Gets or sets the order of serialization of a member.
</summary>
<value>The numeric order of serialization or deserialization.</value>
<value>The numeric order of serialization.</value>
</member>
<member name="P:Newtonsoft.Json.JsonPropertyAttribute.Required">
<summary>
@@ -1956,6 +1916,12 @@
</summary>
<returns>A <see cref="T:System.Byte"/>[] or a null reference if the next JSON token is null. This method will return <c>null</c> at the end of an array.</returns>
</member>
<member name="M:Newtonsoft.Json.JsonReader.ReadAsDouble">
<summary>
Reads the next JSON token from the stream as a <see cref="T:System.Nullable`1"/>.
</summary>
<returns>A <see cref="T:System.Nullable`1"/>. This method will return <c>null</c> at the end of an array.</returns>
</member>
<member name="M:Newtonsoft.Json.JsonReader.ReadAsDecimal">
<summary>
Reads the next JSON token from the stream as a <see cref="T:System.Nullable`1"/>.
@@ -2123,6 +2089,11 @@
<summary>
Gets or sets how type name writing and reading is handled by the serializer.
</summary>
<remarks>
<see cref="P:Newtonsoft.Json.JsonSerializer.TypeNameHandling"/> should be used with caution when your application deserializes JSON from an external source.
Incoming types should be validated with a custom <see cref="T:System.Runtime.Serialization.SerializationBinder"/>
when deserializing with a value other than <c>TypeNameHandling.None</c>.
</remarks>
</member>
<member name="P:Newtonsoft.Json.JsonSerializer.TypeNameAssemblyFormat">
<summary>
@@ -2433,7 +2404,7 @@
</member>
<member name="P:Newtonsoft.Json.JsonSerializerSettings.Converters">
<summary>
Gets or sets a collection <see cref="T:Newtonsoft.Json.JsonConverter"/> that will be used during serialization.
Gets or sets a <see cref="T:Newtonsoft.Json.JsonConverter"/> collection that will be used during serialization.
</summary>
<value>The converters.</value>
</member>
@@ -2447,6 +2418,11 @@
<summary>
Gets or sets how type name writing and reading is handled by the serializer.
</summary>
<remarks>
<see cref="P:Newtonsoft.Json.JsonSerializerSettings.TypeNameHandling"/> should be used with caution when your application deserializes JSON from an external source.
Incoming types should be validated with a custom <see cref="T:System.Runtime.Serialization.SerializationBinder"/>
when deserializing with a value other than <c>TypeNameHandling.None</c>.
</remarks>
<value>The type name handling.</value>
</member>
<member name="P:Newtonsoft.Json.JsonSerializerSettings.MetadataPropertyHandling">
@@ -2592,7 +2568,7 @@
</summary>
<param name="reader">The <c>TextReader</c> containing the XML data to read.</param>
</member>
<member name="P:Newtonsoft.Json.JsonTextReader.BufferPool">
<member name="P:Newtonsoft.Json.JsonTextReader.ArrayPool">
<summary>
Gets or sets the reader's character buffer pool.
</summary>
@@ -2605,21 +2581,13 @@
true if the next token was read successfully; false if there are no more tokens to read.
</returns>
</member>
<member name="M:Newtonsoft.Json.JsonTextReader.ReadAsBytes">
<summary>
Reads the next JSON token from the stream as a <see cref="T:System.Byte"/>[].
</summary>
<returns>
A <see cref="T:System.Byte"/>[] or a null reference if the next JSON token is null. This method will return <c>null</c> at the end of an array.
</returns>
</member>
<member name="M:Newtonsoft.Json.JsonTextReader.ReadAsDecimal">
<member name="M:Newtonsoft.Json.JsonTextReader.ReadAsInt32">
<summary>
Reads the next JSON token from the stream as a <see cref="T:System.Nullable`1"/>.
</summary>
<returns>A <see cref="T:System.Nullable`1"/>. This method will return <c>null</c> at the end of an array.</returns>
</member>
<member name="M:Newtonsoft.Json.JsonTextReader.ReadAsInt32">
<member name="M:Newtonsoft.Json.JsonTextReader.ReadAsDateTime">
<summary>
Reads the next JSON token from the stream as a <see cref="T:System.Nullable`1"/>.
</summary>
@@ -2631,17 +2599,29 @@
</summary>
<returns>A <see cref="T:System.String"/>. This method will return <c>null</c> at the end of an array.</returns>
</member>
<member name="M:Newtonsoft.Json.JsonTextReader.ReadAsDateTime">
<member name="M:Newtonsoft.Json.JsonTextReader.ReadAsBytes">
<summary>
Reads the next JSON token from the stream as a <see cref="T:System.Nullable`1"/>.
Reads the next JSON token from the stream as a <see cref="T:System.Byte"/>[].
</summary>
<returns>A <see cref="T:System.Nullable`1"/>. This method will return <c>null</c> at the end of an array.</returns>
<returns>A <see cref="T:System.Byte"/>[] or a null reference if the next JSON token is null. This method will return <c>null</c> at the end of an array.</returns>
</member>
<member name="M:Newtonsoft.Json.JsonTextReader.ReadAsDateTimeOffset">
<summary>
Reads the next JSON token from the stream as a <see cref="T:System.Nullable`1"/>.
</summary>
<returns>A <see cref="T:System.DateTimeOffset"/>. This method will return <c>null</c> at the end of an array.</returns>
<returns>A <see cref="T:System.Nullable`1"/>. This method will return <c>null</c> at the end of an array.</returns>
</member>
<member name="M:Newtonsoft.Json.JsonTextReader.ReadAsDecimal">
<summary>
Reads the next JSON token from the stream as a <see cref="T:System.Nullable`1"/>.
</summary>
<returns>A <see cref="T:System.Nullable`1"/>. This method will return <c>null</c> at the end of an array.</returns>
</member>
<member name="M:Newtonsoft.Json.JsonTextReader.ReadAsDouble">
<summary>
Reads the next JSON token from the stream as a <see cref="T:System.Nullable`1"/>.
</summary>
<returns>A <see cref="T:System.Nullable`1"/>. This method will return <c>null</c> at the end of an array.</returns>
</member>
<member name="M:Newtonsoft.Json.JsonTextReader.Close">
<summary>
@@ -2677,9 +2657,9 @@
Represents a writer that provides a fast, non-cached, forward-only way of generating JSON data.
</summary>
</member>
<member name="P:Newtonsoft.Json.JsonTextWriter.BufferPool">
<member name="P:Newtonsoft.Json.JsonTextWriter.ArrayPool">
<summary>
Gets or sets the writer's character buffer pool.
Gets or sets the writer's character array pool.
</summary>
</member>
<member name="P:Newtonsoft.Json.JsonTextWriter.Indentation">
@@ -3119,6 +3099,12 @@
</summary>
<returns>A <see cref="T:System.Nullable`1"/>.</returns>
</member>
<member name="M:Newtonsoft.Json.JsonValidatingReader.ReadAsDouble">
<summary>
Reads the next JSON token from the stream as a <see cref="T:System.Nullable`1"/>.
</summary>
<returns>A <see cref="T:System.Nullable`1"/>.</returns>
</member>
<member name="M:Newtonsoft.Json.JsonValidatingReader.ReadAsString">
<summary>
Reads the next JSON token from the stream as a <see cref="T:System.String"/>.
@@ -3590,6 +3576,12 @@
</summary>
<param name="ws">The string of white space characters.</param>
</member>
<member name="M:Newtonsoft.Json.JsonWriter.Dispose(System.Boolean)">
<summary>
Releases unmanaged and - optionally - managed resources
</summary>
<param name="disposing"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param>
</member>
<member name="M:Newtonsoft.Json.JsonWriter.SetWriteState(Newtonsoft.Json.JsonToken,System.Object)">
<summary>
Sets the state of the JsonWriter,
@@ -5504,44 +5496,6 @@
</summary>
<param name="token">The token to read from.</param>
</member>
<member name="M:Newtonsoft.Json.Linq.JTokenReader.ReadAsBytes">
<summary>
Reads the next JSON token from the stream as a <see cref="T:System.Byte"/>[].
</summary>
<returns>
A <see cref="T:System.Byte"/>[] or a null reference if the next JSON token is null. This method will return <c>null</c> at the end of an array.
</returns>
</member>
<member name="M:Newtonsoft.Json.Linq.JTokenReader.ReadAsDecimal">
<summary>
Reads the next JSON token from the stream as a <see cref="T:System.Nullable`1"/>.
</summary>
<returns>A <see cref="T:System.Nullable`1"/>. This method will return <c>null</c> at the end of an array.</returns>
</member>
<member name="M:Newtonsoft.Json.Linq.JTokenReader.ReadAsInt32">
<summary>
Reads the next JSON token from the stream as a <see cref="T:System.Nullable`1"/>.
</summary>
<returns>A <see cref="T:System.Nullable`1"/>. This method will return <c>null</c> at the end of an array.</returns>
</member>
<member name="M:Newtonsoft.Json.Linq.JTokenReader.ReadAsString">
<summary>
Reads the next JSON token from the stream as a <see cref="T:System.String"/>.
</summary>
<returns>A <see cref="T:System.String"/>. This method will return <c>null</c> at the end of an array.</returns>
</member>
<member name="M:Newtonsoft.Json.Linq.JTokenReader.ReadAsDateTime">
<summary>
Reads the next JSON token from the stream as a <see cref="T:System.Nullable`1"/>.
</summary>
<returns>A <see cref="T:System.Nullable`1"/>. This method will return <c>null</c> at the end of an array.</returns>
</member>
<member name="M:Newtonsoft.Json.Linq.JTokenReader.ReadAsDateTimeOffset">
<summary>
Reads the next JSON token from the stream as a <see cref="T:System.Nullable`1"/>.
</summary>
<returns>A <see cref="T:System.Nullable`1"/>. This method will return <c>null</c> at the end of an array.</returns>
</member>
<member name="M:Newtonsoft.Json.Linq.JTokenReader.Read">
<summary>
Reads the next JSON token from the stream.
@@ -7619,6 +7573,11 @@
Gets or sets the extension data getter.
</summary>
</member>
<member name="P:Newtonsoft.Json.Serialization.JsonObjectContract.ExtensionDataValueType">
<summary>
Gets or sets the extension data value type.
</summary>
</member>
<member name="M:Newtonsoft.Json.Serialization.JsonObjectContract.#ctor(System.Type)">
<summary>
Initializes a new instance of the <see cref="T:Newtonsoft.Json.Serialization.JsonObjectContract"/> class.
@@ -7655,9 +7614,9 @@
</member>
<member name="P:Newtonsoft.Json.Serialization.JsonProperty.Order">
<summary>
Gets or sets the order of serialization and deserialization of a member.
Gets or sets the order of serialization of a member.
</summary>
<value>The numeric order of serialization or deserialization.</value>
<value>The numeric order of serialization.</value>
</member>
<member name="P:Newtonsoft.Json.Serialization.JsonProperty.UnderlyingName">
<summary>
@@ -8052,6 +8011,11 @@
<summary>
Specifies type name handling options for the <see cref="T:Newtonsoft.Json.JsonSerializer"/>.
</summary>
<remarks>
<see cref="T:Newtonsoft.Json.TypeNameHandling"/> should be used with caution when your application deserializes JSON from an external source.
Incoming types should be validated with a custom <see cref="T:System.Runtime.Serialization.SerializationBinder"/>
when deserializing with a value other than <c>TypeNameHandling.None</c>.
</remarks>
</member>
<member name="F:Newtonsoft.Json.TypeNameHandling.None">
<summary>

View File

@@ -76,46 +76,6 @@
<param name="readRootValueAsArray">if set to <c>true</c> the root object will be read as a JSON array.</param>
<param name="dateTimeKindHandling">The <see cref="T:System.DateTimeKind" /> used when reading <see cref="T:System.DateTime"/> values from BSON.</param>
</member>
<member name="M:Newtonsoft.Json.Bson.BsonReader.ReadAsBytes">
<summary>
Reads the next JSON token from the stream as a <see cref="T:System.Byte"/>[].
</summary>
<returns>
A <see cref="T:System.Byte"/>[] or a null reference if the next JSON token is null. This method will return <c>null</c> at the end of an array.
</returns>
</member>
<member name="M:Newtonsoft.Json.Bson.BsonReader.ReadAsDecimal">
<summary>
Reads the next JSON token from the stream as a <see cref="T:System.Nullable`1"/>.
</summary>
<returns>A <see cref="T:System.Nullable`1"/>. This method will return <c>null</c> at the end of an array.</returns>
</member>
<member name="M:Newtonsoft.Json.Bson.BsonReader.ReadAsInt32">
<summary>
Reads the next JSON token from the stream as a <see cref="T:System.Nullable`1"/>.
</summary>
<returns>A <see cref="T:System.Nullable`1"/>. This method will return <c>null</c> at the end of an array.</returns>
</member>
<member name="M:Newtonsoft.Json.Bson.BsonReader.ReadAsString">
<summary>
Reads the next JSON token from the stream as a <see cref="T:System.String"/>.
</summary>
<returns>A <see cref="T:System.String"/>. This method will return <c>null</c> at the end of an array.</returns>
</member>
<member name="M:Newtonsoft.Json.Bson.BsonReader.ReadAsDateTime">
<summary>
Reads the next JSON token from the stream as a <see cref="T:System.Nullable`1"/>.
</summary>
<returns>A <see cref="T:System.Nullable`1"/>. This method will return <c>null</c> at the end of an array.</returns>
</member>
<member name="M:Newtonsoft.Json.Bson.BsonReader.ReadAsDateTimeOffset">
<summary>
Reads the next JSON token from the stream as a <see cref="T:System.Nullable`1"/>.
</summary>
<returns>
A <see cref="T:System.Nullable`1"/>. This method will return <c>null</c> at the end of an array.
</returns>
</member>
<member name="M:Newtonsoft.Json.Bson.BsonReader.Read">
<summary>
Reads the next JSON token from the stream.
@@ -956,24 +916,24 @@
Causes child objects to be indented according to the <see cref="P:Newtonsoft.Json.JsonTextWriter.Indentation"/> and <see cref="P:Newtonsoft.Json.JsonTextWriter.IndentChar"/> settings.
</summary>
</member>
<member name="T:Newtonsoft.Json.IJsonBufferPool`1">
<member name="T:Newtonsoft.Json.IArrayPool`1">
<summary>
Provides an interface for using pooled buffers.
Provides an interface for using pooled arrays.
</summary>
<typeparam name="T">The buffer type content.</typeparam>
<typeparam name="T">The array type content.</typeparam>
</member>
<member name="M:Newtonsoft.Json.IJsonBufferPool`1.RentBuffer(System.Int32)">
<member name="M:Newtonsoft.Json.IArrayPool`1.Rent(System.Int32)">
<summary>
Rent a buffer from the pool. This buffer must be returned when it is no longer needed.
Rent a array from the pool. This array must be returned when it is no longer needed.
</summary>
<param name="minSize">The minimum required size of the buffer. The returned buffer may be larger.</param>
<returns>The rented buffer from the pool.</returns>
<param name="minimumLength">The minimum required length of the array. The returned array may be longer.</param>
<returns>The rented array from the pool. This array must be returned when it is no longer needed.</returns>
</member>
<member name="M:Newtonsoft.Json.IJsonBufferPool`1.ReturnBuffer(`0[]@)">
<member name="M:Newtonsoft.Json.IArrayPool`1.Return(`0[])">
<summary>
Return a buffer to the pool.
Return an array to the pool.
</summary>
<param name="buffer">The buffer that is being returned.</param>
<param name="array">The array that is being returned.</param>
</member>
<member name="T:Newtonsoft.Json.IJsonLineInfo">
<summary>
@@ -1969,9 +1929,9 @@
</member>
<member name="P:Newtonsoft.Json.JsonPropertyAttribute.Order">
<summary>
Gets or sets the order of serialization and deserialization of a member.
Gets or sets the order of serialization of a member.
</summary>
<value>The numeric order of serialization or deserialization.</value>
<value>The numeric order of serialization.</value>
</member>
<member name="P:Newtonsoft.Json.JsonPropertyAttribute.Required">
<summary>
@@ -2206,6 +2166,12 @@
</summary>
<returns>A <see cref="T:System.Byte"/>[] or a null reference if the next JSON token is null. This method will return <c>null</c> at the end of an array.</returns>
</member>
<member name="M:Newtonsoft.Json.JsonReader.ReadAsDouble">
<summary>
Reads the next JSON token from the stream as a <see cref="T:System.Nullable`1"/>.
</summary>
<returns>A <see cref="T:System.Nullable`1"/>. This method will return <c>null</c> at the end of an array.</returns>
</member>
<member name="M:Newtonsoft.Json.JsonReader.ReadAsDecimal">
<summary>
Reads the next JSON token from the stream as a <see cref="T:System.Nullable`1"/>.
@@ -2373,6 +2339,11 @@
<summary>
Gets or sets how type name writing and reading is handled by the serializer.
</summary>
<remarks>
<see cref="P:Newtonsoft.Json.JsonSerializer.TypeNameHandling"/> should be used with caution when your application deserializes JSON from an external source.
Incoming types should be validated with a custom <see cref="T:System.Runtime.Serialization.SerializationBinder"/>
when deserializing with a value other than <c>TypeNameHandling.None</c>.
</remarks>
</member>
<member name="P:Newtonsoft.Json.JsonSerializer.TypeNameAssemblyFormat">
<summary>
@@ -2683,7 +2654,7 @@
</member>
<member name="P:Newtonsoft.Json.JsonSerializerSettings.Converters">
<summary>
Gets or sets a collection <see cref="T:Newtonsoft.Json.JsonConverter"/> that will be used during serialization.
Gets or sets a <see cref="T:Newtonsoft.Json.JsonConverter"/> collection that will be used during serialization.
</summary>
<value>The converters.</value>
</member>
@@ -2697,6 +2668,11 @@
<summary>
Gets or sets how type name writing and reading is handled by the serializer.
</summary>
<remarks>
<see cref="P:Newtonsoft.Json.JsonSerializerSettings.TypeNameHandling"/> should be used with caution when your application deserializes JSON from an external source.
Incoming types should be validated with a custom <see cref="T:System.Runtime.Serialization.SerializationBinder"/>
when deserializing with a value other than <c>TypeNameHandling.None</c>.
</remarks>
<value>The type name handling.</value>
</member>
<member name="P:Newtonsoft.Json.JsonSerializerSettings.MetadataPropertyHandling">
@@ -2842,7 +2818,7 @@
</summary>
<param name="reader">The <c>TextReader</c> containing the XML data to read.</param>
</member>
<member name="P:Newtonsoft.Json.JsonTextReader.BufferPool">
<member name="P:Newtonsoft.Json.JsonTextReader.ArrayPool">
<summary>
Gets or sets the reader's character buffer pool.
</summary>
@@ -2855,21 +2831,13 @@
true if the next token was read successfully; false if there are no more tokens to read.
</returns>
</member>
<member name="M:Newtonsoft.Json.JsonTextReader.ReadAsBytes">
<summary>
Reads the next JSON token from the stream as a <see cref="T:System.Byte"/>[].
</summary>
<returns>
A <see cref="T:System.Byte"/>[] or a null reference if the next JSON token is null. This method will return <c>null</c> at the end of an array.
</returns>
</member>
<member name="M:Newtonsoft.Json.JsonTextReader.ReadAsDecimal">
<member name="M:Newtonsoft.Json.JsonTextReader.ReadAsInt32">
<summary>
Reads the next JSON token from the stream as a <see cref="T:System.Nullable`1"/>.
</summary>
<returns>A <see cref="T:System.Nullable`1"/>. This method will return <c>null</c> at the end of an array.</returns>
</member>
<member name="M:Newtonsoft.Json.JsonTextReader.ReadAsInt32">
<member name="M:Newtonsoft.Json.JsonTextReader.ReadAsDateTime">
<summary>
Reads the next JSON token from the stream as a <see cref="T:System.Nullable`1"/>.
</summary>
@@ -2881,17 +2849,29 @@
</summary>
<returns>A <see cref="T:System.String"/>. This method will return <c>null</c> at the end of an array.</returns>
</member>
<member name="M:Newtonsoft.Json.JsonTextReader.ReadAsDateTime">
<member name="M:Newtonsoft.Json.JsonTextReader.ReadAsBytes">
<summary>
Reads the next JSON token from the stream as a <see cref="T:System.Nullable`1"/>.
Reads the next JSON token from the stream as a <see cref="T:System.Byte"/>[].
</summary>
<returns>A <see cref="T:System.Nullable`1"/>. This method will return <c>null</c> at the end of an array.</returns>
<returns>A <see cref="T:System.Byte"/>[] or a null reference if the next JSON token is null. This method will return <c>null</c> at the end of an array.</returns>
</member>
<member name="M:Newtonsoft.Json.JsonTextReader.ReadAsDateTimeOffset">
<summary>
Reads the next JSON token from the stream as a <see cref="T:System.Nullable`1"/>.
</summary>
<returns>A <see cref="T:System.DateTimeOffset"/>. This method will return <c>null</c> at the end of an array.</returns>
<returns>A <see cref="T:System.Nullable`1"/>. This method will return <c>null</c> at the end of an array.</returns>
</member>
<member name="M:Newtonsoft.Json.JsonTextReader.ReadAsDecimal">
<summary>
Reads the next JSON token from the stream as a <see cref="T:System.Nullable`1"/>.
</summary>
<returns>A <see cref="T:System.Nullable`1"/>. This method will return <c>null</c> at the end of an array.</returns>
</member>
<member name="M:Newtonsoft.Json.JsonTextReader.ReadAsDouble">
<summary>
Reads the next JSON token from the stream as a <see cref="T:System.Nullable`1"/>.
</summary>
<returns>A <see cref="T:System.Nullable`1"/>. This method will return <c>null</c> at the end of an array.</returns>
</member>
<member name="M:Newtonsoft.Json.JsonTextReader.Close">
<summary>
@@ -2927,9 +2907,9 @@
Represents a writer that provides a fast, non-cached, forward-only way of generating JSON data.
</summary>
</member>
<member name="P:Newtonsoft.Json.JsonTextWriter.BufferPool">
<member name="P:Newtonsoft.Json.JsonTextWriter.ArrayPool">
<summary>
Gets or sets the writer's character buffer pool.
Gets or sets the writer's character array pool.
</summary>
</member>
<member name="P:Newtonsoft.Json.JsonTextWriter.Indentation">
@@ -3369,6 +3349,12 @@
</summary>
<returns>A <see cref="T:System.Nullable`1"/>.</returns>
</member>
<member name="M:Newtonsoft.Json.JsonValidatingReader.ReadAsDouble">
<summary>
Reads the next JSON token from the stream as a <see cref="T:System.Nullable`1"/>.
</summary>
<returns>A <see cref="T:System.Nullable`1"/>.</returns>
</member>
<member name="M:Newtonsoft.Json.JsonValidatingReader.ReadAsString">
<summary>
Reads the next JSON token from the stream as a <see cref="T:System.String"/>.
@@ -3840,6 +3826,12 @@
</summary>
<param name="ws">The string of white space characters.</param>
</member>
<member name="M:Newtonsoft.Json.JsonWriter.Dispose(System.Boolean)">
<summary>
Releases unmanaged and - optionally - managed resources
</summary>
<param name="disposing"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param>
</member>
<member name="M:Newtonsoft.Json.JsonWriter.SetWriteState(Newtonsoft.Json.JsonToken,System.Object)">
<summary>
Sets the state of the JsonWriter,
@@ -5792,44 +5784,6 @@
</summary>
<param name="token">The token to read from.</param>
</member>
<member name="M:Newtonsoft.Json.Linq.JTokenReader.ReadAsBytes">
<summary>
Reads the next JSON token from the stream as a <see cref="T:System.Byte"/>[].
</summary>
<returns>
A <see cref="T:System.Byte"/>[] or a null reference if the next JSON token is null. This method will return <c>null</c> at the end of an array.
</returns>
</member>
<member name="M:Newtonsoft.Json.Linq.JTokenReader.ReadAsDecimal">
<summary>
Reads the next JSON token from the stream as a <see cref="T:System.Nullable`1"/>.
</summary>
<returns>A <see cref="T:System.Nullable`1"/>. This method will return <c>null</c> at the end of an array.</returns>
</member>
<member name="M:Newtonsoft.Json.Linq.JTokenReader.ReadAsInt32">
<summary>
Reads the next JSON token from the stream as a <see cref="T:System.Nullable`1"/>.
</summary>
<returns>A <see cref="T:System.Nullable`1"/>. This method will return <c>null</c> at the end of an array.</returns>
</member>
<member name="M:Newtonsoft.Json.Linq.JTokenReader.ReadAsString">
<summary>
Reads the next JSON token from the stream as a <see cref="T:System.String"/>.
</summary>
<returns>A <see cref="T:System.String"/>. This method will return <c>null</c> at the end of an array.</returns>
</member>
<member name="M:Newtonsoft.Json.Linq.JTokenReader.ReadAsDateTime">
<summary>
Reads the next JSON token from the stream as a <see cref="T:System.Nullable`1"/>.
</summary>
<returns>A <see cref="T:System.Nullable`1"/>. This method will return <c>null</c> at the end of an array.</returns>
</member>
<member name="M:Newtonsoft.Json.Linq.JTokenReader.ReadAsDateTimeOffset">
<summary>
Reads the next JSON token from the stream as a <see cref="T:System.Nullable`1"/>.
</summary>
<returns>A <see cref="T:System.Nullable`1"/>. This method will return <c>null</c> at the end of an array.</returns>
</member>
<member name="M:Newtonsoft.Json.Linq.JTokenReader.Read">
<summary>
Reads the next JSON token from the stream.
@@ -7940,6 +7894,11 @@
Gets or sets the extension data getter.
</summary>
</member>
<member name="P:Newtonsoft.Json.Serialization.JsonObjectContract.ExtensionDataValueType">
<summary>
Gets or sets the extension data value type.
</summary>
</member>
<member name="M:Newtonsoft.Json.Serialization.JsonObjectContract.#ctor(System.Type)">
<summary>
Initializes a new instance of the <see cref="T:Newtonsoft.Json.Serialization.JsonObjectContract"/> class.
@@ -7976,9 +7935,9 @@
</member>
<member name="P:Newtonsoft.Json.Serialization.JsonProperty.Order">
<summary>
Gets or sets the order of serialization and deserialization of a member.
Gets or sets the order of serialization of a member.
</summary>
<value>The numeric order of serialization or deserialization.</value>
<value>The numeric order of serialization.</value>
</member>
<member name="P:Newtonsoft.Json.Serialization.JsonProperty.UnderlyingName">
<summary>
@@ -8373,6 +8332,11 @@
<summary>
Specifies type name handling options for the <see cref="T:Newtonsoft.Json.JsonSerializer"/>.
</summary>
<remarks>
<see cref="T:Newtonsoft.Json.TypeNameHandling"/> should be used with caution when your application deserializes JSON from an external source.
Incoming types should be validated with a custom <see cref="T:System.Runtime.Serialization.SerializationBinder"/>
when deserializing with a value other than <c>TypeNameHandling.None</c>.
</remarks>
</member>
<member name="F:Newtonsoft.Json.TypeNameHandling.None">
<summary>

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -821,6 +821,12 @@
The connection timeout.
</value>
</member>
<member name="P:SteamKit2.Internal.CMClient.DebugNetworkListener">
<summary>
Gets or sets the network listening interface. Use this for debugging only.
For your convenience, you can use <see cref="T:SteamKit2.NetHookNetworkListener"/> class.
</summary>
</member>
<member name="M:SteamKit2.Internal.CMClient.#ctor(System.Net.Sockets.ProtocolType)">
<summary>
Initializes a new instance of the <see cref="T:SteamKit2.Internal.CMClient"/> class with a specific connection type.
@@ -1492,14 +1498,14 @@
Smart list of CM servers.
</summary>
</member>
<member name="P:SteamKit2.SmartCMServerList.ScoreExpiryTimeSpan">
<member name="P:SteamKit2.SmartCMServerList.BadConnectionMemoryTimeSpan">
<summary>
Determines after how much time a server's score should expire and be reset to it's base value.
Determines how long a server's bad connection state is remembered for.
</summary>
</member>
<member name="M:SteamKit2.SmartCMServerList.ResetOldScores">
<summary>
Resets the scores of all servers which had their scores last updated a <see cref="P:SteamKit2.SmartCMServerList.ScoreExpiryTimeSpan"/> ago.
Resets the scores of all servers which has a last bad connection more than <see cref="P:SteamKit2.SmartCMServerList.BadConnectionMemoryTimeSpan"/> ago.
</summary>
</member>
<member name="M:SteamKit2.SmartCMServerList.TryAdd(System.Net.IPEndPoint)">
@@ -1516,9 +1522,18 @@
<param name="endPoints">The collection of <see cref="T:System.Net.IPEndPoint"/>s to add.</param>
<returns>false if any of the specified servers are already in the list, true otherwise.</returns>
</member>
<member name="M:SteamKit2.SmartCMServerList.ResetAllScores">
<member name="M:SteamKit2.SmartCMServerList.MergeWithList(System.Collections.Generic.IEnumerable{System.Net.IPEndPoint})">
<summary>
Explicitly resets the quality of every stored server.
Merges the list with a new list of servers provided to us by the Steam servers.
This adds the new list of <see cref="T:System.Net.IPEndPoint"/>s to the beginning of the list,
ensuring that any pre-existing servers are moved into their new place in order near
the beginning of the list.
</summary>
<param name="listToMerge">The <see cref="T:System.Net.IPEndPoint"/>s to merge into this <see cref="T:SteamKit2.SmartCMServerList"/>.</param>
</member>
<member name="M:SteamKit2.SmartCMServerList.ResetBadServers">
<summary>
Explicitly resets the known state of all servers.
</summary>
</member>
<member name="M:SteamKit2.SmartCMServerList.Clear">
@@ -1853,6 +1868,7 @@
<summary>
Requests details for a specific item of user generated content from the Steam servers.
Results are returned in a <see cref="T:SteamKit2.SteamCloud.UGCDetailsCallback"/>.
The returned <see cref="T:SteamKit2.AsyncJob`1"/> can also be awaited to retrieve the callback result.
</summary>
<param name="ugcId">The unique user generated content id.</param>
<returns>The Job ID of the request. This can be used to find the appropriate <see cref="T:SteamKit2.SteamCloud.UGCDetailsCallback"/>.</returns>
@@ -1861,6 +1877,7 @@
<summary>
Requests details for a specific file in the user's Cloud storage.
Results are returned in a <see cref="T:SteamKit2.SteamCloud.SingleFileInfoCallback"/>.
The returned <see cref="T:SteamKit2.AsyncJob`1"/> can also be awaited to retrieve the callback result.
</summary>
<param name="appid">The app id of the game.</param>
<param name="filename">The path to the file being requested.</param>
@@ -1870,6 +1887,7 @@
<summary>
Commit a Cloud file at the given path to make its UGC handle publicly visible.
Results are returned in a <see cref="T:SteamKit2.SteamCloud.ShareFileCallback"/>.
The returned <see cref="T:SteamKit2.AsyncJob`1"/> can also be awaited to retrieve the callback result.
</summary>
<param name="appid">The app id of the game.</param>
<param name="filename">The path to the file being requested.</param>
@@ -2009,9 +2027,8 @@
</member>
<member name="M:SteamKit2.SteamGameServer.LogOff">
<summary>
Logs the game server off of the Steam3 network.
This method does not disconnect the client.
Results are returned in a <see cref="T:SteamKit2.SteamUser.LoggedOffCallback"/>.
Informs the Steam servers that this client wishes to log off from the network.
The Steam server will disconnect the client, and a <see cref="T:SteamKit2.SteamClient.DisconnectedCallback"/> will be posted.
</summary>
</member>
<member name="M:SteamKit2.SteamGameServer.SendStatus(SteamKit2.SteamGameServer.StatusDetails)">
@@ -2139,6 +2156,7 @@
<summary>
Requests a list of servers from the Steam game master server.
Results are returned in a <see cref="T:SteamKit2.SteamMasterServer.QueryCallback"/>.
The returned <see cref="T:SteamKit2.AsyncJob`1"/> can also be awaited to retrieve the callback result.
</summary>
<param name="details">The details for the request.</param>
<returns>The Job ID of the request. This can be used to find the appropriate <see cref="T:SteamKit2.SteamMasterServer.QueryCallback"/>.</returns>
@@ -2242,6 +2260,7 @@
<summary>
Adds a screenshot to the user's screenshot library. The screenshot image and thumbnail must already exist on the UFS.
Results are returned in a <see cref="T:SteamKit2.SteamScreenshots.ScreenshotAddedCallback"/>.
The returned <see cref="T:SteamKit2.AsyncJob`1"/> can also be awaited to retrieve the callback result.
</summary>
<param name="details">The details of the screenshot.</param>
<returns>The Job ID of the request. This can be used to find the appropriate <see cref="T:SteamKit2.SteamScreenshots.ScreenshotAddedCallback"/>.</returns>
@@ -2428,6 +2447,7 @@
<summary>
Sends a message.
Results are returned in a <see cref="T:SteamKit2.SteamUnifiedMessages.ServiceMethodResponse"/>.
The returned <see cref="T:SteamKit2.AsyncJob`1"/> can also be awaited to retrieve the callback result.
</summary>
<typeparam name="TResponse">The type of the protobuf object which is the response to the RPC call.</typeparam>
<param name="expr">RPC call expression, e.g. x => x.SomeMethodCall(message);</param>
@@ -2438,6 +2458,7 @@
<summary>
Sends a message.
Results are returned in a <see cref="T:SteamKit2.SteamUnifiedMessages.ServiceMethodResponse"/>.
The returned <see cref="T:SteamKit2.AsyncJob`1"/> can also be awaited to retrieve the callback result.
</summary>
<typeparam name="TRequest">The type of a protobuf object.</typeparam>
<param name="name">Name of the RPC endpoint. Takes the format ServiceName.RpcName</param>
@@ -2656,6 +2677,7 @@
<summary>
Enumerates the list of published files for the current logged in user.
Results are returned in a <see cref="T:SteamKit2.SteamWorkshop.UserPublishedFilesCallback"/>.
The returned <see cref="T:SteamKit2.AsyncJob`1"/> can also be awaited to retrieve the callback result.
</summary>
<param name="details">The specific details of the request.</param>
<returns>The Job ID of the request. This can be used to find the appropriate <see cref="T:SteamKit2.SteamWorkshop.UserPublishedFilesCallback"/>.</returns>
@@ -2664,6 +2686,7 @@
<summary>
Enumerates the list of subscribed files for the current logged in user.
Results are returned in a <see cref="T:SteamKit2.SteamWorkshop.UserSubscribedFilesCallback"/>.
The returned <see cref="T:SteamKit2.AsyncJob`1"/> can also be awaited to retrieve the callback result.
</summary>
<param name="details">The specific details of the request.</param>
<returns>The Job ID of the request. This can be used to find the appropriate <see cref="T:SteamKit2.SteamWorkshop.UserSubscribedFilesCallback"/>.</returns>
@@ -2672,6 +2695,7 @@
<summary>
Enumerates the list of published files for the current logged in user based on user action.
Results are returned in a <see cref="T:SteamKit2.SteamWorkshop.UserActionPublishedFilesCallback"/>.
The returned <see cref="T:SteamKit2.AsyncJob`1"/> can also be awaited to retrieve the callback result.
</summary>
<param name="details">The specific details of the request.</param>
<returns>The Job ID of the request. This can be used to find the appropriate <see cref="T:SteamKit2.SteamWorkshop.UserActionPublishedFilesCallback"/>.</returns>
@@ -2740,6 +2764,7 @@
<summary>
Enumerates the list of all published files on the Steam workshop.
Results are returned in a <see cref="T:SteamKit2.SteamWorkshop.PublishedFilesCallback"/>.
The returned <see cref="T:SteamKit2.AsyncJob`1"/> can also be awaited to retrieve the callback result.
</summary>
<param name="details">The specific details of the request.</param>
<returns>The Job ID of the request. This can be used to find the appropriate <see cref="T:SteamKit2.SteamWorkshop.PublishedFilesCallback"/>.</returns>
@@ -2767,6 +2792,7 @@
<summary>
Asks the Steam back-end for a leaderboard by name for a given appid.
Results are returned in a <see cref="T:SteamKit2.SteamUserStats.FindOrCreateLeaderboardCallback"/>.
The returned <see cref="T:SteamKit2.AsyncJob`1"/> can also be awaited to retrieve the callback result.
</summary>
<param name="appId">The AppID to request a leaderboard for.</param>
<param name="name">Name of the leaderboard to request.</param>
@@ -2776,6 +2802,7 @@
<summary>
Asks the Steam back-end for a leaderboard by name, and will create it if it's not yet.
Results are returned in a <see cref="T:SteamKit2.SteamUserStats.FindOrCreateLeaderboardCallback"/>.
The returned <see cref="T:SteamKit2.AsyncJob`1"/> can also be awaited to retrieve the callback result.
</summary>
<param name="appId">The AppID to request a leaderboard for.</param>
<param name="name">Name of the leaderboard to create.</param>
@@ -2787,6 +2814,7 @@
<summary>
Asks the Steam back-end for a set of rows in the leaderboard.
Results are returned in a <see cref="T:SteamKit2.SteamUserStats.LeaderboardEntriesCallback"/>.
The returned <see cref="T:SteamKit2.AsyncJob`1"/> can also be awaited to retrieve the callback result.
</summary>
<param name="appId">The AppID to request leaderboard rows for.</param>
<param name="id">ID of the leaderboard to view.</param>
@@ -2896,6 +2924,79 @@
Gets the list of leaderboard entries this response contains.
</summary>
</member>
<member name="M:SteamKit2.AsyncJobManager.StartJob(SteamKit2.AsyncJob)">
<summary>
Tracks a job with this manager.
</summary>
<param name="asyncJob">The asynchronous job to track.</param>
</member>
<member name="M:SteamKit2.AsyncJobManager.TryCompleteJob(SteamKit2.JobID,SteamKit2.CallbackMsg)">
<summary>
Passes a callback to a pending async job.
If the given callback completes the job, the job is removed from this manager.
</summary>
<param name="jobId">The JobID.</param>
<param name="callback">The callback.</param>
</member>
<member name="M:SteamKit2.AsyncJobManager.HeartbeatJob(SteamKit2.JobID)">
<summary>
Extends the lifetime of a job.
</summary>
<param name="jobId">The job identifier.</param>
</member>
<member name="M:SteamKit2.AsyncJobManager.FailJob(SteamKit2.JobID)">
<summary>
Marks a certain job as remotely failed.
</summary>
<param name="jobId">The job identifier.</param>
</member>
<member name="M:SteamKit2.AsyncJobManager.CancelPendingJobs">
<summary>
Cancels and clears all jobs being tracked.
</summary>
</member>
<member name="M:SteamKit2.AsyncJobManager.SetTimeoutsEnabled(System.Boolean)">
<summary>
Enables or disables periodic checks for job timeouts.
</summary>
<param name="enable">Whether or not job timeout checks should be enabled.</param>
</member>
<member name="M:SteamKit2.AsyncJobManager.CancelTimedoutJobs">
<summary>
This is called periodically to cancel and clear out any jobs that have timed out (no response from Steam).
</summary>
</member>
<member name="M:SteamKit2.AsyncJobManager.GetJob(SteamKit2.JobID,System.Boolean)">
<summary>
Retrieves a job from this manager, and optionally removes it from tracking.
</summary>
<param name="jobId">The JobID.</param>
<param name="andRemove">If set to <c>true</c>, this job is removed from tracking.</param>
<returns></returns>
</member>
<member name="T:SteamKit2.AsyncJobFailedException">
<summary>
Thrown when Steam encounters a remote error with a pending <see cref="T:SteamKit2.AsyncJob"/>.
</summary>
</member>
<member name="M:SteamKit2.AsyncJobFailedException.#ctor">
<summary>
Initializes a new instance of the <see cref="T:SteamKit2.AsyncJobFailedException"/> class.
</summary>
</member>
<member name="M:SteamKit2.AsyncJobFailedException.#ctor(System.String)">
<summary>
Initializes a new instance of the <see cref="T:SteamKit2.AsyncJobFailedException"/> class.
</summary>
<param name="message">The message that describes the error.</param>
</member>
<member name="M:SteamKit2.AsyncJobFailedException.#ctor(System.String,System.Exception)">
<summary>
Initializes a new instance of the <see cref="T:SteamKit2.AsyncJobFailedException"/> class.
</summary>
<param name="message">The error message that explains the reason for the exception.</param>
<param name="innerException">The exception that is the cause of the current exception, or a null reference (Nothing in Visual Basic) if no inner exception is specified.</param>
</member>
<member name="T:SteamKit2.Callback`1">
<summary>
This utility class is used for binding a callback to a function.
@@ -3229,19 +3330,20 @@
Helper class to load servers from the Steam Directory Web API.
</summary>
</member>
<member name="M:SteamKit2.SteamDirectory.Initialize(System.Int32)">
<member name="M:SteamKit2.SteamDirectory.Initialize(System.UInt32)">
<summary>
Initializes <see cref="T:SteamKit2.Internal.CMClient"/>'s server list with servers from the Steam Directory.
</summary>
<param name="cellid">Cell ID</param>
</member>
<member name="M:SteamKit2.SteamDirectory.LoadAsync(System.Int32)">
<member name="M:SteamKit2.SteamDirectory.LoadAsync(System.UInt32)">
<summary>
Load a list of servers from the Steam Directory.
</summary>
<param name="cellid">Cell ID</param>
<returns>A <see cref="T:System.Threading.Tasks.Task"/> with the Result set to an enumerable list of <see cref="T:System.Net.IPEndPoint"/>s.</returns>
</member>
<member name="M:SteamKit2.SteamDirectory.LoadAsync(System.Int32,System.Threading.CancellationToken)">
<member name="M:SteamKit2.SteamDirectory.LoadAsync(System.UInt32,System.Threading.CancellationToken)">
<summary>
Load a list of servers from the Steam Directory.
</summary>
@@ -3536,45 +3638,6 @@
A <see cref="T:System.String"/> that represents this instance.
</returns>
</member>
<member name="T:SteamKit2.JobID">
<summary>
Represents an identifier of a network task known as a job.
</summary>
</member>
<member name="F:SteamKit2.JobID.Invalid">
<summary>
Represents an invalid JobID.
</summary>
</member>
<member name="M:SteamKit2.JobID.#ctor">
<summary>
Initializes a new instance of the <see cref="T:SteamKit2.JobID"/> class.
</summary>
</member>
<member name="M:SteamKit2.JobID.#ctor(System.UInt64)">
<summary>
Initializes a new instance of the <see cref="T:SteamKit2.JobID"/> class.
</summary>
<param name="jobId">The Job ID to initialize this instance with.</param>
</member>
<member name="M:SteamKit2.JobID.op_Implicit(SteamKit2.JobID)~System.UInt64">
<summary>
Performs an implicit conversion from <see cref="T:SteamKit2.JobID"/> to <see cref="T:System.UInt64"/>.
</summary>
<param name="jobId">The Job ID.</param>
<returns>
The result of the conversion.
</returns>
</member>
<member name="M:SteamKit2.JobID.op_Implicit(System.UInt64)~SteamKit2.JobID">
<summary>
Performs an implicit conversion from <see cref="T:System.UInt64"/> to <see cref="T:SteamKit2.JobID"/>.
</summary>
<param name="jobId">The Job ID.</param>
<returns>
The result of the conversion.
</returns>
</member>
<member name="T:SteamKit2.UGCHandle">
<summary>
Represents a single unique handle to a piece of User Generated Content.
@@ -3699,6 +3762,195 @@
<param name="encryptionKey">The encryption key.</param>
<returns><c>true</c> if the file names were successfully decrypted; otherwise, <c>false</c>.</returns>
</member>
<member name="T:SteamKit2.JobID">
<summary>
Represents an identifier of a network task known as a job.
</summary>
</member>
<member name="F:SteamKit2.JobID.Invalid">
<summary>
Represents an invalid JobID.
</summary>
</member>
<member name="M:SteamKit2.JobID.#ctor">
<summary>
Initializes a new instance of the <see cref="T:SteamKit2.JobID"/> class.
</summary>
</member>
<member name="M:SteamKit2.JobID.#ctor(System.UInt64)">
<summary>
Initializes a new instance of the <see cref="T:SteamKit2.JobID"/> class.
</summary>
<param name="jobId">The Job ID to initialize this instance with.</param>
</member>
<member name="M:SteamKit2.JobID.op_Implicit(SteamKit2.JobID)~System.UInt64">
<summary>
Performs an implicit conversion from <see cref="T:SteamKit2.JobID"/> to <see cref="T:System.UInt64"/>.
</summary>
<param name="jobId">The Job ID.</param>
<returns>
The result of the conversion.
</returns>
</member>
<member name="M:SteamKit2.JobID.op_Implicit(System.UInt64)~SteamKit2.JobID">
<summary>
Performs an implicit conversion from <see cref="T:System.UInt64"/> to <see cref="T:SteamKit2.JobID"/>.
</summary>
<param name="jobId">The Job ID.</param>
<returns>
The result of the conversion.
</returns>
</member>
<member name="M:SteamKit2.JobID.op_Implicit(SteamKit2.AsyncJob)~SteamKit2.JobID">
<summary>
Performs an implicit conversion from <see cref="T:SteamKit2.AsyncJob"/> to <see cref="T:SteamKit2.JobID"/>.
</summary>
<param name="asyncJob">The asynchronous job.</param>
<returns>
The result of the conversion.
</returns>
</member>
<member name="T:SteamKit2.AsyncJob">
<summary>
The base class for awaitable versions of a <see cref="P:SteamKit2.AsyncJob.JobID"/>.
Should not be used or constructed directly, but rather with <see cref="T:SteamKit2.AsyncJob`1"/>.
</summary>
</member>
<member name="P:SteamKit2.AsyncJob.JobID">
<summary>
Gets the <see cref="P:SteamKit2.AsyncJob.JobID"/> for this job.
</summary>
</member>
<member name="P:SteamKit2.AsyncJob.Timeout">
<summary>
Gets or sets the period of time before this job will be considered timed out and will be canceled. By default this is 10 seconds.
</summary>
</member>
<member name="M:SteamKit2.AsyncJob.AddResult(SteamKit2.CallbackMsg)">
<summary>
Adds a callback to the async job's result set.
</summary>
<param name="callback">The callback.</param>
<returns><c>true</c> if this result completes the set; otherwise, <c>false</c>.</returns>
</member>
<member name="M:SteamKit2.AsyncJob.SetFailed(System.Boolean)">
<summary>
Sets this job as failed, either remotely or due to a message timeout.
</summary>
<param name="dueToRemoteFailure">
If set to <c>true</c> this job is marked as failed because Steam informed us of a job failure;
otherwise, this job has failed due to a message timeout.
</param>
</member>
<member name="M:SteamKit2.AsyncJob.Heartbeat">
<summary>
Marks this job as having received a heartbeat and extends the job's timeout.
</summary>
</member>
<member name="T:SteamKit2.AsyncJob`1">
<summary>
Represents an awaitable version of a <see cref="T:SteamKit2.JobID"/>.
Can either be converted to a TPL <see cref="T:System.Threading.Tasks.Task"/> with <see cref="M:SteamKit2.AsyncJob`1.ToTask"/> or can be awaited directly.
</summary>
<typeparam name="T">The callback type that will be returned by this async job.</typeparam>
</member>
<member name="M:SteamKit2.AsyncJob`1.#ctor(SteamKit2.SteamClient,SteamKit2.JobID)">
<summary>
Initializes a new instance of the <see cref="T:SteamKit2.AsyncJob`1" /> class.
</summary>
<param name="client">The <see cref="T:SteamKit2.SteamClient"/> that this job will be associated with.</param>
<param name="jobId">The Job ID value associated with this async job.</param>
</member>
<member name="M:SteamKit2.AsyncJob`1.ToTask">
<summary>
Converts this <see cref="T:SteamKit2.AsyncJob`1"/> instance into a TPL <see cref="T:System.Threading.Tasks.Task`1"/>.
</summary>
<returns></returns>
</member>
<member name="M:SteamKit2.AsyncJob`1.GetAwaiter">
<summary>Gets an awaiter used to await this <see cref="T:SteamKit2.AsyncJob`1"/>.</summary>
<returns>An awaiter instance.</returns>
<remarks>This method is intended for compiler use rather than use directly in code.</remarks>
</member>
<member name="M:SteamKit2.AsyncJob`1.AddResult(SteamKit2.CallbackMsg)">
<summary>
Adds a callback to the async job's result set. For an <see cref="T:SteamKit2.AsyncJob`1"/>, this always completes the set.
</summary>
<param name="callback">The callback.</param>
<returns>Always <c>true</c>.</returns>
</member>
<member name="M:SteamKit2.AsyncJob`1.SetFailed(System.Boolean)">
<summary>
Sets this job as failed, either remotely or due to a message timeout.
</summary>
<param name="dueToRemoteFailure">
If set to <c>true</c> this job is marked as failed because Steam informed us of a job failure;
otherwise, this job has failed due to a message timeout.
</param>
</member>
<member name="T:SteamKit2.AsyncJobMultiple`1">
<summary>
Represents an awaitable version of a <see cref="T:SteamKit2.JobID"/>.
Can either be converted to a TPL <see cref="T:System.Threading.Tasks.Task"/> with <see cref="M:SteamKit2.AsyncJobMultiple`1.ToTask"/> or can be awaited directly.
This type of async job can contain multiple callback results.
</summary>
<typeparam name="T">The callback type that will be returned by this async job.</typeparam>
</member>
<member name="T:SteamKit2.AsyncJobMultiple`1.ResultSet">
<summary>
The set of callback results for an <see cref="T:SteamKit2.AsyncJobMultiple`1"/>.
</summary>
</member>
<member name="P:SteamKit2.AsyncJobMultiple`1.ResultSet.Complete">
<summary>
Gets a value indicating whether this <see cref="T:SteamKit2.AsyncJobMultiple`1.ResultSet" /> is complete and contains every result sent by Steam.
</summary>
</member>
<member name="P:SteamKit2.AsyncJobMultiple`1.ResultSet.Failed">
<summary>
Gets a value indicating whether the parent <see cref="T:SteamKit2.AsyncJobMultiple`1" /> received an incomplete result set and then encountered a remote failure.
</summary>
</member>
<member name="P:SteamKit2.AsyncJobMultiple`1.ResultSet.Results">
<summary>
Gets a read only collection of callback results for this async job.
</summary>
</member>
<member name="M:SteamKit2.AsyncJobMultiple`1.#ctor(SteamKit2.SteamClient,SteamKit2.JobID,System.Predicate{`0})">
<summary>
Initializes a new instance of the <see cref="T:SteamKit2.AsyncJob`1" /> class.
</summary>
<param name="client">The <see cref="T:SteamKit2.SteamClient"/> that this job will be associated with.</param>
<param name="jobId">The Job ID value associated with this async job.</param>
<param name="finishCondition">The condition that must be fulfilled for the result set to be considered complete.</param>
</member>
<member name="M:SteamKit2.AsyncJobMultiple`1.ToTask">
<summary>
Converts this <see cref="T:SteamKit2.AsyncJob`1"/> instance into a TPL <see cref="T:System.Threading.Tasks.Task`1"/>.
</summary>
<returns></returns>
</member>
<member name="M:SteamKit2.AsyncJobMultiple`1.GetAwaiter">
<summary>Gets an awaiter used to await this <see cref="T:SteamKit2.AsyncJob`1"/>.</summary>
<returns>An awaiter instance.</returns>
<remarks>This method is intended for compiler use rather than use directly in code.</remarks>
</member>
<member name="M:SteamKit2.AsyncJobMultiple`1.AddResult(SteamKit2.CallbackMsg)">
<summary>
Adds a callback to the async job's result set.
</summary>
<param name="callback">The callback.</param>
<returns><c>true</c> if this result completes the set; otherwise, <c>false</c>.</returns>
</member>
<member name="M:SteamKit2.AsyncJobMultiple`1.SetFailed(System.Boolean)">
<summary>
Sets this job as failed, either remotely or due to a message timeout.
</summary>
<param name="dueToRemoteFailure">
If set to <c>true</c> this job is marked as failed because Steam informed us of a job failure;
otherwise, this job has failed due to a message timeout.
</param>
</member>
<member name="T:SteamKit2.MessageObject">
<summary>
Represents a <see cref="T:SteamKit2.KeyValue"/> backed MessageObject structure, which are often sent by the Steam servers.
@@ -3840,6 +4092,60 @@
The result of the operator.
</returns>
</member>
<member name="T:SteamKit2.IDebugNetworkListener">
<summary>
This is a debug utility, do not use it to implement your business logic.
This interface is used for logging network messages sent to and received from the Steam server that the client is connected to.
</summary>
</member>
<member name="M:SteamKit2.IDebugNetworkListener.OnIncomingNetworkMessage(SteamKit2.EMsg,System.Byte[])">
<summary>
Called when a packet is received from the Steam server.
</summary>
<param name="msgType">Network message type of this packet message.</param>
<param name="data">Raw packet data that was received.</param>
</member>
<member name="M:SteamKit2.IDebugNetworkListener.OnOutgoingNetworkMessage(SteamKit2.EMsg,System.Byte[])">
<summary>
Called when a packet is about to be sent to the Steam server.
</summary>
<param name="msgType">Network message type of this packet message.</param>
<param name="data">Raw packet data that will be sent.</param>
</member>
<member name="T:SteamKit2.NetHookNetworkListener">
<summary>
Dump any network messages sent to and received from the Steam server that the client is connected to.
These messages are dumped to file, and can be analyzed further with NetHookAnalyzer, a hex editor, or your own purpose-built tools.
Be careful with this, sensitive data may be written to the disk (such as your Steam password).
</summary>
</member>
<member name="M:SteamKit2.NetHookNetworkListener.#ctor">
<summary>
Will create a folder in path "%assembly%/nethook/%currenttime%/"
</summary>
</member>
<member name="M:SteamKit2.NetHookNetworkListener.#ctor(System.String)">
<summary>
Log to your own folder.
</summary>
<param name="path">Path to folder.</param>
</member>
<member name="M:SteamKit2.NetHookNetworkListener.OnIncomingNetworkMessage(SteamKit2.EMsg,System.Byte[])">
<summary>
Called when a packet is received from the Steam server.
</summary>
<param name="msgType">Network message type of this packet message.</param>
<param name="data">Raw packet data that was received.</param>
</member>
<member name="M:SteamKit2.NetHookNetworkListener.OnOutgoingNetworkMessage(SteamKit2.EMsg,System.Byte[])">
<summary>
Called when a packet is about to be sent to the Steam server.
</summary>
<param name="msgType">Network message type of this packet message.</param>
<param name="data">Raw packet data that will be sent.</param>
</member>
<member name="P:SteamKit2.UdpPacket.IsValid">
<summary>
Gets a value indicating whether this instance is valid.
@@ -4356,7 +4662,7 @@
</member>
<member name="P:SteamKit2.SteamApps.PICSProductInfoCallback.ResponsePending">
<summary>
Gets if the are more product information responses pending
Gets if there are more product information responses pending
</summary>
</member>
<member name="P:SteamKit2.SteamApps.PICSProductInfoCallback.UnknownPackages">
@@ -4507,6 +4813,7 @@
<summary>
Requests an app ownership ticket for the specified AppID.
Results are returned in a <see cref="T:SteamKit2.SteamApps.AppOwnershipTicketCallback"/> callback.
The returned <see cref="T:SteamKit2.AsyncJob`1"/> can also be awaited to retrieve the callback result.
</summary>
<param name="appid">The appid to request the ownership ticket of.</param>
<returns>The Job ID of the request. This can be used to find the appropriate <see cref="T:SteamKit2.SteamApps.AppOwnershipTicketCallback"/>.</returns>
@@ -4515,6 +4822,7 @@
<summary>
Requests app information for a single app. Use the overload for requesting information on a batch of apps.
Results are returned in a <see cref="T:SteamKit2.SteamApps.AppInfoCallback"/> callback.
The returned <see cref="T:SteamKit2.AsyncJob`1"/> can also be awaited to retrieve the callback result.
Consider using <see cref="o:SteamApps.PICSGetProductInfo"/> instead.
</summary>
@@ -4526,6 +4834,7 @@
<summary>
Requests app information for a single app. Use the overload for requesting information on a batch of apps.
Results are returned in a <see cref="T:SteamKit2.SteamApps.AppInfoCallback"/> callback.
The returned <see cref="T:SteamKit2.AsyncJob`1"/> can also be awaited to retrieve the callback result.
Consider using <see cref="o:SteamApps.PICSGetProductInfo"/> instead.
</summary>
@@ -4537,6 +4846,7 @@
<summary>
Requests app information for a list of apps.
Results are returned in a <see cref="T:SteamKit2.SteamApps.AppInfoCallback"/> callback.
The returned <see cref="T:SteamKit2.AsyncJob`1"/> can also be awaited to retrieve the callback result.
Consider using <see cref="o:SteamApps.PICSGetProductInfo"/> instead.
</summary>
@@ -4548,6 +4858,7 @@
<summary>
Requests app information for a list of apps.
Results are returned in a <see cref="T:SteamKit2.SteamApps.AppInfoCallback"/> callback.
The returned <see cref="T:SteamKit2.AsyncJob`1"/> can also be awaited to retrieve the callback result.
Consider using <see cref="o:SteamApps.PICSGetProductInfo"/> instead.
</summary>
@@ -4559,6 +4870,7 @@
<summary>
Requests package information for a single package. Use the overload for requesting information on a batch of packages.
Results are returned in a <see cref="T:SteamKit2.SteamApps.PackageInfoCallback"/> callback.
The returned <see cref="T:SteamKit2.AsyncJob`1"/> can also be awaited to retrieve the callback result.
Consider using <see cref="o:SteamApps.PICSGetProductInfo"/> instead.
</summary>
@@ -4570,6 +4882,7 @@
<summary>
Requests package information for a list of packages.
Results are returned in a <see cref="T:SteamKit2.SteamApps.PackageInfoCallback"/> callback.
The returned <see cref="T:SteamKit2.AsyncJob`1"/> can also be awaited to retrieve the callback result.
Consider using <see cref="o:SteamApps.PICSGetProductInfo"/> instead.
</summary>
@@ -4591,15 +4904,27 @@
<summary>
Request the depot decryption key for a specified DepotID.
Results are returned in a <see cref="T:SteamKit2.SteamApps.DepotKeyCallback"/> callback.
The returned <see cref="T:SteamKit2.AsyncJob`1"/> can also be awaited to retrieve the callback result.
</summary>
<param name="depotid">The DepotID to request a decryption key for.</param>
<param name="appid">The AppID to request the decryption key for.</param>
<returns>The Job ID of the request. This can be used to find the appropriate <see cref="T:SteamKit2.SteamApps.DepotKeyCallback"/>.</returns>
</member>
<member name="M:SteamKit2.SteamApps.PICSGetAccessTokens(System.Nullable{System.UInt32},System.Nullable{System.UInt32})">
<summary>
Request PICS access tokens for an app or package.
Results are returned in a <see cref="T:SteamKit2.SteamApps.PICSTokensCallback"/> callback.
The returned <see cref="T:SteamKit2.AsyncJob`1"/> can also be awaited to retrieve the callback result.
</summary>
<param name="app">App id to request access token for.</param>
<param name="package">Package id to request access token for.</param>
<returns>The Job ID of the request. This can be used to find the appropriate <see cref="T:SteamKit2.SteamApps.PICSTokensCallback"/>.</returns>
</member>
<member name="M:SteamKit2.SteamApps.PICSGetAccessTokens(System.Collections.Generic.IEnumerable{System.UInt32},System.Collections.Generic.IEnumerable{System.UInt32})">
<summary>
Request PICS access tokens for a list of app ids and package ids
Results are returned in a <see cref="T:SteamKit2.SteamApps.PICSTokensCallback"/> callback.
The returned <see cref="T:SteamKit2.AsyncJob`1"/> can also be awaited to retrieve the callback result.
</summary>
<param name="appIds">List of app ids to request access tokens for.</param>
<param name="packageIds">List of package ids to request access tokens for.</param>
@@ -4609,6 +4934,7 @@
<summary>
Request changes for apps and packages since a given change number
Results are returned in a <see cref="T:SteamKit2.SteamApps.PICSChangesCallback"/> callback.
The returned <see cref="T:SteamKit2.AsyncJob`1"/> can also be awaited to retrieve the callback result.
</summary>
<param name="lastChangeNumber">Last change number seen.</param>
<param name="sendAppChangelist">Whether to send app changes.</param>
@@ -4619,6 +4945,7 @@
<summary>
Request product information for an app or package
Results are returned in a <see cref="T:SteamKit2.SteamApps.PICSProductInfoCallback"/> callback.
The returned <see cref="T:SteamKit2.AsyncJob`1"/> can also be awaited to retrieve the callback result.
</summary>
<param name="app">App id requested.</param>
<param name="package">Package id requested.</param>
@@ -4630,6 +4957,7 @@
<summary>
Request product information for a list of apps or packages
Results are returned in a <see cref="T:SteamKit2.SteamApps.PICSProductInfoCallback"/> callback.
The returned <see cref="T:SteamKit2.AsyncJob`1"/> can also be awaited to retrieve the callback result.
</summary>
<param name="apps">List of app ids requested.</param>
<param name="packages">List of package ids requested.</param>
@@ -4641,6 +4969,7 @@
<summary>
Request product information for a list of apps or packages
Results are returned in a <see cref="T:SteamKit2.SteamApps.PICSProductInfoCallback"/> callback.
The returned <see cref="T:SteamKit2.AsyncJob`1"/> can also be awaited to retrieve the callback result.
</summary>
<param name="apps">List of <see cref="T:SteamKit2.SteamApps.PICSRequest"/> requests for apps.</param>
<param name="packages">List of <see cref="T:SteamKit2.SteamApps.PICSRequest"/> requests for packages.</param>
@@ -4651,6 +4980,7 @@
<summary>
Request product information for an app or package
Results are returned in a <see cref="T:SteamKit2.SteamApps.CDNAuthTokenCallback"/> callback.
The returned <see cref="T:SteamKit2.AsyncJob`1"/> can also be awaited to retrieve the callback result.
</summary>
<param name="app">App id requested.</param>
<param name="host_name">CDN host name being requested.</param>
@@ -4660,6 +4990,7 @@
<summary>
Request a free license for given appid, can be used for free on demand apps
Results are returned in a <see cref="T:SteamKit2.SteamApps.FreeLicenseCallback"/> callback.
The returned <see cref="T:SteamKit2.AsyncJob`1"/> can also be awaited to retrieve the callback result.
</summary>
<param name="app">The app to request a free license for.</param>
<returns>The Job ID of the request. This can be used to find the appropriate <see cref="T:SteamKit2.SteamApps.FreeLicenseCallback"/>.</returns>
@@ -4668,6 +4999,7 @@
<summary>
Request a free license for given appids, can be used for free on demand apps
Results are returned in a <see cref="T:SteamKit2.SteamApps.FreeLicenseCallback"/> callback.
The returned <see cref="T:SteamKit2.AsyncJob`1"/> can also be awaited to retrieve the callback result.
</summary>
<param name="apps">The apps to request a free license for.</param>
<returns>The Job ID of the request. This can be used to find the appropriate <see cref="T:SteamKit2.SteamApps.FreeLicenseCallback"/>.</returns>
@@ -5027,6 +5359,54 @@
</summary>
<value>The message.</value>
</member>
<member name="T:SteamKit2.SteamFriends.FriendMsgHistoryCallback">
<summary>
<para>This callback is fired in response to receiving historical messages.</para>
See also <seealso cref="M:SteamKit2.SteamFriends.RequestOfflineMessages"/> and
<seealso cref="M:SteamKit2.SteamFriends.RequestMessageHistory(SteamKit2.SteamID)"/>.
</summary>
</member>
<member name="P:SteamKit2.SteamFriends.FriendMsgHistoryCallback.Result">
<summary>
Gets the result of the request.
</summary>
</member>
<member name="P:SteamKit2.SteamFriends.FriendMsgHistoryCallback.SteamID">
<summary>
Gets the SteamID of the user with whom these messages were exchanged.
</summary>
</member>
<member name="P:SteamKit2.SteamFriends.FriendMsgHistoryCallback.Messages">
<summary>
The messages exchanged with the user.
Offline messages are marked by having set <see cref="P:SteamKit2.SteamFriends.FriendMsgHistoryCallback.FriendMessage.Unread"/> to <c>true</c>
</summary>
</member>
<member name="T:SteamKit2.SteamFriends.FriendMsgHistoryCallback.FriendMessage">
<summary>
Represents a single Message sent to or received from a friend
</summary>
</member>
<member name="P:SteamKit2.SteamFriends.FriendMsgHistoryCallback.FriendMessage.SteamID">
<summary>
The SteamID of the User that wrote the message
</summary>
</member>
<member name="P:SteamKit2.SteamFriends.FriendMsgHistoryCallback.FriendMessage.Unread">
<summary>
Whether or not the message has been read, i.e., is an offline message.
</summary>
</member>
<member name="P:SteamKit2.SteamFriends.FriendMsgHistoryCallback.FriendMessage.Message">
<summary>
The actual message
</summary>
</member>
<member name="P:SteamKit2.SteamFriends.FriendMsgHistoryCallback.FriendMessage.Timestamp">
<summary>
The time (in UTC) when the message was sent
</summary>
</member>
<member name="T:SteamKit2.SteamFriends.FriendAddedCallback">
<summary>
This callback is fired in response to adding a user to your friends list.
@@ -5345,6 +5725,7 @@
<summary>
Sets the local user's persona name and broadcasts it over the network.
Results are returned in a <see cref="T:SteamKit2.SteamFriends.PersonaChangeCallback"/> callback.
The returned <see cref="T:SteamKit2.AsyncJob`1"/> can also be awaited to retrieve the callback result.
</summary>
<param name="name">The name.</param>
<returns>The Job ID of the request. This can be used to find the appropriate <see cref="T:SteamKit2.SteamFriends.PersonaChangeCallback"/>.</returns>
@@ -5359,6 +5740,7 @@
<summary>
Sets the local user's persona state and broadcasts it over the network.
Results are returned in a <see cref="T:SteamKit2.SteamFriends.PersonaChangeCallback"/> callback.
The returned <see cref="T:SteamKit2.AsyncJob`1"/> can also be awaited to retrieve the callback result.
</summary>
<param name="state">The state.</param>
<returns>The Job ID of the request. This can be used to find the appropriate <see cref="T:SteamKit2.SteamFriends.PersonaChangeCallback"/>.</returns>
@@ -5547,6 +5929,7 @@
<summary>
Ignores or unignores a friend on Steam.
Results are returned in a <see cref="T:SteamKit2.SteamFriends.IgnoreFriendCallback"/>.
The returned <see cref="T:SteamKit2.AsyncJob`1"/> can also be awaited to retrieve the callback result.
</summary>
<param name="steamId">The SteamID of the friend to ignore or unignore.</param>
<param name="setIgnore">if set to <c>true</c>, the friend will be ignored; otherwise, they will be unignored.</param>
@@ -5556,10 +5939,25 @@
<summary>
Requests profile information for the given <see cref="T:SteamKit2.SteamID"/>.
Results are returned in a <see cref="T:SteamKit2.SteamFriends.ProfileInfoCallback"/>.
The returned <see cref="T:SteamKit2.AsyncJob`1"/> can also be awaited to retrieve the callback result.
</summary>
<param name="steamId">The SteamID of the friend to request the details of.</param>
<returns>The Job ID of the request. This can be used to find the appropriate <see cref="T:SteamKit2.SteamFriends.ProfileInfoCallback"/>.</returns>
</member>
<member name="M:SteamKit2.SteamFriends.RequestMessageHistory(SteamKit2.SteamID)">
<summary>
Requests the last few chat messages with a friend.
Results are returned in a <see cref="T:SteamKit2.SteamFriends.FriendMsgHistoryCallback"/>
</summary>
<param name="steamId">SteamID of the friend</param>
</member>
<member name="M:SteamKit2.SteamFriends.RequestOfflineMessages">
<summary>
Requests all offline messages.
This also marks them as read server side.
Results are returned in a <see cref="T:SteamKit2.SteamFriends.FriendMsgHistoryCallback"/>.
</summary>
</member>
<member name="M:SteamKit2.SteamFriends.HandleMsg(SteamKit2.IPacketMsg)">
<summary>
Handles a client message. This should not be called directly.
@@ -5920,6 +6318,18 @@
</summary>
<value>The CellID.</value>
</member>
<member name="P:SteamKit2.SteamUser.LogOnDetails.LoginID">
<summary>
Gets or sets the LoginID. This number is used for identifying logon session.
The purpose of this field is to allow multiple sessions to the same steam account from the same machine.
This is because Steam Network doesn't allow more than one session with the same LoginID to access given account at the same time.
If you want to establish more than one active session to given account, you must make sure that every session (to that account) has unique LoginID.
By default LoginID is automatically generated based on machine's primary bind address, which is the same for all sessions.
Null value will cause this property to be automatically generated based on default behaviour.
If in doubt, set this property to null.
</summary>
<value>The LoginID.</value>
</member>
<member name="P:SteamKit2.SteamUser.LogOnDetails.AuthCode">
<summary>
Gets or sets the Steam Guard auth code used to login. This is the code sent to the user's email.
@@ -6139,9 +6549,8 @@
</member>
<member name="M:SteamKit2.SteamUser.LogOff">
<summary>
Logs the user off of the Steam3 network.
This method does not disconnect the client.
Results are returned in a <see cref="T:SteamKit2.SteamUser.LoggedOffCallback"/>.
Informs the Steam servers that this client wishes to log off from the network.
The Steam server will disconnect the client, and a <see cref="T:SteamKit2.SteamClient.DisconnectedCallback"/> will be posted.
</summary>
</member>
<member name="M:SteamKit2.SteamUser.SendMachineAuthResponse(SteamKit2.SteamUser.MachineAuthDetails)">
@@ -6155,6 +6564,7 @@
<summary>
Requests a new WebAPI authentication user nonce.
Results are returned in a <see cref="T:SteamKit2.SteamUser.WebAPIUserNonceCallback"/>.
The returned <see cref="T:SteamKit2.AsyncJob`1"/> can also be awaited to retrieve the callback result.
</summary>
<returns>The Job ID of the request. This can be used to find the appropriate <see cref="T:SteamKit2.SteamUser.WebAPIUserNonceCallback"/>.</returns>
</member>
@@ -6181,37 +6591,6 @@
then this will be <see cref="P:JobID.Invalid"/>
</summary>
</member>
<member name="T:SteamKit2.CallbackMsgExtensions">
<summary>
Useful extensions for ICallbackMsg
</summary>
</member>
<member name="M:SteamKit2.CallbackMsgExtensions.IsType``1(SteamKit2.ICallbackMsg)">
<summary>
Determines whether this callback is a certain type.
</summary>
<typeparam name="T">The type to check against.</typeparam>
<returns>
<c>true</c> if this callback is the type specified; otherwise, <c>false</c>.
</returns>
<exception cref="T:System.ArgumentNullException">
<c>msg</c> is null.
</exception>
</member>
<member name="M:SteamKit2.CallbackMsgExtensions.Handle``1(SteamKit2.ICallbackMsg,System.Action{``0})">
<summary>
Invokes the specified handler delegate if the callback matches the type parameter.
</summary>
<typeparam name="T">The type to check against.</typeparam>
<param name="msg">The callback in question.</param>
<param name="handler">The handler to invoke.</param>
<returns>
<c>true</c> if the callback matches and the handler was called; otherwise, <c>false</c>.
</returns>
<exception cref="T:System.ArgumentNullException">
<c>msg</c> is null or <c>handler</c> is null.
</exception>
</member>
<member name="T:SteamKit2.CallbackMsg">
<summary>
Represents the base object all callbacks are based off.
@@ -6394,6 +6773,13 @@
Gets the underlying <see cref="T:SteamKit2.SteamClient"/> for use in sending replies.
</summary>
</member>
<member name="P:SteamKit2.ClientMsgHandler.ExpectDisconnection">
<summary>
Gets or sets whether or not the related <see cref="T:SteamKit2.SteamClient" /> should imminently expect the server to close the connection.
If this is true when the connection is closed, the <see cref="T:SteamKit2.SteamClient.DisconnectedCallback"/>'s <see cref="P:SteamKit2.SteamClient.DisconnectedCallback.UserInitiated"/> property
will be set to <c>true</c>.
</summary>
</member>
<member name="M:SteamKit2.ClientMsgHandler.#ctor">
<summary>
Initializes a new instance of the <see cref="T:SteamKit2.ClientMsgHandler"/> class.
@@ -7104,11 +7490,11 @@
</summary>
<param name="packet">The packet.</param>
</member>
<member name="M:SteamKit2.UdpConnection.SetNetEncryptionFilter(SteamKit2.NetFilterEncryption)">
<member name="M:SteamKit2.UdpConnection.SetNetEncryptionFilter(SteamKit2.INetFilterEncryption)">
<summary>
Sets the network encryption filter for this connection
</summary>
<param name="filter">filter implementing <see cref="T:SteamKit2.NetFilterEncryption"/></param>
<param name="filter">filter implementing <see cref="T:SteamKit2.INetFilterEncryption"/></param>
</member>
<member name="T:SteamKit2.NetMsgEventArgs">
<summary>
@@ -7166,11 +7552,11 @@
</summary>
<returns>The local IP.</returns>
</member>
<member name="M:SteamKit2.Connection.SetNetEncryptionFilter(SteamKit2.NetFilterEncryption)">
<member name="M:SteamKit2.Connection.SetNetEncryptionFilter(SteamKit2.INetFilterEncryption)">
<summary>
Sets the network encryption filter for this connection
</summary>
<param name="filter">filter implementing <see cref="T:SteamKit2.NetFilterEncryption"/></param>
<param name="filter">filter implementing <see cref="T:SteamKit2.INetFilterEncryption"/></param>
</member>
<member name="T:SteamKit2.KeyDictionary">
<summary>
@@ -7229,16 +7615,36 @@
Decrypts an input byte array using AES/CBC/PKCS7 with a given key and IV
</summary>
</member>
<member name="M:SteamKit2.CryptoHelper.SymmetricEncryptWithIV(System.Byte[],System.Byte[],System.Byte[])">
<summary>
Performs an encryption using AES/CBC/PKCS7 with an input byte array and key, with a random IV prepended using AES/ECB/None
</summary>
</member>
<member name="M:SteamKit2.CryptoHelper.SymmetricEncrypt(System.Byte[],System.Byte[])">
<summary>
Performs an encryption using AES/CBC/PKCS7 with an input byte array and key, with a random IV prepended using AES/ECB/None
</summary>
</member>
<member name="M:SteamKit2.CryptoHelper.SymmetricEncryptWithHMACIV(System.Byte[],System.Byte[],System.Byte[])">
<summary>
Performs an encryption using AES/CBC/PKCS7 with an input byte array and key, with a IV (comprised of random bytes and the HMAC-SHA1 of the random bytes and plaintext) prepended using AES/ECB/None
</summary>
</member>
<member name="M:SteamKit2.CryptoHelper.SymmetricDecrypt(System.Byte[],System.Byte[])">
<summary>
Decrypts using AES/CBC/PKCS7 with an input byte array and key, using the random IV prepended using AES/ECB/None
</summary>
</member>
<member name="M:SteamKit2.CryptoHelper.SymmetricDecryptHMACIV(System.Byte[],System.Byte[],System.Byte[])">
<summary>
Decrypts using AES/CBC/PKCS7 with an input byte array and key, using the IV (comprised of random bytes and the HMAC-SHA1 of the random bytes and plaintext) prepended using AES/ECB/None
</summary>
</member>
<member name="M:SteamKit2.CryptoHelper.SymmetricDecrypt(System.Byte[],System.Byte[],System.Byte[]@)">
<summary>
Decrypts using AES/CBC/PKCS7 with an input byte array and key, using the random IV prepended using AES/ECB/None
</summary>
</member>
<member name="M:SteamKit2.CryptoHelper.VerifyAndDecryptPassword(System.Byte[],System.String)">
<summary>
Verifies and performs a symmetricdecrypt on the input using the given password as a key

View File

@@ -1,3 +1,30 @@
------------------------------------------------------------------------------
v 1.7.0 Dec 21, 2015
------------------------------------------------------------------------------
* Added awaitable API for job-based messages. APIs which returned a `JobID` now return an `AsyncJob<>`, which can be used to asynchronously await for results. (pr #170)
* Added `SteamApps.PICSGetAccessTokens` overload with singular parameters. (pr #190)
* Added `SteamFriends.RequestMessageHistory` and `SteamFriends.RequestOfflineMessages` (pr #193)
* Added the ability to connect to Developer instances of Steam (`EUniverse.Dev`). If anyone at Valve is using this internally, hi!
* Added the ability to set a `LoginID` in `SteamUser.LogOnDetails` so that multiple instances can connect from the same host concurrenctly. (pr #217)
* Added `SteamClient.DebugNetworkListener` API to intercept and log raw messages. (pr #204)
* Added the ability to dump messages in NetHook2 format for debugging purposes. (pr #204)
* Upgraded the encryption protocol used to communicate with the Steam servers.
* Implemented protection against man-in-the-middle attacks. (pr #214)
* Server List will now maintain ordering from Steam, increasing the chances of a successful and geographically local connection. (pr #218)
* After calling `SteamUser.LogOff` or `SteamGameServer.LogOff`, `SteamClient.DisconnectedCallback.UserInitiated` will be `true`. (pr #205)
* Fixed a crash when parsing a Steam ID of the format '[i:1:234]'.
* Fixed a crash when logging on in an enviromnent where the hard disk has no serial ID, such as Hyper-V.
* Fixed a bug when parsing a KeyValue file that contains a `/` followed by a newline. (pr #187)
* Updated Steam enums and protobufs.
* Updated game-related GC messages and protobufs.
BREAKING CHANGES
* SteamKit2 now requires .NET 4.5 or equivalent (Mono 3.0), or higher.
* Removed obsoleted `ICallbackMsg` extension methods `IsType<>` and `Handle<>`. (pr #221)
* Game Coordinator base messages are now generated per-game, instead of relying on Dota 2. GC messages should use the base messages for their game, which is separated by namespace. (pr #180)
* Cell IDs are now consistently `uint`s within `SteamDirectory`.
------------------------------------------------------------------------------
v 1.6.5 Oct 17, 2015
------------------------------------------------------------------------------

BIN
tools/ILMerge.doc Normal file

Binary file not shown.

Binary file not shown.