mirror of
https://github.com/JustArchiNET/ArchiSteamFarm.git
synced 2025-12-26 03:06:48 +00:00
Compare commits
65 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
21156a6c79 | ||
|
|
eb56b3c2ac | ||
|
|
4b4f2626a8 | ||
|
|
ec4439afb4 | ||
|
|
9b2a86d891 | ||
|
|
d2c2e30d47 | ||
|
|
d7f2610313 | ||
|
|
1363b23008 | ||
|
|
c1a1cf15b0 | ||
|
|
89a36beeae | ||
|
|
92b9aeae31 | ||
|
|
ef01b304bb | ||
|
|
a8045ac50b | ||
|
|
f97379bf60 | ||
|
|
5197fffa3b | ||
|
|
dc74114f4c | ||
|
|
872151d2f7 | ||
|
|
d495d649ba | ||
|
|
dbd9389d6c | ||
|
|
965432d346 | ||
|
|
c4e1fe2bcf | ||
|
|
b0fc06f3d2 | ||
|
|
4845b21642 | ||
|
|
b7f3ce4036 | ||
|
|
6217552f23 | ||
|
|
a21689c76f | ||
|
|
a461b2da64 | ||
|
|
c653edfca8 | ||
|
|
53b38f5d55 | ||
|
|
9896758c3b | ||
|
|
855a09d4ea | ||
|
|
bfbcf59770 | ||
|
|
29924ad379 | ||
|
|
fd70edc5dd | ||
|
|
0431592be8 | ||
|
|
78405e9ccf | ||
|
|
a6f0c8f7c1 | ||
|
|
057a291f35 | ||
|
|
e0edfebe31 | ||
|
|
b210c24c9c | ||
|
|
f276762025 | ||
|
|
cdd9343903 | ||
|
|
33fc121e67 | ||
|
|
61bd191c15 | ||
|
|
05a7a40332 | ||
|
|
1535ec1c0c | ||
|
|
a7e2e8db73 | ||
|
|
1a91703157 | ||
|
|
7d0ff9f267 | ||
|
|
0753373ba9 | ||
|
|
96ee9692c0 | ||
|
|
4e6afe516a | ||
|
|
1f82a61346 | ||
|
|
8cf368ff88 | ||
|
|
d04e17a046 | ||
|
|
b19a9fdf1f | ||
|
|
cc406998ff | ||
|
|
b4483057b9 | ||
|
|
f72c51a2f8 | ||
|
|
c887dc102e | ||
|
|
2af76f746d | ||
|
|
8fe30f7442 | ||
|
|
941e19ecc5 | ||
|
|
e7b6cc7801 | ||
|
|
3edc89c34e |
15
.gitignore
vendored
15
.gitignore
vendored
@@ -2,15 +2,22 @@
|
||||
## ArchiSteamFarm
|
||||
#################
|
||||
|
||||
# Ignore all config files, apart from ones we want to include
|
||||
ArchiSteamFarm/config/*
|
||||
# Ignore all config files
|
||||
ArchiSteamFarm/config
|
||||
GUI/config
|
||||
|
||||
# Include default config files
|
||||
!ArchiSteamFarm/config/ASF.json
|
||||
!ArchiSteamFarm/config/example.json
|
||||
!ArchiSteamFarm/config/minimal.json
|
||||
|
||||
# Ignore local debugging
|
||||
# Ignore local log
|
||||
ArchiSteamFarm/log.txt
|
||||
ArchiSteamFarm/debug/*
|
||||
GUI/log.txt
|
||||
|
||||
# Ignore local debugging
|
||||
ArchiSteamFarm/debug
|
||||
GUI/debug
|
||||
|
||||
# Ignore out
|
||||
out/
|
||||
|
||||
@@ -79,10 +79,34 @@
|
||||
<HintPath>..\packages\HtmlAgilityPack.1.4.9.5\lib\Net45\HtmlAgilityPack.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.Threading.Tasks, Version=1.0.12.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.Threading.Tasks.Extensions, Version=1.0.12.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.Extensions.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.Threading.Tasks.Extensions.Desktop, Version=1.0.168.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.Extensions.Desktop.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="Newtonsoft.Json, Version=9.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Newtonsoft.Json.9.0.2-beta2\lib\net45\Newtonsoft.Json.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="Nito.AsyncEx, Version=4.0.1.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Nito.AsyncEx.4.0.1\lib\net45\Nito.AsyncEx.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="Nito.AsyncEx.Concurrent, Version=4.0.1.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Nito.AsyncEx.4.0.1\lib\net45\Nito.AsyncEx.Concurrent.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="Nito.AsyncEx.Enlightenment, Version=4.0.1.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Nito.AsyncEx.4.0.1\lib\net45\Nito.AsyncEx.Enlightenment.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="NLog, Version=5.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\NLog.5.0.0-beta05-test\lib\net45\NLog.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
@@ -99,6 +123,7 @@
|
||||
<Reference Include="System.Configuration.Install" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.IO.Compression" />
|
||||
<Reference Include="System.Net" />
|
||||
<Reference Include="System.Security" />
|
||||
<Reference Include="System.ServiceModel" />
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
@@ -138,6 +163,7 @@
|
||||
<Compile Include="Logging.cs" />
|
||||
<Compile Include="InMemoryServerListProvider.cs" />
|
||||
<Compile Include="MobileAuthenticator.cs" />
|
||||
<Compile Include="OS.cs" />
|
||||
<Compile Include="Runtime.cs" />
|
||||
<Compile Include="Program.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
@@ -205,6 +231,7 @@
|
||||
<EmbeddedResource Include="Localization\Strings.ko-KR.resx" />
|
||||
<EmbeddedResource Include="Localization\Strings.lt-LT.resx" />
|
||||
<EmbeddedResource Include="Localization\Strings.mk-MK.resx" />
|
||||
<EmbeddedResource Include="Localization\Strings.nl-BE.resx" />
|
||||
<EmbeddedResource Include="Localization\Strings.nl-NL.resx" />
|
||||
<EmbeddedResource Include="Localization\Strings.no-NO.resx" />
|
||||
<EmbeddedResource Include="Localization\Strings.pl-PL.resx" />
|
||||
@@ -242,6 +269,7 @@
|
||||
copy "$(TargetDir)$(TargetName).exe" "$(SolutionDir)out\ASF.exe"
|
||||
</PostBuildEvent>
|
||||
<PostBuildEvent Condition=" '$(OS)' == 'Unix' AND '$(ConfigurationName)' == 'Release' ">
|
||||
set -e
|
||||
if [ -f "$(SolutionDir)mono_envsetup.sh" ]; then
|
||||
. "$(SolutionDir)mono_envsetup.sh"
|
||||
fi
|
||||
@@ -250,7 +278,13 @@
|
||||
cp "$(TargetDir)config/ASF.json" "$(SolutionDir)out/config"
|
||||
cp "$(TargetDir)config/example.json" "$(SolutionDir)out/config"
|
||||
cp "$(TargetDir)config/minimal.json" "$(SolutionDir)out/config"
|
||||
mono "$(SolutionDir)tools/ILRepack/ILRepack.exe" /ndebug /internalize /parallel /targetplatform:v4 /wildcards /out:"$(SolutionDir)out/ASF-Service.exe" "$(TargetDir)$(TargetName).exe" "$(TargetDir)*.dll"
|
||||
|
||||
if [ -n "$MONO_FACADES" ]; then
|
||||
mono "$(SolutionDir)tools/ILRepack/ILRepack.exe" "/lib:$MONO_FACADES" /ndebug /internalize /parallel /targetplatform:v4 /wildcards /out:"$(SolutionDir)out/ASF-Service.exe" "$(TargetDir)$(TargetName).exe" "$(TargetDir)*.dll"
|
||||
else
|
||||
mono "$(SolutionDir)tools/ILRepack/ILRepack.exe" /ndebug /internalize /parallel /targetplatform:v4 /wildcards /out:"$(SolutionDir)out/ASF-Service.exe" "$(TargetDir)$(TargetName).exe" "$(TargetDir)*.dll"
|
||||
fi
|
||||
|
||||
rm "$(SolutionDir)out/ASF-Service.exe.config"
|
||||
cp "$(SolutionDir)out/ASF-Service.exe" "$(SolutionDir)out/ASF.exe"
|
||||
</PostBuildEvent>
|
||||
@@ -262,10 +296,12 @@
|
||||
<Error Condition="!Exists('..\packages\Fody.1.30.0-beta01\build\dotnet\Fody.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Fody.1.30.0-beta01\build\dotnet\Fody.targets'))" />
|
||||
<Error Condition="!Exists('..\packages\Costura.Fody.2.0.0-beta0018\build\Costura.Fody.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Costura.Fody.2.0.0-beta0018\build\Costura.Fody.targets'))" />
|
||||
<Error Condition="!Exists('..\packages\Resource.Embedder.1.2.2\build\Resource.Embedder.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Resource.Embedder.1.2.2\build\Resource.Embedder.targets'))" />
|
||||
<Error Condition="!Exists('..\packages\Microsoft.Bcl.Build.1.0.21\build\Microsoft.Bcl.Build.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.Bcl.Build.1.0.21\build\Microsoft.Bcl.Build.targets'))" />
|
||||
</Target>
|
||||
<Import Project="..\packages\Fody.1.30.0-beta01\build\dotnet\Fody.targets" Condition="'$(OS)' != 'Unix' AND '$(ConfigurationName)' == 'Release' AND Exists('..\packages\Fody.1.30.0-beta01\build\dotnet\Fody.targets')" />
|
||||
<Import Project="..\packages\Costura.Fody.2.0.0-beta0018\build\Costura.Fody.targets" Condition="'$(OS)' != 'Unix' AND '$(ConfigurationName)' == 'Release' AND Exists('..\packages\Costura.Fody.2.0.0-beta0018\build\Costura.Fody.targets')" />
|
||||
<Import Project="..\packages\Resource.Embedder.1.2.2\build\Resource.Embedder.targets" Condition="'$(OS)' != 'Unix' AND '$(ConfigurationName)' == 'Release' AND Exists('..\packages\Resource.Embedder.1.2.2\build\Resource.Embedder.targets')" />
|
||||
<Import Project="..\packages\Microsoft.Bcl.Build.1.0.21\build\Microsoft.Bcl.Build.targets" Condition="Exists('..\packages\Microsoft.Bcl.Build.1.0.21\build\Microsoft.Bcl.Build.targets')" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
|
||||
@@ -58,14 +58,16 @@ namespace ArchiSteamFarm {
|
||||
private static int Timeout = GlobalConfig.DefaultConnectionTimeout * 1000; // This must be int type
|
||||
|
||||
private readonly Bot Bot;
|
||||
private readonly SemaphoreSlim PublicInventorySemaphore = new SemaphoreSlim(1);
|
||||
private readonly SemaphoreSlim SessionSemaphore = new SemaphoreSlim(1);
|
||||
private readonly SemaphoreSlim SteamApiKeySemaphore = new SemaphoreSlim(1);
|
||||
private readonly WebBrowser WebBrowser;
|
||||
|
||||
internal bool Ready { get; private set; }
|
||||
|
||||
private bool? CachedPublicInventory;
|
||||
private string CachedSteamApiKey;
|
||||
private DateTime LastSessionRefreshCheck = DateTime.MinValue;
|
||||
private string SteamApiKey;
|
||||
private ulong SteamID;
|
||||
|
||||
internal ArchiWebHandler(Bot bot) {
|
||||
@@ -79,6 +81,7 @@ namespace ArchiSteamFarm {
|
||||
}
|
||||
|
||||
public void Dispose() {
|
||||
PublicInventorySemaphore.Dispose();
|
||||
SessionSemaphore.Dispose();
|
||||
SteamApiKeySemaphore.Dispose();
|
||||
}
|
||||
@@ -172,7 +175,7 @@ namespace ArchiSteamFarm {
|
||||
}
|
||||
|
||||
string steamApiKey = await GetApiKey().ConfigureAwait(false);
|
||||
if (string.IsNullOrEmpty(SteamApiKey)) {
|
||||
if (string.IsNullOrEmpty(steamApiKey)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -223,7 +226,7 @@ namespace ArchiSteamFarm {
|
||||
|
||||
internal async Task<HashSet<Steam.TradeOffer>> GetActiveTradeOffers() {
|
||||
string steamApiKey = await GetApiKey().ConfigureAwait(false);
|
||||
if (string.IsNullOrEmpty(SteamApiKey)) {
|
||||
if (string.IsNullOrEmpty(steamApiKey)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -611,7 +614,7 @@ namespace ArchiSteamFarm {
|
||||
}
|
||||
|
||||
string steamApiKey = await GetApiKey().ConfigureAwait(false);
|
||||
if (string.IsNullOrEmpty(SteamApiKey)) {
|
||||
if (string.IsNullOrEmpty(steamApiKey)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -784,6 +787,31 @@ namespace ArchiSteamFarm {
|
||||
return response?.Success;
|
||||
}
|
||||
|
||||
internal async Task<bool> HasPublicInventory() {
|
||||
if (CachedPublicInventory.HasValue) {
|
||||
return CachedPublicInventory.Value;
|
||||
}
|
||||
|
||||
// We didn't fetch state yet
|
||||
await PublicInventorySemaphore.WaitAsync().ConfigureAwait(false);
|
||||
|
||||
try {
|
||||
if (CachedPublicInventory.HasValue) {
|
||||
return CachedPublicInventory.Value;
|
||||
}
|
||||
|
||||
bool? isInventoryPublic = await IsInventoryPublic().ConfigureAwait(false);
|
||||
if (!isInventoryPublic.HasValue) {
|
||||
return false;
|
||||
}
|
||||
|
||||
CachedPublicInventory = isInventoryPublic.Value;
|
||||
return isInventoryPublic.Value;
|
||||
} finally {
|
||||
PublicInventorySemaphore.Release();
|
||||
}
|
||||
}
|
||||
|
||||
internal async Task<bool> HasValidApiKey() => !string.IsNullOrEmpty(await GetApiKey().ConfigureAwait(false));
|
||||
|
||||
internal static void Init() => Timeout = Program.GlobalConfig.ConnectionTimeout * 1000;
|
||||
@@ -984,18 +1012,18 @@ namespace ArchiSteamFarm {
|
||||
}
|
||||
|
||||
private async Task<string> GetApiKey(bool allowRegister = true) {
|
||||
if (SteamApiKey != null) {
|
||||
if (CachedSteamApiKey != null) {
|
||||
// We fetched API key already, and either got valid one, or permanent AccessDenied
|
||||
// In any case, this is our final result
|
||||
return SteamApiKey;
|
||||
return CachedSteamApiKey;
|
||||
}
|
||||
|
||||
// We didn't fetch API key yet
|
||||
await SteamApiKeySemaphore.WaitAsync().ConfigureAwait(false);
|
||||
|
||||
try {
|
||||
if (SteamApiKey != null) {
|
||||
return SteamApiKey;
|
||||
if (CachedSteamApiKey != null) {
|
||||
return CachedSteamApiKey;
|
||||
}
|
||||
|
||||
Tuple<ESteamApiKeyState, string> result = await GetApiKeyState().ConfigureAwait(false);
|
||||
@@ -1008,8 +1036,8 @@ namespace ArchiSteamFarm {
|
||||
case ESteamApiKeyState.Registered:
|
||||
// We succeeded in fetching API key, and it resulted in registered key
|
||||
// Cache the result and return it
|
||||
SteamApiKey = result.Item2;
|
||||
return SteamApiKey;
|
||||
CachedSteamApiKey = result.Item2;
|
||||
return CachedSteamApiKey;
|
||||
case ESteamApiKeyState.NotRegisteredYet:
|
||||
// We succeeded in fetching API key, and it resulted in no key registered yet
|
||||
if (!allowRegister) {
|
||||
@@ -1034,7 +1062,7 @@ namespace ArchiSteamFarm {
|
||||
case ESteamApiKeyState.AccessDenied:
|
||||
// We succeeded in fetching API key, but it resulted in access denied
|
||||
// Cache the result as empty, and return null
|
||||
SteamApiKey = "";
|
||||
CachedSteamApiKey = "";
|
||||
return null;
|
||||
default:
|
||||
// We got some kind of error, maybe it's temporary, maybe it's permanent
|
||||
@@ -1183,6 +1211,25 @@ namespace ArchiSteamFarm {
|
||||
}
|
||||
}
|
||||
|
||||
private async Task<bool?> IsInventoryPublic() {
|
||||
if (!Ready || !await RefreshSessionIfNeeded().ConfigureAwait(false)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const string request = SteamCommunityURL + "/my/edit/settings?l=english";
|
||||
HtmlDocument htmlDocument = await WebBrowser.UrlGetToHtmlDocumentRetry(request).ConfigureAwait(false);
|
||||
|
||||
HtmlNode htmlNode = htmlDocument?.DocumentNode.SelectSingleNode("//input[@id='inventoryPrivacySetting_public']");
|
||||
if (htmlNode == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Notice: checked doesn't have a value - null is lack of attribute, "" is attribute existing
|
||||
string state = htmlNode.GetAttributeValue("checked", null);
|
||||
|
||||
return state != null;
|
||||
}
|
||||
|
||||
private async Task<bool?> IsLoggedIn() {
|
||||
// It would make sense to use /my/profile here, but it dismisses notifications related to profile comments
|
||||
// So instead, we'll use some less intrusive link, such as /my/videos
|
||||
|
||||
@@ -235,11 +235,8 @@ namespace ArchiSteamFarm {
|
||||
ArchiWebHandler.Dispose();
|
||||
CardsFarmer.Dispose();
|
||||
HeartBeatTimer.Dispose();
|
||||
HandledGifts.Dispose();
|
||||
CallbackSemaphore.Dispose();
|
||||
InitializationSemaphore.Dispose();
|
||||
SteamFamilySharingIDs.Dispose();
|
||||
OwnedPackageIDs.Dispose();
|
||||
//SteamSaleEvent.Dispose();
|
||||
Trading.Dispose();
|
||||
|
||||
|
||||
@@ -53,7 +53,7 @@ namespace ArchiSteamFarm {
|
||||
internal readonly string CustomGamePlayedWhileIdle = null;
|
||||
|
||||
[JsonProperty(Required = Required.DisallowNull)]
|
||||
internal readonly bool DismissInventoryNotifications = true;
|
||||
internal readonly bool DismissInventoryNotifications = false;
|
||||
|
||||
[JsonProperty(Required = Required.DisallowNull)]
|
||||
internal readonly bool Enabled = false;
|
||||
|
||||
@@ -86,8 +86,6 @@ namespace ArchiSteamFarm {
|
||||
|
||||
public void Dispose() {
|
||||
// Those are objects that are always being created if constructor doesn't throw exception
|
||||
CurrentGamesFarming.Dispose();
|
||||
GamesToFarm.Dispose();
|
||||
FarmingSemaphore.Dispose();
|
||||
FarmResetEvent.Dispose();
|
||||
|
||||
@@ -370,9 +368,9 @@ namespace ArchiSteamFarm {
|
||||
ushort cardsRemaining = 0;
|
||||
Match progressMatch = Regex.Match(progressText, @"\d+");
|
||||
|
||||
// This might fail if we have no card drops remaining, that's fine
|
||||
// This might fail if we have no card drops remaining, 0 is not printed in this case - that's fine
|
||||
if (progressMatch.Success) {
|
||||
if (!ushort.TryParse(progressMatch.Value, out cardsRemaining)) {
|
||||
if (!ushort.TryParse(progressMatch.Value, out cardsRemaining) || (cardsRemaining == 0)) {
|
||||
Bot.ArchiLogger.LogNullError(nameof(cardsRemaining));
|
||||
continue;
|
||||
}
|
||||
@@ -435,12 +433,12 @@ namespace ArchiSteamFarm {
|
||||
continue;
|
||||
}
|
||||
|
||||
float hours = 0;
|
||||
float hours = 0.0F;
|
||||
Match hoursMatch = Regex.Match(hoursString, @"[0-9\.,]+");
|
||||
|
||||
// This might fail if we have exactly 0.0 hours played, that's fine
|
||||
// This might fail if we have exactly 0.0 hours played, as it's not printed in that case - that's fine
|
||||
if (hoursMatch.Success) {
|
||||
if (!float.TryParse(hoursMatch.Value, NumberStyles.Number, CultureInfo.InvariantCulture, out hours)) {
|
||||
if (!float.TryParse(hoursMatch.Value, NumberStyles.Number, CultureInfo.InvariantCulture, out hours) || (hours <= 0.0F)) {
|
||||
Bot.ArchiLogger.LogNullError(nameof(hours));
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -25,30 +25,27 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using Nito.AsyncEx;
|
||||
|
||||
namespace ArchiSteamFarm {
|
||||
internal sealed class ConcurrentEnumerator<T> : IEnumerator<T> {
|
||||
public T Current => Enumerator.Current;
|
||||
|
||||
private readonly IEnumerator<T> Enumerator;
|
||||
private readonly ReaderWriterLockSlim Lock;
|
||||
private readonly IDisposable Lock;
|
||||
|
||||
object IEnumerator.Current => Current;
|
||||
|
||||
internal ConcurrentEnumerator(ICollection<T> collection, ReaderWriterLockSlim rwLock) {
|
||||
internal ConcurrentEnumerator(ICollection<T> collection, AsyncReaderWriterLock rwLock) {
|
||||
if ((collection == null) || (rwLock == null)) {
|
||||
throw new ArgumentNullException(nameof(collection) + " || " + nameof(rwLock));
|
||||
}
|
||||
|
||||
rwLock.EnterReadLock();
|
||||
|
||||
Lock = rwLock;
|
||||
Lock = rwLock.ReaderLock();
|
||||
Enumerator = collection.GetEnumerator();
|
||||
}
|
||||
|
||||
public void Dispose() => Lock?.ExitReadLock();
|
||||
|
||||
public void Dispose() => Lock.Dispose();
|
||||
public bool MoveNext() => Enumerator.MoveNext();
|
||||
public void Reset() => Enumerator.Reset();
|
||||
}
|
||||
|
||||
@@ -22,21 +22,16 @@
|
||||
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using Nito.AsyncEx;
|
||||
|
||||
namespace ArchiSteamFarm {
|
||||
internal sealed class ConcurrentHashSet<T> : ICollection<T>, IDisposable {
|
||||
internal sealed class ConcurrentHashSet<T> : ICollection<T> {
|
||||
public int Count {
|
||||
get {
|
||||
Lock.EnterReadLock();
|
||||
|
||||
try {
|
||||
using (Lock.ReaderLock()) {
|
||||
return HashSet.Count;
|
||||
} finally {
|
||||
Lock.ExitReadLock();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -44,48 +39,31 @@ namespace ArchiSteamFarm {
|
||||
public bool IsReadOnly => false;
|
||||
|
||||
private readonly HashSet<T> HashSet = new HashSet<T>();
|
||||
private readonly ReaderWriterLockSlim Lock = new ReaderWriterLockSlim();
|
||||
private readonly AsyncReaderWriterLock Lock = new AsyncReaderWriterLock();
|
||||
|
||||
public void Clear() {
|
||||
Lock.EnterWriteLock();
|
||||
|
||||
try {
|
||||
using (Lock.WriterLock()) {
|
||||
HashSet.Clear();
|
||||
} finally {
|
||||
Lock.ExitWriteLock();
|
||||
}
|
||||
}
|
||||
|
||||
public bool Contains(T item) {
|
||||
Lock.EnterReadLock();
|
||||
|
||||
try {
|
||||
using (Lock.ReaderLock()) {
|
||||
return HashSet.Contains(item);
|
||||
} finally {
|
||||
Lock.ExitReadLock();
|
||||
}
|
||||
}
|
||||
|
||||
public void CopyTo(T[] array, int arrayIndex) {
|
||||
Lock.EnterReadLock();
|
||||
|
||||
try {
|
||||
using (Lock.ReaderLock()) {
|
||||
HashSet.CopyTo(array, arrayIndex);
|
||||
} finally {
|
||||
Lock.ExitReadLock();
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose() => Lock.Dispose();
|
||||
public IEnumerator<T> GetEnumerator() => new ConcurrentEnumerator<T>(HashSet, Lock);
|
||||
|
||||
public bool Remove(T item) {
|
||||
Lock.EnterWriteLock();
|
||||
|
||||
try {
|
||||
using (Lock.WriterLock()) {
|
||||
return HashSet.Remove(item);
|
||||
} finally {
|
||||
Lock.ExitWriteLock();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -94,45 +72,43 @@ namespace ArchiSteamFarm {
|
||||
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
|
||||
|
||||
internal void Add(T item) {
|
||||
Lock.EnterWriteLock();
|
||||
|
||||
try {
|
||||
using (Lock.WriterLock()) {
|
||||
HashSet.Add(item);
|
||||
} finally {
|
||||
Lock.ExitWriteLock();
|
||||
}
|
||||
}
|
||||
|
||||
internal void ClearAndTrim() {
|
||||
Lock.EnterWriteLock();
|
||||
|
||||
try {
|
||||
using (Lock.WriterLock()) {
|
||||
HashSet.Clear();
|
||||
HashSet.TrimExcess();
|
||||
} finally {
|
||||
Lock.ExitWriteLock();
|
||||
}
|
||||
}
|
||||
|
||||
internal bool ReplaceIfNeededWith(ICollection<T> items) {
|
||||
Lock.EnterUpgradeableReadLock();
|
||||
|
||||
try {
|
||||
using (AsyncReaderWriterLock.UpgradeableReaderKey readerKey = Lock.UpgradeableReaderLock()) {
|
||||
if (HashSet.SetEquals(items)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ReplaceWith(items);
|
||||
ReplaceWith(items, readerKey);
|
||||
return true;
|
||||
} finally {
|
||||
Lock.ExitUpgradeableReadLock();
|
||||
}
|
||||
}
|
||||
|
||||
internal void ReplaceWith(IEnumerable<T> items) {
|
||||
Lock.EnterWriteLock();
|
||||
|
||||
try {
|
||||
using (Lock.WriterLock()) {
|
||||
HashSet.Clear();
|
||||
|
||||
foreach (T item in items) {
|
||||
HashSet.Add(item);
|
||||
}
|
||||
|
||||
HashSet.TrimExcess();
|
||||
}
|
||||
}
|
||||
|
||||
private void ReplaceWith(IEnumerable<T> items, AsyncReaderWriterLock.UpgradeableReaderKey readerKey) {
|
||||
using (readerKey.Upgrade()) {
|
||||
HashSet.Clear();
|
||||
|
||||
foreach (T item in items) {
|
||||
@@ -140,8 +116,6 @@ namespace ArchiSteamFarm {
|
||||
}
|
||||
|
||||
HashSet.TrimExcess();
|
||||
} finally {
|
||||
Lock.ExitWriteLock();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -77,10 +77,7 @@ namespace ArchiSteamFarm {
|
||||
ServerListProvider.ServerListUpdated += OnServerListUpdated;
|
||||
}
|
||||
|
||||
public void Dispose() {
|
||||
ServerListProvider.ServerListUpdated -= OnServerListUpdated;
|
||||
ServerListProvider.Dispose();
|
||||
}
|
||||
public void Dispose() => ServerListProvider.ServerListUpdated -= OnServerListUpdated;
|
||||
|
||||
internal static GlobalDatabase Load(string filePath) {
|
||||
if (string.IsNullOrEmpty(filePath)) {
|
||||
|
||||
@@ -30,11 +30,10 @@ using Newtonsoft.Json;
|
||||
using SteamKit2.Discovery;
|
||||
|
||||
namespace ArchiSteamFarm {
|
||||
internal sealed class InMemoryServerListProvider : IDisposable, IServerListProvider {
|
||||
internal sealed class InMemoryServerListProvider : IServerListProvider {
|
||||
[JsonProperty(Required = Required.DisallowNull)]
|
||||
private readonly ConcurrentHashSet<IPEndPoint> Servers = new ConcurrentHashSet<IPEndPoint>();
|
||||
|
||||
public void Dispose() => Servers.Dispose();
|
||||
public Task<IEnumerable<IPEndPoint>> FetchServerListAsync() => Task.FromResult<IEnumerable<IPEndPoint>>(Servers);
|
||||
|
||||
public Task UpdateServerListAsync(IEnumerable<IPEndPoint> endPoints) {
|
||||
|
||||
@@ -28,23 +28,36 @@ using Newtonsoft.Json;
|
||||
|
||||
namespace ArchiSteamFarm.JSON {
|
||||
internal static class GitHub {
|
||||
[SuppressMessage("ReSharper", "ClassCannotBeInstantiated")]
|
||||
[SuppressMessage("ReSharper", "ClassNeverInstantiated.Global")]
|
||||
internal sealed class ReleaseResponse {
|
||||
#pragma warning disable 649
|
||||
internal sealed class Asset {
|
||||
[JsonProperty(PropertyName = "browser_download_url", Required = Required.Always)]
|
||||
internal readonly string DownloadURL;
|
||||
|
||||
[JsonProperty(PropertyName = "name", Required = Required.Always)]
|
||||
internal readonly string Name;
|
||||
}
|
||||
|
||||
[JsonProperty(PropertyName = "tag_name", Required = Required.Always)]
|
||||
internal readonly string Tag;
|
||||
|
||||
[JsonProperty(PropertyName = "assets", Required = Required.Always)]
|
||||
internal readonly List<Asset> Assets;
|
||||
#pragma warning restore 649
|
||||
|
||||
#pragma warning disable 649
|
||||
[JsonProperty(PropertyName = "tag_name", Required = Required.Always)]
|
||||
internal readonly string Tag;
|
||||
#pragma warning restore 649
|
||||
|
||||
// Deserialized from JSON
|
||||
private ReleaseResponse() { }
|
||||
|
||||
internal sealed class Asset {
|
||||
#pragma warning disable 649
|
||||
[JsonProperty(PropertyName = "browser_download_url", Required = Required.Always)]
|
||||
internal readonly string DownloadURL;
|
||||
#pragma warning restore 649
|
||||
|
||||
#pragma warning disable 649
|
||||
[JsonProperty(PropertyName = "name", Required = Required.Always)]
|
||||
internal readonly string Name;
|
||||
#pragma warning restore 649
|
||||
|
||||
// Deserialized from JSON
|
||||
private Asset() { }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -26,7 +26,6 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using HtmlAgilityPack;
|
||||
using Newtonsoft.Json;
|
||||
using SteamKit2;
|
||||
@@ -40,6 +39,7 @@ namespace ArchiSteamFarm.JSON {
|
||||
[JsonProperty(PropertyName = "success", Required = Required.Always)]
|
||||
internal readonly bool Success;
|
||||
#pragma warning restore 649
|
||||
|
||||
internal ulong OtherSteamID64 {
|
||||
get {
|
||||
if (_OtherSteamID64 != 0) {
|
||||
@@ -103,6 +103,7 @@ namespace ArchiSteamFarm.JSON {
|
||||
[JsonProperty(PropertyName = "html", Required = Required.DisallowNull)]
|
||||
private readonly string HTML;
|
||||
#pragma warning restore 649
|
||||
|
||||
private HtmlDocument HtmlDocument {
|
||||
get {
|
||||
if (_HtmlDocument != null) {
|
||||
@@ -113,8 +114,7 @@ namespace ArchiSteamFarm.JSON {
|
||||
return null;
|
||||
}
|
||||
|
||||
_HtmlDocument = new HtmlDocument();
|
||||
_HtmlDocument.LoadHtml(WebUtility.HtmlDecode(HTML));
|
||||
_HtmlDocument = WebBrowser.StringToHtmlDocument(HTML);
|
||||
return _HtmlDocument;
|
||||
}
|
||||
}
|
||||
@@ -196,7 +196,9 @@ namespace ArchiSteamFarm.JSON {
|
||||
private ulong _OtherSteamID64;
|
||||
private ulong _TradeOfferID;
|
||||
private EType _Type;
|
||||
private ConfirmationDetails() { } // Deserialized from JSON
|
||||
|
||||
// Deserialized from JSON
|
||||
private ConfirmationDetails() { }
|
||||
|
||||
internal enum EType : byte {
|
||||
Unknown,
|
||||
@@ -208,16 +210,18 @@ namespace ArchiSteamFarm.JSON {
|
||||
|
||||
[SuppressMessage("ReSharper", "ClassCannotBeInstantiated")]
|
||||
[SuppressMessage("ReSharper", "ClassNeverInstantiated.Global")]
|
||||
internal sealed class ConfirmationResponse { // Deserialized from JSON
|
||||
internal sealed class ConfirmationResponse {
|
||||
#pragma warning disable 649
|
||||
[JsonProperty(PropertyName = "success", Required = Required.Always)]
|
||||
internal readonly bool Success;
|
||||
#pragma warning restore 649
|
||||
|
||||
// Deserialized from JSON
|
||||
private ConfirmationResponse() { }
|
||||
}
|
||||
|
||||
internal sealed class Item { // REF: https://developer.valvesoftware.com/wiki/Steam_Web_API/IEconService#CEcon_Asset | Deserialized from JSON (SteamCommunity) and constructed from code
|
||||
// REF: https://developer.valvesoftware.com/wiki/Steam_Web_API/IEconService#CEcon_Asset
|
||||
internal sealed class Item {
|
||||
internal const ushort SteamAppID = 753;
|
||||
internal const byte SteamCommunityContextID = 6;
|
||||
|
||||
@@ -340,8 +344,8 @@ namespace ArchiSteamFarm.JSON {
|
||||
set { AssetIDString = value; }
|
||||
}
|
||||
|
||||
// This constructor is used for constructing items in trades being received
|
||||
internal Item(uint appID, ulong contextID, ulong classID, uint amount, uint realAppID, EType type) {
|
||||
// Constructed from trades being received
|
||||
internal Item(uint appID, ulong contextID, ulong classID, uint amount, uint realAppID, EType type = EType.Unknown) {
|
||||
if ((appID == 0) || (contextID == 0) || (classID == 0) || (amount == 0) || (realAppID == 0)) {
|
||||
throw new ArgumentNullException(nameof(classID) + " || " + nameof(contextID) + " || " + nameof(classID) + " || " + nameof(amount) + " || " + nameof(realAppID));
|
||||
}
|
||||
@@ -354,6 +358,7 @@ namespace ArchiSteamFarm.JSON {
|
||||
Type = type;
|
||||
}
|
||||
|
||||
// Deserialized from JSON
|
||||
[SuppressMessage("ReSharper", "UnusedMember.Local")]
|
||||
private Item() { }
|
||||
|
||||
@@ -371,27 +376,30 @@ namespace ArchiSteamFarm.JSON {
|
||||
/*
|
||||
[SuppressMessage("ReSharper", "ClassCannotBeInstantiated")]
|
||||
[SuppressMessage("ReSharper", "ClassNeverInstantiated.Global")]
|
||||
internal sealed class NewDiscoveryQueueResponse { // Deserialized from JSON
|
||||
internal sealed class NewDiscoveryQueueResponse {
|
||||
#pragma warning disable 649
|
||||
[JsonProperty(PropertyName = "queue", Required = Required.Always)]
|
||||
internal readonly HashSet<uint> Queue;
|
||||
#pragma warning restore 649
|
||||
|
||||
// Deserialized from JSON
|
||||
private NewDiscoveryQueueResponse() { }
|
||||
}
|
||||
*/
|
||||
|
||||
[SuppressMessage("ReSharper", "ClassCannotBeInstantiated")]
|
||||
[SuppressMessage("ReSharper", "ClassNeverInstantiated.Global")]
|
||||
internal sealed class RedeemWalletResponse { // Deserialized from JSON
|
||||
internal sealed class RedeemWalletResponse {
|
||||
#pragma warning disable 649
|
||||
[JsonProperty(PropertyName = "detail", Required = Required.Always)]
|
||||
internal readonly ArchiHandler.PurchaseResponseCallback.EPurchaseResult PurchaseResult;
|
||||
#pragma warning restore 649
|
||||
|
||||
// Deserialized from JSON
|
||||
private RedeemWalletResponse() { }
|
||||
}
|
||||
|
||||
// REF: https://developer.valvesoftware.com/wiki/Steam_Web_API/IEconService#CEcon_TradeOffer
|
||||
internal sealed class TradeOffer {
|
||||
internal readonly HashSet<Item> ItemsToGive = new HashSet<Item>();
|
||||
internal readonly HashSet<Item> ItemsToReceive = new HashSet<Item>();
|
||||
@@ -418,6 +426,7 @@ namespace ArchiSteamFarm.JSON {
|
||||
|
||||
private ulong _OtherSteamID64;
|
||||
|
||||
// Constructed from trades being received
|
||||
internal TradeOffer(ulong tradeOfferID, uint otherSteamID3, ETradeOfferState state) {
|
||||
if ((tradeOfferID == 0) || (otherSteamID3 == 0) || (state == ETradeOfferState.Unknown)) {
|
||||
throw new ArgumentNullException(nameof(tradeOfferID) + " || " + nameof(otherSteamID3) + " || " + nameof(state));
|
||||
@@ -486,7 +495,7 @@ namespace ArchiSteamFarm.JSON {
|
||||
return true;
|
||||
}
|
||||
|
||||
internal bool IsSteamCardsRequest() => ItemsToGive.All(item => (item.AppID == Item.SteamAppID) && (item.ContextID == Item.SteamCommunityContextID) && (item.Type == Item.EType.TradingCard)); // REF: https://developer.valvesoftware.com/wiki/Steam_Web_API/IEconService#CEcon_TradeOffer | Constructed from code
|
||||
internal bool IsSteamCardsRequest() => ItemsToGive.All(item => (item.AppID == Item.SteamAppID) && (item.ContextID == Item.SteamCommunityContextID) && (item.Type == Item.EType.TradingCard));
|
||||
|
||||
[SuppressMessage("ReSharper", "UnusedMember.Global")]
|
||||
internal enum ETradeOfferState : byte {
|
||||
@@ -511,7 +520,7 @@ namespace ArchiSteamFarm.JSON {
|
||||
internal readonly ItemList ItemsToGive = new ItemList();
|
||||
|
||||
[JsonProperty(PropertyName = "them", Required = Required.Always)]
|
||||
internal readonly ItemList ItemsToReceive = new ItemList(); // Constructed from code
|
||||
internal readonly ItemList ItemsToReceive = new ItemList();
|
||||
|
||||
internal sealed class ItemList {
|
||||
[JsonProperty(PropertyName = "assets", Required = Required.Always)]
|
||||
|
||||
@@ -118,7 +118,7 @@
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<data name="AcceptingTrade" xml:space="preserve">
|
||||
<value>Приемане на търговията: {0}</value>
|
||||
<value>Приемане на замяната: {0}</value>
|
||||
<comment>{0} will be replaced by trade number</comment>
|
||||
</data>
|
||||
<data name="AutoUpdateCheckInfo" xml:space="preserve">
|
||||
@@ -160,7 +160,7 @@
|
||||
<value>Отказва да изпълни тази функцията, поради невалиден DeviceID в ASF 2FA!</value>
|
||||
</data>
|
||||
<data name="ErrorNoBotsDefined" xml:space="preserve">
|
||||
<value>Няма настрени ботове, да не би да сте забравили да настроите ASF?</value>
|
||||
<value>Няма настроени ботове, да не би да сте забравили да настроите ASF?</value>
|
||||
</data>
|
||||
<data name="ErrorObjectIsNull" xml:space="preserve">
|
||||
<value>{0} е нулев!</value>
|
||||
@@ -200,7 +200,9 @@
|
||||
<data name="WarningFailed" xml:space="preserve">
|
||||
<value>Неуспешно!</value>
|
||||
</data>
|
||||
|
||||
<data name="GlobalConfigChanged" xml:space="preserve">
|
||||
<value>Файлът с общите настройки беше променен!</value>
|
||||
</data>
|
||||
|
||||
<data name="IgnoringTrade" xml:space="preserve">
|
||||
<value>Пренебрегване на замяната: {0}</value>
|
||||
@@ -225,8 +227,14 @@
|
||||
</data>
|
||||
|
||||
|
||||
|
||||
|
||||
<data name="RuntimeVersionOK" xml:space="preserve">
|
||||
<value>Вашата {0} версия е ОК.</value>
|
||||
<comment>{0} will be replaced by runtime name (e.g. "Mono")</comment>
|
||||
</data>
|
||||
<data name="WarningRuntimeVersionTooOld" xml:space="preserve">
|
||||
<value>Вашата {0} версия е твърде стара!</value>
|
||||
<comment>{0} will be replaced by runtime name (e.g. "Mono")</comment>
|
||||
</data>
|
||||
<data name="Starting" xml:space="preserve">
|
||||
<value>Стартиране...</value>
|
||||
</data>
|
||||
@@ -265,12 +273,25 @@
|
||||
<value>{0} секунди</value>
|
||||
<comment>{0} will be replaced by number of seconds</comment>
|
||||
</data>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<data name="UnlockingParentalAccount" xml:space="preserve">
|
||||
<value>Отключване на родителския профил...</value>
|
||||
</data>
|
||||
<data name="UpdateCheckingNewVersion" xml:space="preserve">
|
||||
<value>Проверяване за нова версия...</value>
|
||||
</data>
|
||||
<data name="UpdateDownloadingNewVersion" xml:space="preserve">
|
||||
<value>В момента се сваля новата версия... Докато чакате, помислете за дарение, ако оценявате свършената от нас работа! :)</value>
|
||||
</data>
|
||||
<data name="UpdateFinished" xml:space="preserve">
|
||||
<value>Обновлението приключи!</value>
|
||||
</data>
|
||||
<data name="UpdateNewVersionAvailable" xml:space="preserve">
|
||||
<value>Нова версия на ASF е налична! Помислете за обновление!</value>
|
||||
</data>
|
||||
<data name="UpdateVersionInfo" xml:space="preserve">
|
||||
<value>Версия на компютъра Ви: {0} | Версия на сървъра: {1}</value>
|
||||
<comment>{0} will be replaced by current version, {1} will be replaced by remote version</comment>
|
||||
</data>
|
||||
|
||||
|
||||
|
||||
@@ -392,12 +413,16 @@
|
||||
<value>Влизане…</value>
|
||||
</data>
|
||||
|
||||
<data name="BotLootingFailed" xml:space="preserve">
|
||||
<value>Предложението за замяна е неуспешно!</value>
|
||||
</data>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<data name="BotLootingSuccess" xml:space="preserve">
|
||||
<value>Предложението за замяна е изпратено успешно!</value>
|
||||
</data>
|
||||
|
||||
|
||||
|
||||
@@ -431,8 +456,14 @@
|
||||
</data>
|
||||
|
||||
|
||||
|
||||
|
||||
<data name="BotUnableToConnect" xml:space="preserve">
|
||||
<value>Не може да се свърже със Steam: {0}</value>
|
||||
<comment>{0} will be replaced by failure reason (string)</comment>
|
||||
</data>
|
||||
<data name="BotUnableToLogin" xml:space="preserve">
|
||||
<value>Не може да се впише в Steam: {0}/{1}</value>
|
||||
<comment>{0} will be replaced by failure reason (string), {1} will be replaced by extended failure reason (string)</comment>
|
||||
</data>
|
||||
<data name="ErrorIsEmpty" xml:space="preserve">
|
||||
<value>{0} е празен!</value>
|
||||
<comment>{0} will be replaced by object's name</comment>
|
||||
|
||||
@@ -132,8 +132,13 @@
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<data name="ErrorExitingWithNonZeroErrorCode" xml:space="preserve">
|
||||
<value>Exiting with non-zero error code!</value>
|
||||
</data>
|
||||
<data name="ErrorFailingRequest" xml:space="preserve">
|
||||
<value>Pyyntö evätty: {0}</value>
|
||||
<comment>{0} will be replaced by URL of the request</comment>
|
||||
</data>
|
||||
|
||||
<data name="ErrorIsInvalid" xml:space="preserve">
|
||||
<value>{0} on virheellinen!</value>
|
||||
@@ -159,7 +164,10 @@
|
||||
|
||||
|
||||
|
||||
|
||||
<data name="LoggingIn" xml:space="preserve">
|
||||
<value>Kirjaudutaan to {0}...</value>
|
||||
<comment>{0} will be replaced by service's name</comment>
|
||||
</data>
|
||||
|
||||
|
||||
|
||||
@@ -265,38 +273,43 @@
|
||||
<value>Tarkastellaan muita badge sivuja...</value>
|
||||
</data>
|
||||
<data name="ChosenFarmingAlgorithm" xml:space="preserve">
|
||||
<value>Asetettu idlaus algoritmi: {0}</value>
|
||||
<value>Asetettu idlaamisen algoritmi: {0}</value>
|
||||
<comment>{0} will be replaced by the name of chosen idling algorithm</comment>
|
||||
</data>
|
||||
<data name="Done" xml:space="preserve">
|
||||
<value>Valmis!</value>
|
||||
</data>
|
||||
<data name="GamesToIdle" xml:space="preserve">
|
||||
<value>In case there is only 1 game left to idle and only one card drop left, "peliä" should be "peli" and "korttia" should "kortti". Same goes for timestamps, if only 1 left its "minuutti, tunti, päivä, kuukausi
|
||||
|
||||
edit; also word "joissa" should be "jossa" if only card left
|
||||
|
||||
{0}{1}{2}</value>
|
||||
<value>Idlattavana yhteensä {0} peliä joissa ({1} korttia). Arvioitu aika (~{2})...</value>
|
||||
<comment>{0} will be replaced by number of games, {1} will be replaced by number of cards, {2} will be replaced by translated TimeSpan string built from TimeSpan* translation parts</comment>
|
||||
</data>
|
||||
<data name="IdlingFinished" xml:space="preserve">
|
||||
<value>Idlaus valmis!</value>
|
||||
<value>Idlaaminen valmis!</value>
|
||||
</data>
|
||||
<data name="IdlingFinishedForGame" xml:space="preserve">
|
||||
<value>Idlaus valmis {0} ({1}) Kulunut aika: {2}!
|
||||
|
||||
I think this works alot better in finnish...</value>
|
||||
<value>Idlaaminen valmis {0} ({1}) Kulunut aika: {2}!</value>
|
||||
<comment>{0} will be replaced by game's appID (number), {1} will be replaced by game's name, {2} will be replaced by translated TimeSpan string built from TimeSpan* translation parts</comment>
|
||||
</data>
|
||||
|
||||
|
||||
<data name="IdlingStatusForGame" xml:space="preserve">
|
||||
<value>Idlauksen tila kohteelle {0} ({1}): {2} korttia jäljellä</value>
|
||||
<comment>{0} will be replaced by game's appID (number), {1} will be replaced by game's name, {2} will be replaced by number of cards left to idle</comment>
|
||||
</data>
|
||||
<data name="IdlingStopped" xml:space="preserve">
|
||||
<value>Idlaus pysäytetty!</value>
|
||||
<value>Idlaaminen pysäytetty!</value>
|
||||
</data>
|
||||
|
||||
|
||||
|
||||
|
||||
<data name="NothingToIdle" xml:space="preserve">
|
||||
<value>Tällä accountilla ei ole mitään idlattavaa!</value>
|
||||
</data>
|
||||
<data name="NowIdling" xml:space="preserve">
|
||||
<value>Nyt idlataan: {0} ({1})</value>
|
||||
<comment>{0} will be replaced by game's appID (number), {1} will be replaced by game's name</comment>
|
||||
</data>
|
||||
<data name="NowIdlingList" xml:space="preserve">
|
||||
<value>Nyt idlataan: {0}</value>
|
||||
<comment>{0} will be replaced by list of the games (appIDs, numbers), separated by a comma</comment>
|
||||
</data>
|
||||
|
||||
<data name="StillIdling" xml:space="preserve">
|
||||
<value>Idlataan: {0} ({1})</value>
|
||||
@@ -307,11 +320,11 @@ I think this works alot better in finnish...</value>
|
||||
<comment>{0} will be replaced by list of the games (appIDs, numbers), separated by a comma</comment>
|
||||
</data>
|
||||
<data name="StoppedIdling" xml:space="preserve">
|
||||
<value>Idlaus pysäytetty: {0} ({1})</value>
|
||||
<value>Idlaaminen pysäytetty: {0} ({1})</value>
|
||||
<comment>{0} will be replaced by game's appID (number), {1} will be replaced by game's name</comment>
|
||||
</data>
|
||||
<data name="StoppedIdlingList" xml:space="preserve">
|
||||
<value>Idlaus pysäytetty: {0}</value>
|
||||
<value>Idlaaminen pysäytetty: {0}</value>
|
||||
<comment>{0} will be replaced by list of the games (appIDs, numbers), separated by a comma</comment>
|
||||
</data>
|
||||
<data name="UnknownCommand" xml:space="preserve">
|
||||
@@ -333,11 +346,13 @@ I think this works alot better in finnish...</value>
|
||||
<value>Sinun DeviceID on virheellinen tai sitä ei ole olemassa!</value>
|
||||
</data>
|
||||
|
||||
|
||||
<data name="BotAutomaticIdlingNowPaused" xml:space="preserve">
|
||||
<value>Automaattinen idlaaminen on pysäytetty!</value>
|
||||
</data>
|
||||
|
||||
|
||||
<data name="BotAutomaticIdlingPausedWithCountdown" xml:space="preserve">
|
||||
<value>Automaattinen idlaus on pysäytetty! Sinulla on {0} minuuttia aikaa käynnistää peli.</value>
|
||||
<value>Automaattinen idlaaminen on pysäytetty! Sinulla on {0} minuuttia aikaa käynnistää peli.</value>
|
||||
<comment>{0} will be replaced by number of minutes</comment>
|
||||
</data>
|
||||
|
||||
@@ -409,9 +424,7 @@ I think this works alot better in finnish...</value>
|
||||
<data name="BotConnectionLost" xml:space="preserve">
|
||||
<value>Yhteys Steamin palvelimeen katkesi, yhdistetään uudelleen...</value>
|
||||
</data>
|
||||
<data name="BotAccountFree" xml:space="preserve">
|
||||
<value>Suljit pelin, idlaus prosessi jatkuu!</value>
|
||||
</data>
|
||||
|
||||
|
||||
|
||||
<data name="BotConnecting" xml:space="preserve">
|
||||
|
||||
@@ -384,7 +384,7 @@ StackTrace :
|
||||
<comment>{0} will be replaced by bot's name, {1} will be replaced by game's appID (number), {2} will be replaced by game's name, {3} will be replaced by number of cards left to idle, {4} will be replaced by total number of games to idle, {5} will be replaced by total number of cards to idle, {6} will be replaced by translated TimeSpan string built from TimeSpan* translation parts</comment>
|
||||
</data>
|
||||
<data name="BotStatusIdlingList" xml:space="preserve">
|
||||
<value>Le bot {0} collecte les cartes des jeux : {1} sur un total de {2} jeux (cartes{3}) restant à farmer (~{4} restantes).</value>
|
||||
<value>Le bot {0} collecte les cartes des jeux : {1} sur un total de {2} jeux ({3} cartes) restants à traiter (~{4} restant(e)s).</value>
|
||||
<comment>{0} will be replaced by bot's name, {1} will be replaced by list of the games (appIDs, numbers), {2} will be replaced by total number of games to idle, {3} will be replaced by total number of cards to idle, {4} will be replaced by translated TimeSpan string built from TimeSpan* translation parts</comment>
|
||||
</data>
|
||||
<data name="CheckingFirstBadgePage" xml:space="preserve">
|
||||
@@ -470,7 +470,7 @@ StackTrace :
|
||||
<comment>{0} will be replaced by giftID (number)</comment>
|
||||
</data>
|
||||
<data name="BotAccountLimited" xml:space="preserve">
|
||||
<value>Ce compte est limité, le processus de farming est impossible tant que la restriction n'a pas été levée !</value>
|
||||
<value>Ce compte est limité, le processus de collecte est impossible tant que la restriction n'a pas été levée !</value>
|
||||
</data>
|
||||
<data name="BotAddLicenseResponse" xml:space="preserve">
|
||||
<value><{0}> GameID : {1} | Statut : {2}</value>
|
||||
|
||||
@@ -149,33 +149,62 @@ StackTrace: {2}</value>
|
||||
<value>Kérés sikertelen: {0}</value>
|
||||
<comment>{0} will be replaced by URL of the request</comment>
|
||||
</data>
|
||||
|
||||
<data name="ErrorGlobalConfigNotLoaded" xml:space="preserve">
|
||||
<value>Nem lehet betölteni a globális konfigurációt! Kérlek, győződj meg róla, hogy {0} létezik és érvényes! Ha valami nem tiszta, olvasd el a wikin a telepítési segédletet.</value>
|
||||
<comment>{0} will be replaced by file's path</comment>
|
||||
</data>
|
||||
<data name="ErrorIsInvalid" xml:space="preserve">
|
||||
<value>Érvénytelen {0}!</value>
|
||||
<comment>{0} will be replaced by object's name</comment>
|
||||
</data>
|
||||
|
||||
|
||||
<data name="ErrorMobileAuthenticatorInvalidDeviceID" xml:space="preserve">
|
||||
<value>Ez a funkció nem hajtható végre, mivel a DeviceID érvénytelen az ASF 2FA-ban!</value>
|
||||
</data>
|
||||
<data name="ErrorNoBotsDefined" xml:space="preserve">
|
||||
<value>Nincsenek botok definiálva, elfelejtetted volna bekonfigurálni az ASF-t?</value>
|
||||
</data>
|
||||
<data name="ErrorObjectIsNull" xml:space="preserve">
|
||||
<value>{0} értéke nulla!</value>
|
||||
<comment>{0} will be replaced by object's name</comment>
|
||||
</data>
|
||||
<data name="ErrorParsingObject" xml:space="preserve">
|
||||
<value>{0} feldolgozása sikertelen!</value>
|
||||
<comment>{0} will be replaced by object's name</comment>
|
||||
</data>
|
||||
<data name="ErrorRemovingOldBinary" xml:space="preserve">
|
||||
<value>Nem lehet törölni a régi ASF bináris fájlt, kérlek manuálisan töröld {0}-t, hogy sikerüljön a frissítés!</value>
|
||||
<comment>{0} will be replaced by file's path</comment>
|
||||
</data>
|
||||
<data name="ErrorRequestFailedTooManyTimes" xml:space="preserve">
|
||||
<value>A kérést {0} próbálkozás után sem sikerült teljesíteni!</value>
|
||||
<comment>{0} will be replaced by maximum number of tries</comment>
|
||||
</data>
|
||||
<data name="ErrorUpdateCheckFailed" xml:space="preserve">
|
||||
<value>Nem lehet lekérni a legújabb verziót!</value>
|
||||
</data>
|
||||
<data name="ErrorUpdateNoAssetForThisBinary" xml:space="preserve">
|
||||
<value>Nem lehet folytatni a frissítést, mivel nincs olyan fájl, ami kapcsolatban állna a jelenleg futó binárissal! Győződj meg róla, hogy az ASF bináris fájlod rendesen van elnevezve!</value>
|
||||
</data>
|
||||
<data name="ErrorUpdateNoAssets" xml:space="preserve">
|
||||
<value>Nem lehet folytatni a frissítést, mivel ez a verzió nem tartalmaz egyetlen fájlt sem!</value>
|
||||
</data>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<data name="ErrorWCFAccessDenied" xml:space="preserve">
|
||||
<value>A kérés nem teljesíthető, mivel a SteamOwnerID nincs beállítva!</value>
|
||||
<comment>SteamOwnerID is name of bot config property, it should not be translated</comment>
|
||||
</data>
|
||||
<data name="Exiting" xml:space="preserve">
|
||||
<value>Kilépés...</value>
|
||||
</data>
|
||||
<data name="WarningFailed" xml:space="preserve">
|
||||
<value>Sikertelen!</value>
|
||||
</data>
|
||||
|
||||
|
||||
<data name="GlobalConfigChanged" xml:space="preserve">
|
||||
<value>A globális konfigurációs fájl megváltozott!</value>
|
||||
</data>
|
||||
<data name="ErrorGlobalConfigRemoved" xml:space="preserve">
|
||||
<value>A globális konfigurációs fájl törölve lett!</value>
|
||||
</data>
|
||||
<data name="IgnoringTrade" xml:space="preserve">
|
||||
<value>Csereajánlat figyelmen kívül hagyása: {0}</value>
|
||||
<comment>{0} will be replaced by trade number</comment>
|
||||
@@ -184,8 +213,12 @@ StackTrace: {2}</value>
|
||||
<value>Belépés {0} szolgáltatásba...</value>
|
||||
<comment>{0} will be replaced by service's name</comment>
|
||||
</data>
|
||||
|
||||
|
||||
<data name="NoBotsAreRunning" xml:space="preserve">
|
||||
<value>Egyetlen bot sem fut, kilépés...</value>
|
||||
</data>
|
||||
<data name="RefreshingOurSession" xml:space="preserve">
|
||||
<value>Munkamenet frissítése!</value>
|
||||
</data>
|
||||
<data name="RejectingTrade" xml:space="preserve">
|
||||
<value>Csereajánlat elutasítása: {0}</value>
|
||||
<comment>{0} will be replaced by trade number</comment>
|
||||
@@ -193,10 +226,21 @@ StackTrace: {2}</value>
|
||||
<data name="Restarting" xml:space="preserve">
|
||||
<value>Újraindítás...</value>
|
||||
</data>
|
||||
|
||||
|
||||
|
||||
|
||||
<data name="WarningRuntimeUnsupported" xml:space="preserve">
|
||||
<value>Az ASF nem támogatott futásidejű verziót észlelt, a program lehet hogy NEM fog megfelelően futni a jelenlegi környezetben. Futtatás csak saját felelősségre, segítséget ne várj!</value>
|
||||
</data>
|
||||
<data name="RuntimeVersionComparison" xml:space="preserve">
|
||||
<value>Szükséges verzió: {0} | Észlelt verzió: {1}</value>
|
||||
<comment>{0} will be replaced by required version, {1} will be replaced by current version</comment>
|
||||
</data>
|
||||
<data name="RuntimeVersionOK" xml:space="preserve">
|
||||
<value>A {0} futásidejű verziója rendben van.</value>
|
||||
<comment>{0} will be replaced by runtime name (e.g. "Mono")</comment>
|
||||
</data>
|
||||
<data name="WarningRuntimeVersionTooOld" xml:space="preserve">
|
||||
<value>A {0} futásidejű verziója túl régi!</value>
|
||||
<comment>{0} will be replaced by runtime name (e.g. "Mono")</comment>
|
||||
</data>
|
||||
<data name="Starting" xml:space="preserve">
|
||||
<value>Indítás...</value>
|
||||
</data>
|
||||
@@ -241,118 +285,330 @@ StackTrace: {2}</value>
|
||||
<data name="UpdateCheckingNewVersion" xml:space="preserve">
|
||||
<value>Új verzió keresése...</value>
|
||||
</data>
|
||||
|
||||
<data name="UpdateDownloadingNewVersion" xml:space="preserve">
|
||||
<value>Új verzió letöltése folyamatban... Mialatt várakozol, fontold meg, hogy pénzzel támogatod a munkámat, ha tetszik, amit csinálok! :)</value>
|
||||
</data>
|
||||
<data name="UpdateFinished" xml:space="preserve">
|
||||
<value>Frissítés kész!</value>
|
||||
</data>
|
||||
|
||||
|
||||
<data name="UpdateNewVersionAvailable" xml:space="preserve">
|
||||
<value>Új ASF verzió elérhető! Fontold meg a manuális frissítést!</value>
|
||||
</data>
|
||||
<data name="UpdateVersionInfo" xml:space="preserve">
|
||||
<value>Lokális verzió: {0} | Távoli verzió: {1}</value>
|
||||
<comment>{0} will be replaced by current version, {1} will be replaced by remote version</comment>
|
||||
</data>
|
||||
<data name="UserInputDeviceID" xml:space="preserve">
|
||||
<value><{0}> Adja meg az eszköz ID-t ("android:" részt is beleértve): </value>
|
||||
<comment>{0} will be replaced by bot's name. Please note that this translation should end with space</comment>
|
||||
</data>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<data name="UserInputSteam2FA" xml:space="preserve">
|
||||
<value><{0}> Kérlek, add meg a 2FA kódodat a Steam authenticator alkalmazásból: </value>
|
||||
<comment>{0} will be replaced by bot's name. Please note that this translation should end with space</comment>
|
||||
</data>
|
||||
<data name="UserInputSteamGuard" xml:space="preserve">
|
||||
<value><{0}> Kérlek, add meg a SteamGuard hitelesítő kódodat, amit az e-mail címedre küldtek: </value>
|
||||
<comment>{0} will be replaced by bot's name. Please note that this translation should end with space</comment>
|
||||
</data>
|
||||
<data name="UserInputSteamLogin" xml:space="preserve">
|
||||
<value><{0}> Kérlek, add meg a Steam belépési neved: </value>
|
||||
<comment>{0} will be replaced by bot's name. Please note that this translation should end with space</comment>
|
||||
</data>
|
||||
<data name="UserInputSteamParentalPIN" xml:space="preserve">
|
||||
<value><{0}> Kérlek, add meg a Steam szülői felügyelet PIN kódját: </value>
|
||||
<comment>{0} will be replaced by bot's name. Please note that this translation should end with space</comment>
|
||||
</data>
|
||||
<data name="UserInputSteamPassword" xml:space="preserve">
|
||||
<value><{0}> Kérlek, add meg a Steam jelszavad: </value>
|
||||
<comment>{0} will be replaced by bot's name. Please note that this translation should end with space</comment>
|
||||
</data>
|
||||
<data name="UserInputUnknown" xml:space="preserve">
|
||||
<value><{0}> Kérlek, add meg a(z) {1} nem dokumentált értékét: </value>
|
||||
<comment>{0} will be replaced by bot's name, {1} will be replaced by property name. Please note that this translation should end with space</comment>
|
||||
</data>
|
||||
<data name="UserInputWCFHost" xml:space="preserve">
|
||||
<value><{0}> Kérlek, add meg a WCF host-odat: </value>
|
||||
<comment>{0} will be replaced by bot's name. Please note that this translation should end with space</comment>
|
||||
</data>
|
||||
<data name="WarningUnknownValuePleaseReport" xml:space="preserve">
|
||||
<value>{0} ismeretlen értéket kapott, kérlek, jelentsd ezt: {1}</value>
|
||||
<comment>{0} will be replaced by object's name, {1} will be replaced by value for that object</comment>
|
||||
</data>
|
||||
<data name="WarningTooManyGamesToPlay" xml:space="preserve">
|
||||
<value>Több mint {0} játék egyidejű játszására nincs lehetőség, csak az első {0} bejegyzés lesz használva {1}-ból!</value>
|
||||
<comment>{0} will be replaced by max number of games, {1} will be replaced by name of the configuration property</comment>
|
||||
</data>
|
||||
<data name="WarningWCFIgnoringCommand" xml:space="preserve">
|
||||
<value>WCF parancs figyelmen kívül hagyva, mivel --client nem volt megadva: {0}</value>
|
||||
<comment>{0} will be replaced by WCF command</comment>
|
||||
</data>
|
||||
<data name="ErrorWCFAddressAccessDeniedException" xml:space="preserve">
|
||||
<value>A WCF szolgáltatást nem lehetett elindítani AddressAccessDeniedException miatt! Ha szeretnéd az ASF által nyújtott WCF szolgáltatást használni, próbáld meg az ASF-t adminisztrátorként, vagy megfelelő engedélyekkel futtatni!</value>
|
||||
</data>
|
||||
<data name="WCFAnswered" xml:space="preserve">
|
||||
<value>A WCF parancsra ({0}) a következő válasz érkezett: {1}</value>
|
||||
<comment>{0} will be replaced by WCF command, {1} will be replaced by WCF answer</comment>
|
||||
</data>
|
||||
<data name="WCFReady" xml:space="preserve">
|
||||
<value>A WCF szerver készen áll!</value>
|
||||
</data>
|
||||
<data name="WCFResponseReceived" xml:space="preserve">
|
||||
<value>WCF válasz érkezett: {0}</value>
|
||||
<comment>{0} will be replaced by WCF response</comment>
|
||||
</data>
|
||||
<data name="WCFSendingCommand" xml:space="preserve">
|
||||
<value>{0} parancs küldése a WCF szervernek {1}-n...</value>
|
||||
<comment>{0} will be replaced by WCF command, {1} will be replaced by WCF hostname</comment>
|
||||
</data>
|
||||
<data name="WCFStarting" xml:space="preserve">
|
||||
<value>WCF szerver indítása {0}-n...</value>
|
||||
<comment>{0} will be replaced by WCF hostname</comment>
|
||||
</data>
|
||||
<data name="BotAlreadyStopped" xml:space="preserve">
|
||||
<value>Az a bot példány már le lett állítva!</value>
|
||||
</data>
|
||||
<data name="BotNotFound" xml:space="preserve">
|
||||
<value>Egyetlen bot sem található {0} névvel!</value>
|
||||
<comment>{0} will be replaced by bot's name</comment>
|
||||
</data>
|
||||
<data name="BotsStatusOverview" xml:space="preserve">
|
||||
<value>{0}/{1} bot fut jelenleg. Összesen {2} játékot ({3} kártya) kell még futtatni.</value>
|
||||
<comment>{0} will be replaced by number of active bots, {1} will be replaced by total number of bots, {2} will be replaced by total number of games left to idle, {3} will be replaced by total number of cards left to idle</comment>
|
||||
</data>
|
||||
<data name="BotStatusIdling" xml:space="preserve">
|
||||
<value>Bot {0} az alábbi játékot farmolja: {1} ({2}, {3} kártya maradt még). Összesen {4} játék ({5} kártya) maradt (kb. {6} míg végez).</value>
|
||||
<comment>{0} will be replaced by bot's name, {1} will be replaced by game's appID (number), {2} will be replaced by game's name, {3} will be replaced by number of cards left to idle, {4} will be replaced by total number of games to idle, {5} will be replaced by total number of cards to idle, {6} will be replaced by translated TimeSpan string built from TimeSpan* translation parts</comment>
|
||||
</data>
|
||||
<data name="BotStatusIdlingList" xml:space="preserve">
|
||||
<value>Bot {0} az alábbi játékokat farmolja: {1}. Összesen {2} játék ({3} kártya) maradt (kb. {4} míg végez).</value>
|
||||
<comment>{0} will be replaced by bot's name, {1} will be replaced by list of the games (appIDs, numbers), {2} will be replaced by total number of games to idle, {3} will be replaced by total number of cards to idle, {4} will be replaced by translated TimeSpan string built from TimeSpan* translation parts</comment>
|
||||
</data>
|
||||
<data name="CheckingFirstBadgePage" xml:space="preserve">
|
||||
<value>A kitűzők első oldalának ellenőrzése...</value>
|
||||
</data>
|
||||
<data name="CheckingOtherBadgePages" xml:space="preserve">
|
||||
<value>A többi kitűző oldal ellenőrzése...</value>
|
||||
</data>
|
||||
<data name="ChosenFarmingAlgorithm" xml:space="preserve">
|
||||
<value>A kiválasztott farmoló algoritmus: {0}</value>
|
||||
<comment>{0} will be replaced by the name of chosen idling algorithm</comment>
|
||||
</data>
|
||||
<data name="Done" xml:space="preserve">
|
||||
<value>Kész!</value>
|
||||
</data>
|
||||
<data name="GamesToIdle" xml:space="preserve">
|
||||
<value>Még összesen {0} játék ({1} kártya) maradt (kb. {2} míg végez)...</value>
|
||||
<comment>{0} will be replaced by number of games, {1} will be replaced by number of cards, {2} will be replaced by translated TimeSpan string built from TimeSpan* translation parts</comment>
|
||||
</data>
|
||||
<data name="IdlingFinished" xml:space="preserve">
|
||||
<value>Farmolás befejezve!</value>
|
||||
</data>
|
||||
<data name="IdlingFinishedForGame" xml:space="preserve">
|
||||
<value>Farmolás befejezve: {0} ({1}) készen van {2} játékidő után!</value>
|
||||
<comment>{0} will be replaced by game's appID (number), {1} will be replaced by game's name, {2} will be replaced by translated TimeSpan string built from TimeSpan* translation parts</comment>
|
||||
</data>
|
||||
<data name="IdlingFinishedForGames" xml:space="preserve">
|
||||
<value>Az alábbi játékok farmolása befejeződött: {0}</value>
|
||||
<comment>{0} will be replaced by list of the games (appIDs, numbers), separated by a comma</comment>
|
||||
</data>
|
||||
<data name="IdlingStatusForGame" xml:space="preserve">
|
||||
<value>A farmolás állapota {0} ({1}) számára: {2} kártya maradt</value>
|
||||
<comment>{0} will be replaced by game's appID (number), {1} will be replaced by game's name, {2} will be replaced by number of cards left to idle</comment>
|
||||
</data>
|
||||
<data name="IdlingStopped" xml:space="preserve">
|
||||
<value>Farmolás leállítva!</value>
|
||||
</data>
|
||||
|
||||
<data name="NothingToIdle" xml:space="preserve">
|
||||
<value>Ezen az accounton nincs mit farmolni!</value>
|
||||
</data>
|
||||
<data name="NowIdling" xml:space="preserve">
|
||||
<value>Farmolás alatt: {0} ({1})</value>
|
||||
<comment>{0} will be replaced by game's appID (number), {1} will be replaced by game's name</comment>
|
||||
</data>
|
||||
<data name="NowIdlingList" xml:space="preserve">
|
||||
<value>Farmolás alatt: {0}</value>
|
||||
<comment>{0} will be replaced by list of the games (appIDs, numbers), separated by a comma</comment>
|
||||
</data>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<data name="StillIdling" xml:space="preserve">
|
||||
<value>Még mindig farmolás alatt: {0} ({1})</value>
|
||||
<comment>{0} will be replaced by game's appID (number), {1} will be replaced by game's name</comment>
|
||||
</data>
|
||||
<data name="StillIdlingList" xml:space="preserve">
|
||||
<value>Még mindig farmolás alatt: {0}</value>
|
||||
<comment>{0} will be replaced by list of the games (appIDs, numbers), separated by a comma</comment>
|
||||
</data>
|
||||
<data name="StoppedIdling" xml:space="preserve">
|
||||
<value>Farmolás leállítva: {0} ({1})</value>
|
||||
<comment>{0} will be replaced by game's appID (number), {1} will be replaced by game's name</comment>
|
||||
</data>
|
||||
<data name="StoppedIdlingList" xml:space="preserve">
|
||||
<value>Farmolás leállítva: {0}</value>
|
||||
<comment>{0} will be replaced by list of the games (appIDs, numbers), separated by a comma</comment>
|
||||
</data>
|
||||
<data name="UnknownCommand" xml:space="preserve">
|
||||
<value>Ismeretlen parancs!</value>
|
||||
</data>
|
||||
<data name="WarningCouldNotCheckBadges" xml:space="preserve">
|
||||
<value>Nem lehet lekérni a kitűző információkat, később újra lesz próbálva!</value>
|
||||
</data>
|
||||
<data name="WarningCouldNotCheckCardsStatus" xml:space="preserve">
|
||||
<value>A kártyák állapota nem elérhető ehhez: {0} ({1}), később újra lesz próbálva!</value>
|
||||
<comment>{0} will be replaced by game's appID (number), {1} will be replaced by game's name</comment>
|
||||
</data>
|
||||
<data name="BotAcceptingGift" xml:space="preserve">
|
||||
<value>Ajándék elfogadása: {0}...</value>
|
||||
<comment>{0} will be replaced by giftID (number)</comment>
|
||||
</data>
|
||||
<data name="BotAccountLimited" xml:space="preserve">
|
||||
<value>Ez az account korlátozva van, a farmolás a korlátozás megszűnéséig nem elérhető!</value>
|
||||
</data>
|
||||
<data name="BotAddLicenseResponse" xml:space="preserve">
|
||||
<value><{0}> GameID: {1} | Állapot: {2}</value>
|
||||
<comment>{0} will be replaced by bot's name, {1} will be replaced by gameID (number), {2} will be replaced by status string</comment>
|
||||
</data>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<data name="BotAlreadyRunning" xml:space="preserve">
|
||||
<value>Az a bot példány már fut!</value>
|
||||
<comment>{0} will be replaced by bot's name</comment>
|
||||
</data>
|
||||
<data name="BotAuthenticatorConverting" xml:space="preserve">
|
||||
<value>.maFile konvertálása ASF formátumba...</value>
|
||||
</data>
|
||||
<data name="BotAuthenticatorImportFinished" xml:space="preserve">
|
||||
<value>A mobil hitelesítő importálása sikeres!</value>
|
||||
</data>
|
||||
<data name="BotAuthenticatorInvalidDeviceID" xml:space="preserve">
|
||||
<value>A DeviceID-d inkorrekt, vagy nem létezik!</value>
|
||||
</data>
|
||||
<data name="BotAuthenticatorToken" xml:space="preserve">
|
||||
<value>2FA Token: {0}</value>
|
||||
<comment>{0} will be replaced by generated 2FA token (string)</comment>
|
||||
</data>
|
||||
<data name="BotAutomaticIdlingNowPaused" xml:space="preserve">
|
||||
<value>Automatikus farmolás szüneteltetve!</value>
|
||||
</data>
|
||||
<data name="BotAutomaticIdlingNowResumed" xml:space="preserve">
|
||||
<value>Automatikus farmolás folytatva!</value>
|
||||
</data>
|
||||
<data name="BotAutomaticIdlingPausedAlready" xml:space="preserve">
|
||||
<value>Az automatikus farmolás már szüneteltetve van!</value>
|
||||
</data>
|
||||
<data name="BotAutomaticIdlingPausedWithCountdown" xml:space="preserve">
|
||||
<value>Automatikus farmolás szüneteltetve! {0} perced van, hogy elindíts egy játékot.</value>
|
||||
<comment>{0} will be replaced by number of minutes</comment>
|
||||
</data>
|
||||
<data name="BotAutomaticIdlingResumedAlready" xml:space="preserve">
|
||||
<value>Az automatikus farmolás már folytatva van!</value>
|
||||
</data>
|
||||
<data name="BotConnected" xml:space="preserve">
|
||||
<value>Csatlakozva a Steamhez!</value>
|
||||
</data>
|
||||
<data name="BotDisconnected" xml:space="preserve">
|
||||
<value>Lecsatlakozva a Steamről!</value>
|
||||
</data>
|
||||
<data name="BotDisconnecting" xml:space="preserve">
|
||||
<value>Kapcsolat bontása...</value>
|
||||
</data>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<data name="BotEncryptedPassword" xml:space="preserve">
|
||||
<value>[{0}] jelszó: {1}</value>
|
||||
<comment>{0} will be replaced by password encryption method (string), {1} will be replaced by encrypted password using that method (string)</comment>
|
||||
</data>
|
||||
<data name="BotInstanceNotStartingBecauseDisabled" xml:space="preserve">
|
||||
<value>Ezt a bot példányt nem lehet elindítani, mert a konfigurációs fájlban ki van kapcsolva!</value>
|
||||
</data>
|
||||
<data name="BotInvalidAuthenticatorDuringLogin" xml:space="preserve">
|
||||
<value>TwoFactorCodeMismatch hibakód érkezett {0} alkalommal egymás után. Ez szinte mindig érvénytelen ASF 2FA adatokat jelent. Megszakítás!</value>
|
||||
<comment>{0} will be replaced by maximum allowed number of failed 2FA attempts</comment>
|
||||
</data>
|
||||
<data name="BotLoggedOff" xml:space="preserve">
|
||||
<value>Kijelentkezve a Steamből: {0}</value>
|
||||
<comment>{0} will be replaced by logging off reason (string)</comment>
|
||||
</data>
|
||||
<data name="BotLoggedOn" xml:space="preserve">
|
||||
<value>Sikeres bejelentkezés!</value>
|
||||
</data>
|
||||
<data name="BotLoggingIn" xml:space="preserve">
|
||||
<value>Bejelentkezés...</value>
|
||||
</data>
|
||||
<data name="BotLogonSessionReplaced" xml:space="preserve">
|
||||
<value>Ezt az accountot egy másik ASF példány már használja, ami nem várt viselkedést eredményez. A további futás megtagadva!</value>
|
||||
</data>
|
||||
<data name="BotLootingFailed" xml:space="preserve">
|
||||
<value>Csereajánlat nem sikerült!</value>
|
||||
</data>
|
||||
<data name="BotLootingMasterNotDefined" xml:space="preserve">
|
||||
<value>A csereajánlatot nem lehet elküldeni, mert a SteamMasterID nincs beállítva!</value>
|
||||
<comment>SteamMasterID is name of bot config property, it should not be translated</comment>
|
||||
</data>
|
||||
|
||||
|
||||
|
||||
<data name="BotLootingSuccess" xml:space="preserve">
|
||||
<value>Csereajánlat sikeresen elküldve!</value>
|
||||
</data>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<data name="BotNoASFAuthenticator" xml:space="preserve">
|
||||
<value>Annál a botnál nincs bekapcsolva az ASF 2FA! Elfelejtetted volna ASF 2FA-ként importálni a hitelesítődet?</value>
|
||||
</data>
|
||||
<data name="BotNotConnected" xml:space="preserve">
|
||||
<value>Ez a bot példány nincs csatlakozva!</value>
|
||||
<comment>{0} will be replaced by bot's name</comment>
|
||||
</data>
|
||||
<data name="BotNotOwnedYet" xml:space="preserve">
|
||||
<value><{0}> Még nincs meg: {1}</value>
|
||||
<comment>{0} will be replaced by bot's name, {1} will be replaced by query (string)</comment>
|
||||
</data>
|
||||
<data name="BotOwnedAlready" xml:space="preserve">
|
||||
<value><{0}> Már megvan: {1} | {2}</value>
|
||||
<comment>{0} will be replaced by bot's name, {1} will be replaced by game's appID (number), {2} will be replaced by game's name</comment>
|
||||
</data>
|
||||
|
||||
<data name="BotReconnecting" xml:space="preserve">
|
||||
<value>Újracsatlakozás...</value>
|
||||
</data>
|
||||
<data name="BotRedeemResponse" xml:space="preserve">
|
||||
<value><{0}> Kulcs: {1} | Állapot: {2}</value>
|
||||
<comment>{0} will be replaced by bot's name, {1} will be replaced by cd-key (string), {2} will be replaced by status string</comment>
|
||||
</data>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<data name="BotRemovedExpiredLoginKey" xml:space="preserve">
|
||||
<value>A lejárt belépési kulcs törölve!</value>
|
||||
</data>
|
||||
<data name="BotsStatusNotIdling" xml:space="preserve">
|
||||
<value>Bot {0} nem farmol jelenleg semmit.</value>
|
||||
<comment>{0} will be replaced by bot's name</comment>
|
||||
</data>
|
||||
<data name="BotStatusLimited" xml:space="preserve">
|
||||
<value>Bot {0} korlátozva van, ezért farmolással nem tud kártyákat dobni.</value>
|
||||
<comment>{0} will be replaced by bot's name</comment>
|
||||
</data>
|
||||
<data name="BotStatusNotConnected" xml:space="preserve">
|
||||
<value>Bot {0} nincs csatlakoztatva.</value>
|
||||
<comment>{0} will be replaced by bot's name</comment>
|
||||
</data>
|
||||
<data name="BotStatusNotRunning" xml:space="preserve">
|
||||
<value>Bot {0} nem fut jelenleg.</value>
|
||||
<comment>{0} will be replaced by bot's name</comment>
|
||||
</data>
|
||||
<data name="BotStatusPaused" xml:space="preserve">
|
||||
<value>Bot {0} le van állítva, vagy manuális módban fut.</value>
|
||||
<comment>{0} will be replaced by bot's name</comment>
|
||||
</data>
|
||||
<data name="BotStatusPlayingNotAvailable" xml:space="preserve">
|
||||
<value>Bot {0} jelenleg használatban van.</value>
|
||||
<comment>{0} will be replaced by bot's name</comment>
|
||||
</data>
|
||||
<data name="BotUnableToConnect" xml:space="preserve">
|
||||
<value>Nem lehet csatlakozni a Steamhez: {0}</value>
|
||||
<comment>{0} will be replaced by failure reason (string)</comment>
|
||||
</data>
|
||||
<data name="BotUnableToLogin" xml:space="preserve">
|
||||
<value>Nem lehet belépni a Steamre: {0}/{1}</value>
|
||||
<comment>{0} will be replaced by failure reason (string), {1} will be replaced by extended failure reason (string)</comment>
|
||||
</data>
|
||||
<data name="ErrorIsEmpty" xml:space="preserve">
|
||||
<value>Üres {0}!</value>
|
||||
<comment>{0} will be replaced by object's name</comment>
|
||||
@@ -361,23 +617,59 @@ StackTrace: {2}</value>
|
||||
<value>Fel nem használt kulcsok: {0}</value>
|
||||
<comment>{0} will be replaced by list of cd-keys (strings), separated by a comma</comment>
|
||||
</data>
|
||||
<data name="WarningFailedWithError" xml:space="preserve">
|
||||
<value>Hiba miatt nem sikerült: {0}</value>
|
||||
<comment>{0} will be replaced by failure reason (string)</comment>
|
||||
</data>
|
||||
<data name="BotConnectionLost" xml:space="preserve">
|
||||
<value>Megszakadt a kapcsolat a Steam hálózattal, újrakapcsolódás...</value>
|
||||
</data>
|
||||
<data name="BotAccountFree" xml:space="preserve">
|
||||
<value>Az account már nincs használatban, a farmolási folyamat folytatódik!</value>
|
||||
</data>
|
||||
<data name="BotAccountOccupied" xml:space="preserve">
|
||||
<value>Az account jelenleg használatban van, amikor felszabadul, az ASF folytatni fogja a farmolást...</value>
|
||||
</data>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<data name="BotConnecting" xml:space="preserve">
|
||||
<value>Kapcsolódás...</value>
|
||||
</data>
|
||||
<data name="BotHeartBeatFailed" xml:space="preserve">
|
||||
<value>Nem lehet lecsatlakozni a kliensről, megszabadulunk ettől a bot példánytól!</value>
|
||||
</data>
|
||||
<data name="BotSteamDirectoryInitializationFailed" xml:space="preserve">
|
||||
<value>A SteamDirectory-t nem sikerült inicializálni, a Steam hálózathoz való csatlakozás a szokásosnál tovább is eltarthat!</value>
|
||||
</data>
|
||||
<data name="BotStopping" xml:space="preserve">
|
||||
<value>Leállás...</value>
|
||||
</data>
|
||||
<data name="ErrorBotConfigInvalid" xml:space="preserve">
|
||||
<value>A bot konfigurációd érvénytelen, kérlek, ellenőrizd {0} tartalmát, majd próbáld meg újból!</value>
|
||||
<comment>{0} will be replaced by file's path</comment>
|
||||
</data>
|
||||
<data name="ErrorDatabaseInvalid" xml:space="preserve">
|
||||
<value>A perzisztens adatbázist nem lehet betölteni! Ha a hiba továbbra is fennáll, kérlek, töröld {0}-t, hogy az adatbázis újra elkészülhessen!</value>
|
||||
<comment>{0} will be replaced by file's path</comment>
|
||||
</data>
|
||||
<data name="Initializing" xml:space="preserve">
|
||||
<value>{0} inicializálása...</value>
|
||||
<comment>{0} will be replaced by service name that is being initialized</comment>
|
||||
</data>
|
||||
<data name="WarningPrivacyPolicy" xml:space="preserve">
|
||||
<value>Kérlek, olvasd el az adatvédelmi szabályzatunkat a wiki-n, ha szeretnéd tudni, mit is csinál valójában az ASF!</value>
|
||||
</data>
|
||||
<data name="Welcome" xml:space="preserve">
|
||||
<value>Úgy tűnik, most indítottad el első alkalommal a programot, üdvözöllek!</value>
|
||||
</data>
|
||||
|
||||
|
||||
|
||||
<data name="ErrorInvalidCurrentCulture" xml:space="preserve">
|
||||
<value>A te CurrentCulture változód érvénytelen, az ASF az alapértelmezettet fogja használni!</value>
|
||||
</data>
|
||||
<data name="TranslationIncomplete" xml:space="preserve">
|
||||
<value>Az ASF megpróbálja az elsődleges kultúrádat ({0}) használni, de a fordítás azon a nyelven csak {1}-ban készült el eddig. Talán segíthetnél a saját nyelved ASF fordításában?</value>
|
||||
<comment>{0} will be replaced by culture code, such as "en-US", {1} will be replaced by completeness percentage, such as "78.5%"</comment>
|
||||
</data>
|
||||
<data name="IdlingGameNotReleasedYet" xml:space="preserve">
|
||||
<value>A farmolás {0} ({1}) számára átmenetileg nem elérhető, mivel a játék még nem jelent meg.</value>
|
||||
<comment>{0} will be replaced by game's appID (number), {1} will be replaced by game's name</comment>
|
||||
</data>
|
||||
</root>
|
||||
@@ -696,7 +696,7 @@
|
||||
<comment>{0} will be replaced by culture code, such as "en-US", {1} will be replaced by completeness percentage, such as "78.5%"</comment>
|
||||
</data>
|
||||
<data name="IdlingGameNotReleasedYet" xml:space="preserve">
|
||||
<value>Pendiaman {0} ({1}) sementara dinonaktifkan, seperti permainan yang belum dirilis.</value>
|
||||
<value>Idling {0} ({1}) untuk sementara dinonaktifkan, karena permainan tersebut belum dirilis.</value>
|
||||
<comment>{0} will be replaced by game's appID (number), {1} will be replaced by game's name</comment>
|
||||
</data>
|
||||
</root>
|
||||
703
ArchiSteamFarm/Localization/Strings.nl-BE.resx
Normal file
703
ArchiSteamFarm/Localization/Strings.nl-BE.resx
Normal file
@@ -0,0 +1,703 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" id="root">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace"/>
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0"/>
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string"/>
|
||||
<xsd:attribute name="type" type="xsd:string"/>
|
||||
<xsd:attribute name="mimetype" type="xsd:string"/>
|
||||
<xsd:attribute ref="xml:space"/>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string"/>
|
||||
<xsd:attribute name="name" type="xsd:string"/>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1"/>
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2"/>
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1"/>
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3"/>
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4"/>
|
||||
<xsd:attribute ref="xml:space"/>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1"/>
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required"/>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<data name="AcceptingTrade" xml:space="preserve">
|
||||
<value>Ruilaanbieding {0} wordt geaccepteerd</value>
|
||||
<comment>{0} will be replaced by trade number</comment>
|
||||
</data>
|
||||
<data name="AutoUpdateCheckInfo" xml:space="preserve">
|
||||
<value>ASF controleert automatisch om de {0} uren op een nieuwe versie.</value>
|
||||
<comment>{0} will be replaced by number of hours</comment>
|
||||
</data>
|
||||
<data name="Content" xml:space="preserve">
|
||||
<value>Inhoud: {0}</value>
|
||||
<comment>{0} will be replaced by content string. Please note that this string should include newline for formatting.</comment>
|
||||
</data>
|
||||
<data name="ErrorConfigPropertyInvalid" xml:space="preserve">
|
||||
<value>Geconfigureerde {0} eigenschap is niet geldig: {1}</value>
|
||||
<comment>{0} will be replaced by name of the configuration property, {1} will be replaced by invalid value</comment>
|
||||
</data>
|
||||
<data name="ErrorEarlyFatalExceptionInfo" xml:space="preserve">
|
||||
<value>ASF V{0} heeft een fatale uitzondering tegengekomen voordat het kern logboek module in staat was om te initialiseren!</value>
|
||||
<comment>{0} will be replaced by version number</comment>
|
||||
</data>
|
||||
<data name="ErrorEarlyFatalExceptionPrint" xml:space="preserve">
|
||||
<value>Uitzondering: {0}() {1}
|
||||
StackTrace:
|
||||
{2}</value>
|
||||
<comment>{0} will be replaced by function name, {1} will be replaced by exception message, {2} will be replaced by entire stack trace. Please note that this string should include newlines for formatting.</comment>
|
||||
</data>
|
||||
<data name="ErrorExitingWithNonZeroErrorCode" xml:space="preserve">
|
||||
<value>Afsluiten met een niet-nulzijnde foutcode!</value>
|
||||
</data>
|
||||
<data name="ErrorFailingRequest" xml:space="preserve">
|
||||
<value>Vezoek mislukt: {0}</value>
|
||||
<comment>{0} will be replaced by URL of the request</comment>
|
||||
</data>
|
||||
<data name="ErrorGlobalConfigNotLoaded" xml:space="preserve">
|
||||
<value>Globale configuratie kan niet worden geladen, controleer of het bestand {0} bestaat en of het geldig is! Volg de handleiding op de wiki als je niet weet je wat je moet doen.</value>
|
||||
<comment>{0} will be replaced by file's path</comment>
|
||||
</data>
|
||||
<data name="ErrorIsInvalid" xml:space="preserve">
|
||||
<value>{0} is ongeldig!</value>
|
||||
<comment>{0} will be replaced by object's name</comment>
|
||||
</data>
|
||||
<data name="ErrorMobileAuthenticatorInvalidDeviceID" xml:space="preserve">
|
||||
<value>Deze functie wordt niet uitgevoerd als gevolg van de ongeldige DeviceID in ASF 2FA!</value>
|
||||
</data>
|
||||
<data name="ErrorNoBotsDefined" xml:space="preserve">
|
||||
<value>Er zijn geen bots gedefinieerd, ben je vergeten om ASF te configureren?</value>
|
||||
</data>
|
||||
<data name="ErrorObjectIsNull" xml:space="preserve">
|
||||
<value>{0} is null!</value>
|
||||
<comment>{0} will be replaced by object's name</comment>
|
||||
</data>
|
||||
<data name="ErrorParsingObject" xml:space="preserve">
|
||||
<value>Verwerking van {0} mislukt!</value>
|
||||
<comment>{0} will be replaced by object's name</comment>
|
||||
</data>
|
||||
<data name="ErrorRemovingOldBinary" xml:space="preserve">
|
||||
<value>Kon niet de oude ASF binary verwijderen, verwijder alsjeblieft {0} handmatig zodat de updatefunctie werkt!</value>
|
||||
<comment>{0} will be replaced by file's path</comment>
|
||||
</data>
|
||||
<data name="ErrorRequestFailedTooManyTimes" xml:space="preserve">
|
||||
<value>Verzoek mislukt ondanks {0} pogingen!</value>
|
||||
<comment>{0} will be replaced by maximum number of tries</comment>
|
||||
</data>
|
||||
<data name="ErrorUpdateCheckFailed" xml:space="preserve">
|
||||
<value>Controle voor de laatste versie is mislukt!</value>
|
||||
</data>
|
||||
<data name="ErrorUpdateNoAssetForThisBinary" xml:space="preserve">
|
||||
<value>Kon niet verdergaan met updaten omdat er geen bestand bestaat dat gerelateerd is aan de momenteel actieve binary! Controleer of de ASF binary de juiste naam heeft!</value>
|
||||
</data>
|
||||
<data name="ErrorUpdateNoAssets" xml:space="preserve">
|
||||
<value>Kon niet verdergaan met de update omdat deze versie niet alle bestanden omvat!</value>
|
||||
</data>
|
||||
<data name="ErrorUserInputRunningInHeadlessMode" xml:space="preserve">
|
||||
<value>Aanvraag voor gebruikersinvoer ontvangen, maar het proces draait in headless mode!</value>
|
||||
</data>
|
||||
<data name="ErrorWCFAccessDenied" xml:space="preserve">
|
||||
<value>Het verzoek wordt niet in behandeling genomen omdat SteamOwnerID niet is ingesteld!</value>
|
||||
<comment>SteamOwnerID is name of bot config property, it should not be translated</comment>
|
||||
</data>
|
||||
<data name="Exiting" xml:space="preserve">
|
||||
<value>Afsluiten...</value>
|
||||
</data>
|
||||
<data name="WarningFailed" xml:space="preserve">
|
||||
<value>Mislukt!</value>
|
||||
</data>
|
||||
<data name="GlobalConfigChanged" xml:space="preserve">
|
||||
<value>Globaal configuratiebestand is aangepast!</value>
|
||||
</data>
|
||||
<data name="ErrorGlobalConfigRemoved" xml:space="preserve">
|
||||
<value>Globaal configuratiebestand is verwijderd!</value>
|
||||
</data>
|
||||
<data name="IgnoringTrade" xml:space="preserve">
|
||||
<value>Ruilaanbieding {0} wordt genegeerd</value>
|
||||
<comment>{0} will be replaced by trade number</comment>
|
||||
</data>
|
||||
<data name="LoggingIn" xml:space="preserve">
|
||||
<value>Inloggen op {0}...</value>
|
||||
<comment>{0} will be replaced by service's name</comment>
|
||||
</data>
|
||||
<data name="NoBotsAreRunning" xml:space="preserve">
|
||||
<value>Geen bots actief, afsluiten...</value>
|
||||
</data>
|
||||
<data name="RefreshingOurSession" xml:space="preserve">
|
||||
<value>Sessie wordt ververst!</value>
|
||||
</data>
|
||||
<data name="RejectingTrade" xml:space="preserve">
|
||||
<value>Ruilaanbieding {0} wordt afgekeurd</value>
|
||||
<comment>{0} will be replaced by trade number</comment>
|
||||
</data>
|
||||
<data name="Restarting" xml:space="preserve">
|
||||
<value>Herstarten...</value>
|
||||
</data>
|
||||
<data name="WarningRuntimeUnsupported" xml:space="preserve">
|
||||
<value>ASF heeft een niet ondersteunde runtime versie gedetecteerd, het programma kan mogelijk NIET correct worden uitgevoerd in de huidige omgeving. Je voert dit met eigen risico en zonder ondersteuning uit!</value>
|
||||
</data>
|
||||
<data name="RuntimeVersionComparison" xml:space="preserve">
|
||||
<value>Vereiste versie: {0} | Gevonden versie: {1}</value>
|
||||
<comment>{0} will be replaced by required version, {1} will be replaced by current version</comment>
|
||||
</data>
|
||||
<data name="RuntimeVersionOK" xml:space="preserve">
|
||||
<value>Je {0} runtime versie is OK.</value>
|
||||
<comment>{0} will be replaced by runtime name (e.g. "Mono")</comment>
|
||||
</data>
|
||||
<data name="WarningRuntimeVersionTooOld" xml:space="preserve">
|
||||
<value>Je {0} runtime versie is te oud!</value>
|
||||
<comment>{0} will be replaced by runtime name (e.g. "Mono")</comment>
|
||||
</data>
|
||||
<data name="Starting" xml:space="preserve">
|
||||
<value>Starten...</value>
|
||||
</data>
|
||||
<data name="StatusCode" xml:space="preserve">
|
||||
<value>Status code: {0}</value>
|
||||
<comment>{0} will be replaced by status code number/name</comment>
|
||||
</data>
|
||||
<data name="Success" xml:space="preserve">
|
||||
<value>Succes!</value>
|
||||
</data>
|
||||
<data name="TimeSpanDay" xml:space="preserve">
|
||||
<value>1 dag</value>
|
||||
</data>
|
||||
<data name="TimeSpanDays" xml:space="preserve">
|
||||
<value>{0} dagen</value>
|
||||
<comment>{0} will be replaced by number of days</comment>
|
||||
</data>
|
||||
<data name="TimeSpanHour" xml:space="preserve">
|
||||
<value>1 uur</value>
|
||||
</data>
|
||||
<data name="TimeSpanHours" xml:space="preserve">
|
||||
<value>{0} uren</value>
|
||||
<comment>{0} will be replaced by number of hours</comment>
|
||||
</data>
|
||||
<data name="TimeSpanMinute" xml:space="preserve">
|
||||
<value>1 minuut</value>
|
||||
</data>
|
||||
<data name="TimeSpanMinutes" xml:space="preserve">
|
||||
<value>{0} minuten</value>
|
||||
<comment>{0} will be replaced by number of minutes</comment>
|
||||
</data>
|
||||
<data name="TimeSpanSecond" xml:space="preserve">
|
||||
<value>1 seconde</value>
|
||||
</data>
|
||||
<data name="TimeSpanSeconds" xml:space="preserve">
|
||||
<value>{0} seconden</value>
|
||||
<comment>{0} will be replaced by number of seconds</comment>
|
||||
</data>
|
||||
<data name="UnlockingParentalAccount" xml:space="preserve">
|
||||
<value>Ouderaccount wordt ontgrendeld...</value>
|
||||
</data>
|
||||
<data name="UpdateCheckingNewVersion" xml:space="preserve">
|
||||
<value>Controleren op nieuwe versie...</value>
|
||||
</data>
|
||||
<data name="UpdateDownloadingNewVersion" xml:space="preserve">
|
||||
<value>Nieuwe versie wordt gedownloadt... Onder het wachten, overweeg te doneren als je het gedane werk waardeert! :)</value>
|
||||
</data>
|
||||
<data name="UpdateFinished" xml:space="preserve">
|
||||
<value>Bijwerken afgerond!</value>
|
||||
</data>
|
||||
<data name="UpdateNewVersionAvailable" xml:space="preserve">
|
||||
<value>Een nieuwe ASF-versie is beschikbaar! Overweeg om deze zelf bij te werken!</value>
|
||||
</data>
|
||||
<data name="UpdateVersionInfo" xml:space="preserve">
|
||||
<value>Lokale versie: {0} | Externe versie: {1}</value>
|
||||
<comment>{0} will be replaced by current version, {1} will be replaced by remote version</comment>
|
||||
</data>
|
||||
<data name="UserInputDeviceID" xml:space="preserve">
|
||||
<value><{0}> Vul je Device ID in (inclusief "android:"): </value>
|
||||
<comment>{0} will be replaced by bot's name. Please note that this translation should end with space</comment>
|
||||
</data>
|
||||
<data name="UserInputSteam2FA" xml:space="preserve">
|
||||
<value><{0}> Vul je 2FA code in van je Steam authenticatie app: </value>
|
||||
<comment>{0} will be replaced by bot's name. Please note that this translation should end with space</comment>
|
||||
</data>
|
||||
<data name="UserInputSteamGuard" xml:space="preserve">
|
||||
<value><{0}> Vul de SteamGuard authenticatiecode in die naar je e-mail gestuurd is: </value>
|
||||
<comment>{0} will be replaced by bot's name. Please note that this translation should end with space</comment>
|
||||
</data>
|
||||
<data name="UserInputSteamLogin" xml:space="preserve">
|
||||
<value><{0}> Vul je Steam gebruikersnaam in: </value>
|
||||
<comment>{0} will be replaced by bot's name. Please note that this translation should end with space</comment>
|
||||
</data>
|
||||
<data name="UserInputSteamParentalPIN" xml:space="preserve">
|
||||
<value><{0}> Vul je Steam ouderlijktoezichtscode in: </value>
|
||||
<comment>{0} will be replaced by bot's name. Please note that this translation should end with space</comment>
|
||||
</data>
|
||||
<data name="UserInputSteamPassword" xml:space="preserve">
|
||||
<value><{0}> Vul je Steam wachtwoord in: </value>
|
||||
<comment>{0} will be replaced by bot's name. Please note that this translation should end with space</comment>
|
||||
</data>
|
||||
<data name="UserInputUnknown" xml:space="preserve">
|
||||
<value><{0} > Voer ongedocumenteerde waarde van {1}: </value>
|
||||
<comment>{0} will be replaced by bot's name, {1} will be replaced by property name. Please note that this translation should end with space</comment>
|
||||
</data>
|
||||
<data name="UserInputWCFHost" xml:space="preserve">
|
||||
<value><{0}> Voer je WCF-host in: </value>
|
||||
<comment>{0} will be replaced by bot's name. Please note that this translation should end with space</comment>
|
||||
</data>
|
||||
<data name="WarningUnknownValuePleaseReport" xml:space="preserve">
|
||||
<value>Onbekende waarde ontvangen voor {0}, gelieven dit melden: {1}</value>
|
||||
<comment>{0} will be replaced by object's name, {1} will be replaced by value for that object</comment>
|
||||
</data>
|
||||
<data name="WarningTooManyGamesToPlay" xml:space="preserve">
|
||||
<value>Het spelen van meer dan {0} games gelijktijdig is niet mogelijk, alleen de eerste {0} games van {1} worden gebruikt!</value>
|
||||
<comment>{0} will be replaced by max number of games, {1} will be replaced by name of the configuration property</comment>
|
||||
</data>
|
||||
<data name="WarningWCFIgnoringCommand" xml:space="preserve">
|
||||
<value>WCF opdracht word genegeerd omdat --cliënt niet gespecificeerd was: {0}</value>
|
||||
<comment>{0} will be replaced by WCF command</comment>
|
||||
</data>
|
||||
<data name="ErrorWCFAddressAccessDeniedException" xml:space="preserve">
|
||||
<value>WCF service kan niet worden gestart vanwege de AddressAccessDeniedException! Als je zelf gebruik wilt maken van de WCF service van ASF, overweeg om ASF te starten als administrator of geef de juiste machtigingen!</value>
|
||||
</data>
|
||||
<data name="WCFAnswered" xml:space="preserve">
|
||||
<value>Beantwoordt aan WCF opdracht: {0} met: {1}</value>
|
||||
<comment>{0} will be replaced by WCF command, {1} will be replaced by WCF answer</comment>
|
||||
</data>
|
||||
<data name="WCFReady" xml:space="preserve">
|
||||
<value>WCF server gereed!</value>
|
||||
</data>
|
||||
<data name="WCFResponseReceived" xml:space="preserve">
|
||||
<value>WCF reactie ontvangen: {0}</value>
|
||||
<comment>{0} will be replaced by WCF response</comment>
|
||||
</data>
|
||||
<data name="WCFSendingCommand" xml:space="preserve">
|
||||
<value>Opdracht {0} verzenden naar WCF server op {1}...</value>
|
||||
<comment>{0} will be replaced by WCF command, {1} will be replaced by WCF hostname</comment>
|
||||
</data>
|
||||
<data name="WCFStarting" xml:space="preserve">
|
||||
<value>WCF server starten op {0}...</value>
|
||||
<comment>{0} will be replaced by WCF hostname</comment>
|
||||
</data>
|
||||
<data name="BotAlreadyStopped" xml:space="preserve">
|
||||
<value>Deze bot-instantie is al gestopt!</value>
|
||||
</data>
|
||||
<data name="BotNotFound" xml:space="preserve">
|
||||
<value>Kan geen bot vinden genaamd {0}!</value>
|
||||
<comment>{0} will be replaced by bot's name</comment>
|
||||
</data>
|
||||
<data name="BotsStatusOverview" xml:space="preserve">
|
||||
<value>Er zijn {0}/{1} bots actief, met in totaal {2} spellen ({3} kaarten) te gaan om te idlen.</value>
|
||||
<comment>{0} will be replaced by number of active bots, {1} will be replaced by total number of bots, {2} will be replaced by total number of games left to idle, {3} will be replaced by total number of cards left to idle</comment>
|
||||
</data>
|
||||
<data name="BotStatusIdling" xml:space="preserve">
|
||||
<value>Bot {0} is spel {1} aan het idlen ({2}, {3} kaarten te gaan) van een totaal van {4} spellen ({5} kaarten) nog te verzamelen (~{6} resterende).</value>
|
||||
<comment>{0} will be replaced by bot's name, {1} will be replaced by game's appID (number), {2} will be replaced by game's name, {3} will be replaced by number of cards left to idle, {4} will be replaced by total number of games to idle, {5} will be replaced by total number of cards to idle, {6} will be replaced by translated TimeSpan string built from TimeSpan* translation parts</comment>
|
||||
</data>
|
||||
<data name="BotStatusIdlingList" xml:space="preserve">
|
||||
<value>Bot {0} is spellen aan het idlen: {1} uit een totaal van {2} spellen ({3} kaarten) nog te idlen (~{4} remaining).</value>
|
||||
<comment>{0} will be replaced by bot's name, {1} will be replaced by list of the games (appIDs, numbers), {2} will be replaced by total number of games to idle, {3} will be replaced by total number of cards to idle, {4} will be replaced by translated TimeSpan string built from TimeSpan* translation parts</comment>
|
||||
</data>
|
||||
<data name="CheckingFirstBadgePage" xml:space="preserve">
|
||||
<value>Eerste badge pagina controleren...</value>
|
||||
</data>
|
||||
<data name="CheckingOtherBadgePages" xml:space="preserve">
|
||||
<value>Andere badge pagina's controleren...</value>
|
||||
</data>
|
||||
<data name="ChosenFarmingAlgorithm" xml:space="preserve">
|
||||
<value>Gekozen idling algoritme: {0}</value>
|
||||
<comment>{0} will be replaced by the name of chosen idling algorithm</comment>
|
||||
</data>
|
||||
<data name="Done" xml:space="preserve">
|
||||
<value>Klaar!</value>
|
||||
</data>
|
||||
<data name="GamesToIdle" xml:space="preserve">
|
||||
<value>We hebben een totaal van {0} spellen ({1} kaarten) nog te verzamelen (~{2} resterende)...</value>
|
||||
<comment>{0} will be replaced by number of games, {1} will be replaced by number of cards, {2} will be replaced by translated TimeSpan string built from TimeSpan* translation parts</comment>
|
||||
</data>
|
||||
<data name="IdlingFinished" xml:space="preserve">
|
||||
<value>Idling klaar!</value>
|
||||
</data>
|
||||
<data name="IdlingFinishedForGame" xml:space="preserve">
|
||||
<value>Klaar met idlen: {0} ({1}) na {2} speeltijd!</value>
|
||||
<comment>{0} will be replaced by game's appID (number), {1} will be replaced by game's name, {2} will be replaced by translated TimeSpan string built from TimeSpan* translation parts</comment>
|
||||
</data>
|
||||
<data name="IdlingFinishedForGames" xml:space="preserve">
|
||||
<value>Het idlen is klaar voor de games: {0}</value>
|
||||
<comment>{0} will be replaced by list of the games (appIDs, numbers), separated by a comma</comment>
|
||||
</data>
|
||||
<data name="IdlingStatusForGame" xml:space="preserve">
|
||||
<value>Idling status voor {0} {1}): {2} kaarten resterend</value>
|
||||
<comment>{0} will be replaced by game's appID (number), {1} will be replaced by game's name, {2} will be replaced by number of cards left to idle</comment>
|
||||
</data>
|
||||
<data name="IdlingStopped" xml:space="preserve">
|
||||
<value>Het idlen is gestopt!</value>
|
||||
</data>
|
||||
<data name="IgnoredStickyPauseEnabled" xml:space="preserve">
|
||||
<value>Dit verzoek wordt genegeerd. Permanente pauze staat aan!</value>
|
||||
</data>
|
||||
<data name="NothingToIdle" xml:space="preserve">
|
||||
<value>We hebben niks om te idlen op dit account!</value>
|
||||
</data>
|
||||
<data name="NowIdling" xml:space="preserve">
|
||||
<value>Nu aan het idlen: {0} ({1})</value>
|
||||
<comment>{0} will be replaced by game's appID (number), {1} will be replaced by game's name</comment>
|
||||
</data>
|
||||
<data name="NowIdlingList" xml:space="preserve">
|
||||
<value>Nu aan het idlen: {0}</value>
|
||||
<comment>{0} will be replaced by list of the games (appIDs, numbers), separated by a comma</comment>
|
||||
</data>
|
||||
<data name="PlayingNotAvailable" xml:space="preserve">
|
||||
<value>Spelen is op dit moment niet mogelijk, we proberen het later nog een keer!</value>
|
||||
</data>
|
||||
<data name="StillIdling" xml:space="preserve">
|
||||
<value>Nog steeds aan het idlen: {0} ({1})</value>
|
||||
<comment>{0} will be replaced by game's appID (number), {1} will be replaced by game's name</comment>
|
||||
</data>
|
||||
<data name="StillIdlingList" xml:space="preserve">
|
||||
<value>Nog steeds aan het idlen: {0}</value>
|
||||
<comment>{0} will be replaced by list of the games (appIDs, numbers), separated by a comma</comment>
|
||||
</data>
|
||||
<data name="StoppedIdling" xml:space="preserve">
|
||||
<value>Gestopt met idlen: {0} ({1})</value>
|
||||
<comment>{0} will be replaced by game's appID (number), {1} will be replaced by game's name</comment>
|
||||
</data>
|
||||
<data name="StoppedIdlingList" xml:space="preserve">
|
||||
<value>Gestopt met idlen: {0}</value>
|
||||
<comment>{0} will be replaced by list of the games (appIDs, numbers), separated by a comma</comment>
|
||||
</data>
|
||||
<data name="UnknownCommand" xml:space="preserve">
|
||||
<value>Onbekende opdracht!</value>
|
||||
</data>
|
||||
<data name="WarningCouldNotCheckBadges" xml:space="preserve">
|
||||
<value>Kan de badges informatie niet verkrijgen, we zullen het later nog een keer proberen!</value>
|
||||
</data>
|
||||
<data name="WarningCouldNotCheckCardsStatus" xml:space="preserve">
|
||||
<value>Kaart status kan niet worden gecontroleerd voor {0} ({1}), wij zullen het later nogmaals proberen!</value>
|
||||
<comment>{0} will be replaced by game's appID (number), {1} will be replaced by game's name</comment>
|
||||
</data>
|
||||
<data name="BotAcceptingGift" xml:space="preserve">
|
||||
<value>Cadeau accepteren: {0}...</value>
|
||||
<comment>{0} will be replaced by giftID (number)</comment>
|
||||
</data>
|
||||
<data name="BotAccountLimited" xml:space="preserve">
|
||||
<value>Dit account is beperkt, het idling proces is permanent onbeschikbaar totdat de beperking is verwijderd!</value>
|
||||
</data>
|
||||
<data name="BotAddLicenseResponse" xml:space="preserve">
|
||||
<value><{0}> SpelID: {1} | Status: {2}</value>
|
||||
<comment>{0} will be replaced by bot's name, {1} will be replaced by gameID (number), {2} will be replaced by status string</comment>
|
||||
</data>
|
||||
<data name="BotAddLicenseResponseWithItems" xml:space="preserve">
|
||||
<value><{0}> SpelID: {1} | Status: {2} | Items: {3}</value>
|
||||
<comment>{0} will be replaced by bot's name, {1} will be replaced by gameID (number), {2} will be replaced by status string, {3} will be replaced by list of granted appIDs (numbers), separated by a comma</comment>
|
||||
</data>
|
||||
<data name="BotAlreadyRunning" xml:space="preserve">
|
||||
<value>Die bot-instantie is al bezig!</value>
|
||||
<comment>{0} will be replaced by bot's name</comment>
|
||||
</data>
|
||||
<data name="BotAuthenticatorConverting" xml:space="preserve">
|
||||
<value>.maFile omzetten naar ASF formaat...</value>
|
||||
</data>
|
||||
<data name="BotAuthenticatorImportFinished" xml:space="preserve">
|
||||
<value>Met succes de mobiele authenticator geimporteerd!</value>
|
||||
</data>
|
||||
<data name="BotAuthenticatorInvalidDeviceID" xml:space="preserve">
|
||||
<value>Je DeviceID is incorrect of bestaat niet!</value>
|
||||
</data>
|
||||
<data name="BotAuthenticatorToken" xml:space="preserve">
|
||||
<value>2FA Token: {0}</value>
|
||||
<comment>{0} will be replaced by generated 2FA token (string)</comment>
|
||||
</data>
|
||||
<data name="BotAutomaticIdlingNowPaused" xml:space="preserve">
|
||||
<value>Automatisch idling is nu gepauzeerd!</value>
|
||||
</data>
|
||||
<data name="BotAutomaticIdlingNowResumed" xml:space="preserve">
|
||||
<value>Automatisch idling is nu hervat!</value>
|
||||
</data>
|
||||
<data name="BotAutomaticIdlingPausedAlready" xml:space="preserve">
|
||||
<value>Automatisch idling is al gepauzeerd!</value>
|
||||
</data>
|
||||
<data name="BotAutomaticIdlingPausedWithCountdown" xml:space="preserve">
|
||||
<value>Automatisch idling is nu gepauzeerd! Je hebt {0} minuten om een spel te starten.</value>
|
||||
<comment>{0} will be replaced by number of minutes</comment>
|
||||
</data>
|
||||
<data name="BotAutomaticIdlingResumedAlready" xml:space="preserve">
|
||||
<value>Automatisch idling is al hervat!</value>
|
||||
</data>
|
||||
<data name="BotConnected" xml:space="preserve">
|
||||
<value>Verbonden met Steam!</value>
|
||||
</data>
|
||||
<data name="BotDisconnected" xml:space="preserve">
|
||||
<value>Verbinding met Steam verbroken!</value>
|
||||
</data>
|
||||
<data name="BotDisconnecting" xml:space="preserve">
|
||||
<value>Verbinding verbreken...</value>
|
||||
</data>
|
||||
<data name="BotEncryptedPassword" xml:space="preserve">
|
||||
<value>[{0}] Wachtwoord: {1}</value>
|
||||
<comment>{0} will be replaced by password encryption method (string), {1} will be replaced by encrypted password using that method (string)</comment>
|
||||
</data>
|
||||
<data name="BotInstanceNotStartingBecauseDisabled" xml:space="preserve">
|
||||
<value>Deze bot wordt niet gestart omdat hij uitgeschakeld is in het configuratie bestand!</value>
|
||||
</data>
|
||||
<data name="BotInvalidAuthenticatorDuringLogin" xml:space="preserve">
|
||||
<value>TwoFactorCodeMisMatch foutmelding {0} ontvangen, dit betekent bijna altijd de verkeerde ASF 2FA login informatie, afbreken!</value>
|
||||
<comment>{0} will be replaced by maximum allowed number of failed 2FA attempts</comment>
|
||||
</data>
|
||||
<data name="BotLoggedOff" xml:space="preserve">
|
||||
<value>Uitgelogd op Steam: {0}</value>
|
||||
<comment>{0} will be replaced by logging off reason (string)</comment>
|
||||
</data>
|
||||
<data name="BotLoggedOn" xml:space="preserve">
|
||||
<value>Succesvol ingelogd!</value>
|
||||
</data>
|
||||
<data name="BotLoggingIn" xml:space="preserve">
|
||||
<value>Inloggen...</value>
|
||||
</data>
|
||||
<data name="BotLogonSessionReplaced" xml:space="preserve">
|
||||
<value>Het lijkt erop dat dit account wordt gebruikt in een ander ASF instantie, met onbepaald gedrag, weigeren om het draaiende te houden!</value>
|
||||
</data>
|
||||
<data name="BotLootingFailed" xml:space="preserve">
|
||||
<value>Handelsvoorstel mislukt!</value>
|
||||
</data>
|
||||
<data name="BotLootingMasterNotDefined" xml:space="preserve">
|
||||
<value>Trade kon niet verzonden worden, omdat SteamMasterID niet is ingesteld!</value>
|
||||
<comment>SteamMasterID is name of bot config property, it should not be translated</comment>
|
||||
</data>
|
||||
<data name="BotLootingNoLootableTypes" xml:space="preserve">
|
||||
<value>Je hebt geen lootable types ingesteld!</value>
|
||||
</data>
|
||||
<data name="BotLootingNowDisabled" xml:space="preserve">
|
||||
<value>Looting is nu uitgeschakeld!</value>
|
||||
</data>
|
||||
<data name="BotLootingNowEnabled" xml:space="preserve">
|
||||
<value>Looting is nu ingeschakeld!</value>
|
||||
</data>
|
||||
<data name="BotLootingSuccess" xml:space="preserve">
|
||||
<value>Trade verzoek succesvol verzonden!</value>
|
||||
</data>
|
||||
<data name="BotLootingTemporarilyDisabled" xml:space="preserve">
|
||||
<value>Looting is tijdelijk uitgeschakeld!</value>
|
||||
</data>
|
||||
<data name="BotLootingYourself" xml:space="preserve">
|
||||
<value>Je kan je zelf niet looten!</value>
|
||||
</data>
|
||||
<data name="BotNoASFAuthenticator" xml:space="preserve">
|
||||
<value>Die bot heeft ASF 2FA nog niet ingeschakeld! Ben je vergeten om je authenticator te importeren als ASF 2FA?</value>
|
||||
</data>
|
||||
<data name="BotNotConnected" xml:space="preserve">
|
||||
<value>Deze bot instatie is niet verbonden!</value>
|
||||
<comment>{0} will be replaced by bot's name</comment>
|
||||
</data>
|
||||
<data name="BotNotOwnedYet" xml:space="preserve">
|
||||
<value><{0}> Nog niet in bezit: {1}</value>
|
||||
<comment>{0} will be replaced by bot's name, {1} will be replaced by query (string)</comment>
|
||||
</data>
|
||||
<data name="BotOwnedAlready" xml:space="preserve">
|
||||
<value><{0}> In bezit: {1} | {2}</value>
|
||||
<comment>{0} will be replaced by bot's name, {1} will be replaced by game's appID (number), {2} will be replaced by game's name</comment>
|
||||
</data>
|
||||
<data name="BotRateLimitExceeded" xml:space="preserve">
|
||||
<value>Limiet overschreden, we zullen het over {0} minuten opnieuw proberen...</value>
|
||||
<comment>{0} will be replaced by number of minutes</comment>
|
||||
</data>
|
||||
<data name="BotReconnecting" xml:space="preserve">
|
||||
<value>Opnieuw verbinden...</value>
|
||||
</data>
|
||||
<data name="BotRedeemResponse" xml:space="preserve">
|
||||
<value><{0}> Cd-key: {1} | Status: {2}</value>
|
||||
<comment>{0} will be replaced by bot's name, {1} will be replaced by cd-key (string), {2} will be replaced by status string</comment>
|
||||
</data>
|
||||
<data name="BotRedeemResponseWithItems" xml:space="preserve">
|
||||
<value><{0}> Cd-key: {1} | Status: {2} | Items: {3}</value>
|
||||
<comment>{0} will be replaced by bot's name, {1} will be replaced by cd-key (string), {2} will be replaced by status string, {3} will be replaced by list of key-value pairs, separated by a comma</comment>
|
||||
</data>
|
||||
<data name="BotRemovedExpiredLoginKey" xml:space="preserve">
|
||||
<value>Verlopen login sleutel verwijderd!</value>
|
||||
</data>
|
||||
<data name="BotsStatusNotIdling" xml:space="preserve">
|
||||
<value>Bot {0} is niks aan het idlen.</value>
|
||||
<comment>{0} will be replaced by bot's name</comment>
|
||||
</data>
|
||||
<data name="BotStatusLimited" xml:space="preserve">
|
||||
<value>Bot {0} is beperkt en kan geen kaarten laten vallen via idling.</value>
|
||||
<comment>{0} will be replaced by bot's name</comment>
|
||||
</data>
|
||||
<data name="BotStatusNotConnected" xml:space="preserve">
|
||||
<value>Bot {0} is niet verbonden.</value>
|
||||
<comment>{0} will be replaced by bot's name</comment>
|
||||
</data>
|
||||
<data name="BotStatusNotRunning" xml:space="preserve">
|
||||
<value>Bot {0} is niet actief.</value>
|
||||
<comment>{0} will be replaced by bot's name</comment>
|
||||
</data>
|
||||
<data name="BotStatusPaused" xml:space="preserve">
|
||||
<value>Bot {0} is gepauzeerd of uitgevoerd in de handmatige modus.</value>
|
||||
<comment>{0} will be replaced by bot's name</comment>
|
||||
</data>
|
||||
<data name="BotStatusPlayingNotAvailable" xml:space="preserve">
|
||||
<value>Bot {0} wordt momenteel gebruikt.</value>
|
||||
<comment>{0} will be replaced by bot's name</comment>
|
||||
</data>
|
||||
<data name="BotUnableToConnect" xml:space="preserve">
|
||||
<value>Niet in staat om op Steam in te loggen: {0}</value>
|
||||
<comment>{0} will be replaced by failure reason (string)</comment>
|
||||
</data>
|
||||
<data name="BotUnableToLogin" xml:space="preserve">
|
||||
<value>Niet in staat om op Steam inteloggen: {0}/{1}</value>
|
||||
<comment>{0} will be replaced by failure reason (string), {1} will be replaced by extended failure reason (string)</comment>
|
||||
</data>
|
||||
<data name="ErrorIsEmpty" xml:space="preserve">
|
||||
<value>{0} is leeg!</value>
|
||||
<comment>{0} will be replaced by object's name</comment>
|
||||
</data>
|
||||
<data name="UnusedKeys" xml:space="preserve">
|
||||
<value>Ongebruikte cd-keys: {0}</value>
|
||||
<comment>{0} will be replaced by list of cd-keys (strings), separated by a comma</comment>
|
||||
</data>
|
||||
<data name="WarningFailedWithError" xml:space="preserve">
|
||||
<value>Mislukt door de fout: {0}</value>
|
||||
<comment>{0} will be replaced by failure reason (string)</comment>
|
||||
</data>
|
||||
<data name="BotConnectionLost" xml:space="preserve">
|
||||
<value>Verbinding met het Steam Netwerk verloren, opnieuw verbinden...</value>
|
||||
</data>
|
||||
<data name="BotAccountFree" xml:space="preserve">
|
||||
<value>Account wordt niet meer gebruikt, idle proces hervat!</value>
|
||||
</data>
|
||||
<data name="BotAccountOccupied" xml:space="preserve">
|
||||
<value>Account wordt momenteel gebruikt, ASF zal verder gaan met het idle-proces wanneer de account weer vrij is...</value>
|
||||
</data>
|
||||
<data name="BotAutomaticIdlingPauseTimeout" xml:space="preserve">
|
||||
<value>Gedeelde bibliotheek is niet ingebruik genomen in de gegeven tijd periode, idling proces hervat!</value>
|
||||
</data>
|
||||
<data name="BotConnecting" xml:space="preserve">
|
||||
<value>Verbinden...</value>
|
||||
</data>
|
||||
<data name="BotHeartBeatFailed" xml:space="preserve">
|
||||
<value>Poging om de verbinding van de client te verbreken mislukt, x deze bot instantie!</value>
|
||||
</data>
|
||||
<data name="BotSteamDirectoryInitializationFailed" xml:space="preserve">
|
||||
<value>Kan SteamDirectory niet initialiseren, verbinden met Steam Netwerk kan langer duren dan normaal!</value>
|
||||
</data>
|
||||
<data name="BotStopping" xml:space="preserve">
|
||||
<value>Stoppen...</value>
|
||||
</data>
|
||||
<data name="ErrorBotConfigInvalid" xml:space="preserve">
|
||||
<value>Je bot configuratie is ongeldig, controleer de inhoud van {0} en probeer het opnieuw!</value>
|
||||
<comment>{0} will be replaced by file's path</comment>
|
||||
</data>
|
||||
<data name="ErrorDatabaseInvalid" xml:space="preserve">
|
||||
<value>Blijvende database kan niet worden geladen, als het probleem aanhoudt, verwijder dan {0} om de database opnieuw te maken!</value>
|
||||
<comment>{0} will be replaced by file's path</comment>
|
||||
</data>
|
||||
<data name="Initializing" xml:space="preserve">
|
||||
<value>{0} Initialiseren...</value>
|
||||
<comment>{0} will be replaced by service name that is being initialized</comment>
|
||||
</data>
|
||||
<data name="WarningPrivacyPolicy" xml:space="preserve">
|
||||
<value>Raadpleeg onze privacy beleid op de ASF Wiki als je bezorgd bent over wat ASF in feite doet!</value>
|
||||
</data>
|
||||
<data name="Welcome" xml:space="preserve">
|
||||
<value>Het lijkt erop dat je het programma voor het eerst opstart, welkom!</value>
|
||||
</data>
|
||||
<data name="ErrorInvalidCurrentCulture" xml:space="preserve">
|
||||
<value>De door jou geleverde CurrentCulture is incorrect, ASF zal de standaard blijven gebruiken!</value>
|
||||
</data>
|
||||
<data name="TranslationIncomplete" xml:space="preserve">
|
||||
<value>ASF probeert de {0} taal te gebruiken, maar het vertalen in deze taal was tot {1} compleet. Misschien kan je ons helpen om ASF te vertalen in jouw taal?</value>
|
||||
<comment>{0} will be replaced by culture code, such as "en-US", {1} will be replaced by completeness percentage, such as "78.5%"</comment>
|
||||
</data>
|
||||
<data name="IdlingGameNotReleasedYet" xml:space="preserve">
|
||||
<value>Idling {0} ({1}) is tijdelijk uitgeschakeld, aangezien dat spel nog niet was uitgegeven.</value>
|
||||
<comment>{0} will be replaced by game's appID (number), {1} will be replaced by game's name</comment>
|
||||
</data>
|
||||
</root>
|
||||
@@ -184,13 +184,13 @@ StackTrace:
|
||||
<value>Controle voor de laatste versie is mislukt!</value>
|
||||
</data>
|
||||
<data name="ErrorUpdateNoAssetForThisBinary" xml:space="preserve">
|
||||
<value>Kon niet verdergaan met update omdat er geen bestand bestaat dat gerelateerd is aan de momenteel actieve binary! Controleer of de ASF Binary de juiste naam heeft!</value>
|
||||
<value>Kon niet verdergaan met updaten omdat er geen bestand bestaat dat gerelateerd is aan de momenteel actieve binary! Controleer of de ASF binary de juiste naam heeft!</value>
|
||||
</data>
|
||||
<data name="ErrorUpdateNoAssets" xml:space="preserve">
|
||||
<value>Kan niet verdergaan met update omdat deze versie niet alle bestanden omvat!</value>
|
||||
</data>
|
||||
<data name="ErrorUserInputRunningInHeadlessMode" xml:space="preserve">
|
||||
<value>Aanvraag voor gebruikersinvoer gekregen, maar het proces draait momenteel in headless mode!</value>
|
||||
<value>Aanvraag voor gebruikersinvoer ontvangen, maar het proces draait in headless mode!</value>
|
||||
</data>
|
||||
<data name="ErrorWCFAccessDenied" xml:space="preserve">
|
||||
<value>Het verzoek wordt niet in behandeling genomen omdat SteamOwnerID niet is ingesteld!</value>
|
||||
|
||||
@@ -46,10 +46,21 @@ namespace ArchiSteamFarm {
|
||||
|
||||
private static short? SteamTimeDifference;
|
||||
|
||||
internal bool HasCorrectDeviceID => !string.IsNullOrEmpty(DeviceID) && !DeviceID.Equals("ERROR"); // "ERROR" is being used by SteamDesktopAuthenticator
|
||||
// "ERROR" is being used by SteamDesktopAuthenticator
|
||||
internal bool HasCorrectDeviceID => !string.IsNullOrEmpty(DeviceID) && !DeviceID.Equals("ERROR");
|
||||
|
||||
private readonly SemaphoreSlim ConfirmationsSemaphore = new SemaphoreSlim(1);
|
||||
|
||||
#pragma warning disable 649
|
||||
[JsonProperty(PropertyName = "identity_secret", Required = Required.Always)]
|
||||
private readonly string IdentitySecret;
|
||||
#pragma warning restore 649
|
||||
|
||||
#pragma warning disable 649
|
||||
[JsonProperty(PropertyName = "shared_secret", Required = Required.Always)]
|
||||
private readonly string SharedSecret;
|
||||
#pragma warning restore 649
|
||||
|
||||
private Bot Bot;
|
||||
|
||||
[JsonProperty(PropertyName = "device_id")]
|
||||
@@ -251,7 +262,15 @@ namespace ArchiSteamFarm {
|
||||
return null;
|
||||
}
|
||||
|
||||
byte[] identitySecret = Convert.FromBase64String(IdentitySecret);
|
||||
byte[] identitySecret;
|
||||
|
||||
try {
|
||||
identitySecret = Convert.FromBase64String(IdentitySecret);
|
||||
} catch (FormatException e) {
|
||||
Bot.ArchiLogger.LogGenericException(e);
|
||||
Bot.ArchiLogger.LogGenericError(string.Format(Strings.ErrorIsInvalid, nameof(IdentitySecret)));
|
||||
return null;
|
||||
}
|
||||
|
||||
byte bufferSize = 8;
|
||||
if (!string.IsNullOrEmpty(tag)) {
|
||||
@@ -284,7 +303,15 @@ namespace ArchiSteamFarm {
|
||||
return null;
|
||||
}
|
||||
|
||||
byte[] sharedSecret = Convert.FromBase64String(SharedSecret);
|
||||
byte[] sharedSecret;
|
||||
|
||||
try {
|
||||
sharedSecret = Convert.FromBase64String(SharedSecret);
|
||||
} catch (FormatException e) {
|
||||
Bot.ArchiLogger.LogGenericException(e);
|
||||
Bot.ArchiLogger.LogGenericError(string.Format(Strings.ErrorIsInvalid, nameof(SharedSecret)));
|
||||
return null;
|
||||
}
|
||||
|
||||
byte[] timeArray = BitConverter.GetBytes((long) time / CodeInterval);
|
||||
if (BitConverter.IsLittleEndian) {
|
||||
@@ -357,13 +384,5 @@ namespace ArchiSteamFarm {
|
||||
Type = type;
|
||||
}
|
||||
}
|
||||
|
||||
#pragma warning disable 649
|
||||
[JsonProperty(PropertyName = "shared_secret", Required = Required.Always)]
|
||||
private readonly string SharedSecret;
|
||||
|
||||
[JsonProperty(PropertyName = "identity_secret", Required = Required.Always)]
|
||||
private readonly string IdentitySecret;
|
||||
#pragma warning restore 649
|
||||
}
|
||||
}
|
||||
69
ArchiSteamFarm/OS.cs
Normal file
69
ArchiSteamFarm/OS.cs
Normal file
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
_ _ _ ____ _ _____
|
||||
/ \ _ __ ___ | |__ (_)/ ___| | |_ ___ __ _ _ __ ___ | ___|__ _ _ __ _ __ ___
|
||||
/ _ \ | '__|/ __|| '_ \ | |\___ \ | __|/ _ \ / _` || '_ ` _ \ | |_ / _` || '__|| '_ ` _ \
|
||||
/ ___ \ | | | (__ | | | || | ___) || |_| __/| (_| || | | | | || _|| (_| || | | | | | | |
|
||||
/_/ \_\|_| \___||_| |_||_||____/ \__|\___| \__,_||_| |_| |_||_| \__,_||_| |_| |_| |_|
|
||||
|
||||
Copyright 2015-2017 Łukasz "JustArchi" Domeradzki
|
||||
Contact: JustArchi@JustArchi.net
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using ArchiSteamFarm.Localization;
|
||||
|
||||
namespace ArchiSteamFarm {
|
||||
internal static class OS {
|
||||
private static readonly PlatformID PlatformID = Environment.OSVersion.Platform;
|
||||
|
||||
internal static void Init() {
|
||||
switch (PlatformID) {
|
||||
case PlatformID.Win32NT:
|
||||
case PlatformID.Win32S:
|
||||
case PlatformID.Win32Windows:
|
||||
case PlatformID.WinCE:
|
||||
KeepWindowsSystemActive();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private static void KeepWindowsSystemActive() {
|
||||
// This function calls unmanaged API in order to tell Windows OS that it should not enter sleep state while the program is running
|
||||
// If user wishes to enter sleep mode, then he should use ShutdownOnFarmingFinished or manage ASF process with third-party tool or script
|
||||
// More info: https://msdn.microsoft.com/library/windows/desktop/aa373208(v=vs.85).aspx
|
||||
EExecutionState result = SetThreadExecutionState(EExecutionState.Continuous | EExecutionState.AwayModeRequired | EExecutionState.SystemRequired);
|
||||
|
||||
// SetThreadExecutionState() returns NULL on failure, which is mapped to 0 (EExecutionState.Error) in our case
|
||||
if (result == EExecutionState.Error) {
|
||||
ASF.ArchiLogger.LogGenericError(string.Format(Strings.WarningFailedWithError, result));
|
||||
}
|
||||
}
|
||||
|
||||
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
|
||||
private static extern EExecutionState SetThreadExecutionState(EExecutionState executionState);
|
||||
|
||||
[Flags]
|
||||
private enum EExecutionState : uint {
|
||||
Error = 0,
|
||||
SystemRequired = 0x00000001,
|
||||
// DisplayRequired = 0x00000002,
|
||||
// UserPresent = 0x00000004,
|
||||
AwayModeRequired = 0x00000040,
|
||||
Continuous = 0x80000000
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -130,51 +130,28 @@ namespace ArchiSteamFarm {
|
||||
}
|
||||
|
||||
private static async Task Init(string[] args) {
|
||||
// We must register our logging target as soon as possible
|
||||
Target.Register<SteamTarget>("Steam");
|
||||
await InitCore(args).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
private static async Task InitCore(string[] args) {
|
||||
AppDomain.CurrentDomain.UnhandledException += UnhandledExceptionHandler;
|
||||
TaskScheduler.UnobservedTaskException += UnobservedTaskExceptionHandler;
|
||||
|
||||
string homeDirectory = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);
|
||||
if (!string.IsNullOrEmpty(homeDirectory)) {
|
||||
Directory.SetCurrentDirectory(homeDirectory);
|
||||
// We must register our logging target as soon as possible
|
||||
Target.Register<SteamTarget>("Steam");
|
||||
|
||||
// Allow loading configs from source tree if it's a debug build
|
||||
if (Debugging.IsDebugBuild) {
|
||||
// Common structure is bin/(x64/)Debug/ArchiSteamFarm.exe, so we allow up to 4 directories up
|
||||
for (byte i = 0; i < 4; i++) {
|
||||
Directory.SetCurrentDirectory("..");
|
||||
if (Directory.Exists(SharedInfo.ConfigDirectory)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
InitCore(args);
|
||||
await InitASF(args).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
// If config directory doesn't exist after our adjustment, abort all of that
|
||||
if (!Directory.Exists(SharedInfo.ConfigDirectory)) {
|
||||
Directory.SetCurrentDirectory(homeDirectory);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Parse pre-init args
|
||||
if (args != null) {
|
||||
ParsePreInitArgs(args);
|
||||
}
|
||||
|
||||
Logging.InitLoggers();
|
||||
private static async Task InitASF(string[] args) {
|
||||
ASF.ArchiLogger.LogGenericInfo("ASF V" + SharedInfo.Version);
|
||||
|
||||
await InitServices().ConfigureAwait(false);
|
||||
await InitGlobalConfigAndLanguage().ConfigureAwait(false);
|
||||
|
||||
if (!Runtime.IsRuntimeSupported) {
|
||||
ASF.ArchiLogger.LogGenericError(Strings.WarningRuntimeUnsupported);
|
||||
await Task.Delay(10 * 1000).ConfigureAwait(false);
|
||||
await Task.Delay(60 * 1000).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
await InitGlobalDatabaseAndServices().ConfigureAwait(false);
|
||||
|
||||
// If debugging is on, we prepare debug directory prior to running
|
||||
if (GlobalConfig.Debug) {
|
||||
if (Directory.Exists(SharedInfo.DebugDirectory)) {
|
||||
@@ -207,7 +184,37 @@ namespace ArchiSteamFarm {
|
||||
ASF.InitFileWatcher();
|
||||
}
|
||||
|
||||
private static async Task InitServices() {
|
||||
private static void InitCore(string[] args) {
|
||||
string homeDirectory = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);
|
||||
if (!string.IsNullOrEmpty(homeDirectory)) {
|
||||
Directory.SetCurrentDirectory(homeDirectory);
|
||||
|
||||
// Allow loading configs from source tree if it's a debug build
|
||||
if (Debugging.IsDebugBuild) {
|
||||
// Common structure is bin/(x64/)Debug/ArchiSteamFarm.exe, so we allow up to 4 directories up
|
||||
for (byte i = 0; i < 4; i++) {
|
||||
Directory.SetCurrentDirectory("..");
|
||||
if (Directory.Exists(SharedInfo.ConfigDirectory)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// If config directory doesn't exist after our adjustment, abort all of that
|
||||
if (!Directory.Exists(SharedInfo.ConfigDirectory)) {
|
||||
Directory.SetCurrentDirectory(homeDirectory);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Parse pre-init args
|
||||
if (args != null) {
|
||||
ParsePreInitArgs(args);
|
||||
}
|
||||
|
||||
Logging.InitLoggers();
|
||||
}
|
||||
|
||||
private static async Task InitGlobalConfigAndLanguage() {
|
||||
string globalConfigFile = Path.Combine(SharedInfo.ConfigDirectory, SharedInfo.GlobalConfigFileName);
|
||||
|
||||
GlobalConfig = GlobalConfig.Load(globalConfigFile);
|
||||
@@ -228,23 +235,29 @@ namespace ArchiSteamFarm {
|
||||
}
|
||||
}
|
||||
|
||||
int defaultResourceSetCount = 0;
|
||||
ushort defaultResourceSetCount = 0;
|
||||
ResourceSet defaultResourceSet = Strings.ResourceManager.GetResourceSet(CultureInfo.GetCultureInfo("en-US"), true, true);
|
||||
if (defaultResourceSet != null) {
|
||||
defaultResourceSetCount = defaultResourceSet.Cast<object>().Count();
|
||||
defaultResourceSetCount = (ushort) defaultResourceSet.Cast<object>().Count();
|
||||
}
|
||||
|
||||
int currentResourceSetCount = 0;
|
||||
if (defaultResourceSetCount == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
ushort currentResourceSetCount = 0;
|
||||
ResourceSet currentResourceSet = Strings.ResourceManager.GetResourceSet(CultureInfo.CurrentCulture, true, false);
|
||||
if (currentResourceSet != null) {
|
||||
currentResourceSetCount = currentResourceSet.Cast<object>().Count();
|
||||
currentResourceSetCount = (ushort) currentResourceSet.Cast<object>().Count();
|
||||
}
|
||||
|
||||
if (currentResourceSetCount < defaultResourceSetCount) {
|
||||
float translationCompleteness = currentResourceSetCount / (float) defaultResourceSetCount;
|
||||
ASF.ArchiLogger.LogGenericInfo(string.Format(Strings.TranslationIncomplete, CultureInfo.CurrentCulture.Name, translationCompleteness.ToString("P1")));
|
||||
}
|
||||
}
|
||||
|
||||
private static async Task InitGlobalDatabaseAndServices() {
|
||||
string globalDatabaseFile = Path.Combine(SharedInfo.ConfigDirectory, SharedInfo.GlobalDatabaseFileName);
|
||||
|
||||
if (!File.Exists(globalDatabaseFile)) {
|
||||
@@ -262,8 +275,9 @@ namespace ArchiSteamFarm {
|
||||
}
|
||||
|
||||
ArchiWebHandler.Init();
|
||||
WebBrowser.Init();
|
||||
OS.Init();
|
||||
WCF.Init();
|
||||
WebBrowser.Init();
|
||||
|
||||
WebBrowser = new WebBrowser(ASF.ArchiLogger);
|
||||
}
|
||||
|
||||
@@ -44,7 +44,7 @@ namespace ArchiSteamFarm {
|
||||
internal const string ServiceDescription = "ASF is an application that allows you to farm steam cards using multiple steam accounts simultaneously.";
|
||||
internal const string ServiceName = "ArchiSteamFarm";
|
||||
internal const string StatisticsServer = "asf.justarchi.net";
|
||||
internal const string VersionNumber = "2.2.2.3";
|
||||
internal const string VersionNumber = "2.2.2.5";
|
||||
|
||||
internal static readonly Version Version = Assembly.GetEntryAssembly().GetName().Version;
|
||||
}
|
||||
|
||||
@@ -24,14 +24,16 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using ArchiSteamFarm.JSON;
|
||||
using SteamKit2;
|
||||
|
||||
namespace ArchiSteamFarm {
|
||||
internal sealed class Statistics : IDisposable {
|
||||
private const byte MinHeartBeatTTL = 5; // Minimum amount of minutes we must wait before sending next HeartBeat
|
||||
private const byte MinHeartBeatTTL = 10; // Minimum amount of minutes we must wait before sending next HeartBeat
|
||||
|
||||
private static readonly SemaphoreSlim InitializationSemaphore = new SemaphoreSlim(1);
|
||||
|
||||
@@ -85,6 +87,7 @@ namespace ArchiSteamFarm {
|
||||
|
||||
internal async Task OnLoggedOn() => await Bot.ArchiWebHandler.JoinGroup(SharedInfo.ASFGroupSteamID).ConfigureAwait(false);
|
||||
|
||||
[SuppressMessage("ReSharper", "FunctionComplexityOverflow")]
|
||||
internal async Task OnPersonaState(SteamFriends.PersonaStateCallback callback) {
|
||||
if (callback == null) {
|
||||
ASF.ArchiLogger.LogNullError(nameof(callback));
|
||||
@@ -92,17 +95,17 @@ namespace ArchiSteamFarm {
|
||||
}
|
||||
|
||||
// Don't announce if we don't meet conditions
|
||||
if (!Bot.HasMobileAuthenticator || !Bot.BotConfig.TradingPreferences.HasFlag(BotConfig.ETradingPreferences.SteamTradeMatcher) || !await Bot.ArchiWebHandler.HasValidApiKey().ConfigureAwait(false)) {
|
||||
if (!Bot.HasMobileAuthenticator || !Bot.BotConfig.TradingPreferences.HasFlag(BotConfig.ETradingPreferences.SteamTradeMatcher) || !await Bot.ArchiWebHandler.HasValidApiKey().ConfigureAwait(false) || !await Bot.ArchiWebHandler.HasPublicInventory().ConfigureAwait(false)) {
|
||||
ShouldSendHeartBeats = false;
|
||||
return;
|
||||
}
|
||||
|
||||
string nickname = callback.Name ?? "";
|
||||
string avatarHash = "";
|
||||
|
||||
string avatarHash = "";
|
||||
if ((callback.AvatarHash != null) && (callback.AvatarHash.Length > 0) && callback.AvatarHash.Any(singleByte => singleByte != 0)) {
|
||||
avatarHash = BitConverter.ToString(callback.AvatarHash).Replace("-", "").ToLowerInvariant();
|
||||
if (avatarHash.Equals("0000000000000000000000000000000000000000")) {
|
||||
if (avatarHash.All(singleChar => singleChar == '0')) {
|
||||
avatarHash = "";
|
||||
}
|
||||
}
|
||||
@@ -110,7 +113,7 @@ namespace ArchiSteamFarm {
|
||||
bool matchEverything = Bot.BotConfig.TradingPreferences.HasFlag(BotConfig.ETradingPreferences.MatchEverything);
|
||||
|
||||
// Skip announcing if we already announced this bot with the same data
|
||||
if (!string.IsNullOrEmpty(LastNickname) && nickname.Equals(LastNickname) && !string.IsNullOrEmpty(LastAvatarHash) && avatarHash.Equals(LastAvatarHash) && LastMatchEverything.HasValue && (matchEverything == LastMatchEverything.Value)) {
|
||||
if (ShouldSendHeartBeats && (LastNickname != null) && nickname.Equals(LastNickname) && (LastAvatarHash != null) && avatarHash.Equals(LastAvatarHash) && LastMatchEverything.HasValue && (matchEverything == LastMatchEverything.Value)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -118,7 +121,16 @@ namespace ArchiSteamFarm {
|
||||
|
||||
try {
|
||||
// Skip announcing if we already announced this bot with the same data
|
||||
if (!string.IsNullOrEmpty(LastNickname) && nickname.Equals(LastNickname) && !string.IsNullOrEmpty(LastAvatarHash) && avatarHash.Equals(LastAvatarHash) && LastMatchEverything.HasValue && (matchEverything == LastMatchEverything.Value)) {
|
||||
if (ShouldSendHeartBeats && (LastNickname != null) && nickname.Equals(LastNickname) && (LastAvatarHash != null) && avatarHash.Equals(LastAvatarHash) && LastMatchEverything.HasValue && (matchEverything == LastMatchEverything.Value)) {
|
||||
return;
|
||||
}
|
||||
|
||||
await Trading.LimitInventoryRequestsAsync().ConfigureAwait(false);
|
||||
HashSet<Steam.Item> inventory = await Bot.ArchiWebHandler.GetMySteamInventory(true, new HashSet<Steam.Item.EType> { Steam.Item.EType.TradingCard }).ConfigureAwait(false);
|
||||
|
||||
if ((inventory == null) || (inventory.Count == 0)) {
|
||||
// Don't announce, we have empty inventory
|
||||
ShouldSendHeartBeats = false;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -126,12 +138,13 @@ namespace ArchiSteamFarm {
|
||||
ShouldSendHeartBeats = true;
|
||||
|
||||
string request = await GetURL().ConfigureAwait(false) + "/api/Announce";
|
||||
Dictionary<string, string> data = new Dictionary<string, string>(5) {
|
||||
Dictionary<string, string> data = new Dictionary<string, string>(6) {
|
||||
{ "SteamID", Bot.SteamID.ToString() },
|
||||
{ "Guid", Program.GlobalDatabase.Guid.ToString("N") },
|
||||
{ "Nickname", nickname },
|
||||
{ "AvatarHash", avatarHash },
|
||||
{ "MatchEverything", matchEverything ? "1" : "0" }
|
||||
{ "MatchEverything", matchEverything ? "1" : "0" },
|
||||
{ "CardsCount", inventory.Count.ToString() }
|
||||
};
|
||||
|
||||
// We don't need retry logic here
|
||||
|
||||
@@ -51,10 +51,7 @@ namespace ArchiSteamFarm {
|
||||
Bot = bot;
|
||||
}
|
||||
|
||||
public void Dispose() {
|
||||
IgnoredTrades.Dispose();
|
||||
TradesSemaphore.Dispose();
|
||||
}
|
||||
public void Dispose() => TradesSemaphore.Dispose();
|
||||
|
||||
internal async Task CheckTrades() {
|
||||
// We aim to have a maximum of 2 tasks, one already parsing, and one waiting in the queue
|
||||
|
||||
@@ -66,11 +66,13 @@ namespace ArchiSteamFarm {
|
||||
return Strings.ErrorNoBotsDefined;
|
||||
}
|
||||
|
||||
string command = "!" + input;
|
||||
if (input[0] != '!') {
|
||||
input = "!" + input;
|
||||
}
|
||||
|
||||
// TODO: This should be asynchronous, but for some reason Mono doesn't return any WCF output if it is
|
||||
// We must keep it synchronous until either Mono gets fixed, or culprit for freeze located (and corrected)
|
||||
string output = bot.Response(Program.GlobalConfig.SteamOwnerID, command).Result;
|
||||
string output = bot.Response(Program.GlobalConfig.SteamOwnerID, input).Result;
|
||||
|
||||
ASF.ArchiLogger.LogGenericInfo(string.Format(Strings.WCFAnswered, input, output));
|
||||
return output;
|
||||
|
||||
@@ -87,6 +87,18 @@ namespace ArchiSteamFarm {
|
||||
#endif
|
||||
}
|
||||
|
||||
internal static HtmlDocument StringToHtmlDocument(string html) {
|
||||
if (string.IsNullOrEmpty(html)) {
|
||||
ASF.ArchiLogger.LogNullError(nameof(html));
|
||||
return null;
|
||||
}
|
||||
|
||||
HtmlDocument htmlDocument = new HtmlDocument();
|
||||
htmlDocument.LoadHtml(html);
|
||||
|
||||
return htmlDocument;
|
||||
}
|
||||
|
||||
internal async Task<byte[]> UrlGetToBytesRetry(string request, string referer = null) {
|
||||
if (string.IsNullOrEmpty(request)) {
|
||||
ArchiLogger.LogNullError(nameof(request));
|
||||
@@ -264,13 +276,7 @@ namespace ArchiSteamFarm {
|
||||
}
|
||||
|
||||
string content = await UrlPostToContentRetry(request, data, referer).ConfigureAwait(false);
|
||||
if (string.IsNullOrEmpty(content)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
HtmlDocument htmlDocument = new HtmlDocument();
|
||||
htmlDocument.LoadHtml(content);
|
||||
return htmlDocument;
|
||||
return !string.IsNullOrEmpty(content) ? StringToHtmlDocument(content) : null;
|
||||
}
|
||||
|
||||
internal async Task<T> UrlPostToJsonResultRetry<T>(string request, ICollection<KeyValuePair<string, string>> data = null, string referer = null) {
|
||||
@@ -353,13 +359,7 @@ namespace ArchiSteamFarm {
|
||||
}
|
||||
|
||||
string content = await UrlGetToContent(request, referer).ConfigureAwait(false);
|
||||
if (string.IsNullOrEmpty(content)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
HtmlDocument htmlDocument = new HtmlDocument();
|
||||
htmlDocument.LoadHtml(content);
|
||||
return htmlDocument;
|
||||
return !string.IsNullOrEmpty(content) ? StringToHtmlDocument(content) : null;
|
||||
}
|
||||
|
||||
private async Task<JObject> UrlGetToJObject(string request, string referer = null) {
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
"CardDropsRestricted": true,
|
||||
"CustomGamePlayedWhileFarming": null,
|
||||
"CustomGamePlayedWhileIdle": null,
|
||||
"DismissInventoryNotifications": true,
|
||||
"DismissInventoryNotifications": false,
|
||||
"Enabled": false,
|
||||
"FarmingOrder": 0,
|
||||
"FarmOffline": false,
|
||||
|
||||
@@ -3,7 +3,11 @@
|
||||
<package id="Costura.Fody" version="2.0.0-beta0018" targetFramework="net461" developmentDependency="true" />
|
||||
<package id="Fody" version="1.30.0-beta01" targetFramework="net461" developmentDependency="true" />
|
||||
<package id="HtmlAgilityPack" version="1.4.9.5" targetFramework="net461" />
|
||||
<package id="Microsoft.Bcl" version="1.1.10" targetFramework="net461" />
|
||||
<package id="Microsoft.Bcl.Async" version="1.0.168" targetFramework="net461" />
|
||||
<package id="Microsoft.Bcl.Build" version="1.0.21" targetFramework="net461" />
|
||||
<package id="Newtonsoft.Json" version="9.0.2-beta2" targetFramework="net461" />
|
||||
<package id="Nito.AsyncEx" version="4.0.1" targetFramework="net461" />
|
||||
<package id="NLog" version="5.0.0-beta05-test" targetFramework="net461" />
|
||||
<package id="protobuf-net" version="2.0.0.668" targetFramework="net45" />
|
||||
<package id="Resource.Embedder" version="1.2.2" targetFramework="net461" developmentDependency="true" />
|
||||
|
||||
@@ -55,7 +55,7 @@ namespace ConfigGenerator {
|
||||
public string CustomGamePlayedWhileIdle { get; set; } = null;
|
||||
|
||||
[JsonProperty(Required = Required.DisallowNull)]
|
||||
public bool DismissInventoryNotifications { get; set; } = true;
|
||||
public bool DismissInventoryNotifications { get; set; } = false;
|
||||
|
||||
[LocalizedCategory("Core")]
|
||||
[JsonProperty(Required = Required.DisallowNull)]
|
||||
|
||||
@@ -115,6 +115,7 @@
|
||||
<EmbeddedResource Include="Localization\CGStrings.ko-KR.resx" />
|
||||
<EmbeddedResource Include="Localization\CGStrings.lt-LT.resx" />
|
||||
<EmbeddedResource Include="Localization\CGStrings.mk-MK.resx" />
|
||||
<EmbeddedResource Include="Localization\CGStrings.nl-BE.resx" />
|
||||
<EmbeddedResource Include="Localization\CGStrings.nl-NL.resx" />
|
||||
<EmbeddedResource Include="Localization\CGStrings.no-NO.resx" />
|
||||
<EmbeddedResource Include="Localization\CGStrings.pl-PL.resx" />
|
||||
@@ -176,11 +177,17 @@
|
||||
copy "$(TargetDir)$(TargetName).exe" "$(SolutionDir)out\ASF-ConfigGenerator.exe"
|
||||
</PostBuildEvent>
|
||||
<PostBuildEvent Condition=" '$(OS)' == 'Unix' AND '$(ConfigurationName)' == 'Release' ">
|
||||
set -e
|
||||
if [ -f "$(SolutionDir)mono_envsetup.sh" ]; then
|
||||
. "$(SolutionDir)mono_envsetup.sh"
|
||||
fi
|
||||
|
||||
mono "$(SolutionDir)tools/ILRepack/ILRepack.exe" /ndebug /internalize /parallel /targetplatform:v4 /wildcards /out:"$(SolutionDir)out/ASF-ConfigGenerator.exe" "$(TargetDir)$(TargetName).exe" "$(TargetDir)*.dll"
|
||||
if [ -n "$MONO_FACADES" ]; then
|
||||
mono "$(SolutionDir)tools/ILRepack/ILRepack.exe" "/lib:$MONO_FACADES" /ndebug /internalize /parallel /targetplatform:v4 /wildcards /out:"$(SolutionDir)out/ASF-ConfigGenerator.exe" "$(TargetDir)$(TargetName).exe" "$(TargetDir)*.dll"
|
||||
else
|
||||
mono "$(SolutionDir)tools/ILRepack/ILRepack.exe" /ndebug /internalize /parallel /targetplatform:v4 /wildcards /out:"$(SolutionDir)out/ASF-ConfigGenerator.exe" "$(TargetDir)$(TargetName).exe" "$(TargetDir)*.dll"
|
||||
fi
|
||||
|
||||
rm "$(SolutionDir)out/ASF-ConfigGenerator.exe.config"
|
||||
</PostBuildEvent>
|
||||
</PropertyGroup>
|
||||
|
||||
@@ -193,8 +193,12 @@ ASF: {0} | ConfigGenerator: {1}
|
||||
<value>Чудесно! Вече твоят бот е в готовност. Всъщност, това бе всичко, което ти трябваше да изпълниш, за да ползваш този бот в ASF, но все пак, може да поискаш да зададеш поне още 2 възможности: {0} и {1}. Ако искаш да продължиш с обучението, моля, заповявай. Не забравяй да се обърнеш към wiki ако не си сигурен, как различните настройки да бъдат зададени или ако искаш допълнителна помощ.</value>
|
||||
<comment>{0} will be replaced by "SteamLogin" configuration property, {1} will be replaced by "SteamPassword" configuration property</comment>
|
||||
</data>
|
||||
|
||||
|
||||
<data name="TutorialBotFormReady" xml:space="preserve">
|
||||
<value>Вашият ASF е вече готов! Стартирайте AFS.exe файлът и ако сте въвели всичко правилно, ще забележите, че ASF се вписва и започва да вади карти. Ако имате SteamGuard или двойна защита, ASF може да поиска да въведете съответните изисквания по време на работата.</value>
|
||||
</data>
|
||||
<data name="TutorialFinished" xml:space="preserve">
|
||||
<value>Поздравления! Изпълнихте всичко, което беше необходимо, за да използвате ASF. С това завършва обучението, които Ви подготвихме. Силно препоръчително е да прочетете цялата секция за настройки в нашето wiki, тъй като ASF предлага много полезни функции, които Вие да си настроите, като вадите карти в режим offline или ASF да ползва най-ефективния метод за вадене на карти за Вашия профил. Всичко това са допълнителни възможности и сега спокойно можете да затворите конфигуратора, когато пожелаете. Надяваме се, че ще се радвате на софтуера, който сме Ви предоставили!</value>
|
||||
</data>
|
||||
|
||||
|
||||
|
||||
|
||||
242
ConfigGenerator/Localization/CGStrings.nl-BE.resx
Normal file
242
ConfigGenerator/Localization/CGStrings.nl-BE.resx
Normal file
@@ -0,0 +1,242 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" id="root">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace"/>
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0"/>
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string"/>
|
||||
<xsd:attribute name="type" type="xsd:string"/>
|
||||
<xsd:attribute name="mimetype" type="xsd:string"/>
|
||||
<xsd:attribute ref="xml:space"/>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string"/>
|
||||
<xsd:attribute name="name" type="xsd:string"/>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1"/>
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2"/>
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1"/>
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3"/>
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4"/>
|
||||
<xsd:attribute ref="xml:space"/>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1"/>
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required"/>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<data name="CategoryAccess" xml:space="preserve">
|
||||
<value>Toegang</value>
|
||||
</data>
|
||||
<data name="CategoryAdvanced" xml:space="preserve">
|
||||
<value>Geavanceerd</value>
|
||||
</data>
|
||||
<data name="CategoryCore" xml:space="preserve">
|
||||
<value>Kern</value>
|
||||
</data>
|
||||
<data name="CategoryDebugging" xml:space="preserve">
|
||||
<value>Foutopsporing</value>
|
||||
</data>
|
||||
<data name="CategoryPerformance" xml:space="preserve">
|
||||
<value>Prestaties</value>
|
||||
</data>
|
||||
<data name="CategoryUpdates" xml:space="preserve">
|
||||
<value>Updates</value>
|
||||
</data>
|
||||
<data name="ConfirmRemoval" xml:space="preserve">
|
||||
<value>Wil je deze configuratie echt verwijderen?</value>
|
||||
</data>
|
||||
<data name="ErrorBotNameEmpty" xml:space="preserve">
|
||||
<value>Je bot heeft geen naam!</value>
|
||||
</data>
|
||||
<data name="ErrorCantRemoveGlobalConfig" xml:space="preserve">
|
||||
<value>Je kan het globale config bestand niet verwijderen!</value>
|
||||
</data>
|
||||
<data name="ErrorCantRenameGlobalConfig" xml:space="preserve">
|
||||
<value>Je kan het globale configuratie bestand niet hernoemen!</value>
|
||||
</data>
|
||||
<data name="ErrorConfigDirectoryNotFound" xml:space="preserve">
|
||||
<value>Configuratiefolder kon niet gevonden worden!</value>
|
||||
</data>
|
||||
<data name="ErrorConfigPropertyInvalid" xml:space="preserve">
|
||||
<value>Geconfigureerde {0} eigenschap is niet geldig: {1}</value>
|
||||
<comment>{0} will be replaced by name of the configuration property, {1} will be replaced by invalid value</comment>
|
||||
</data>
|
||||
<data name="ErrorInvalidCurrentCulture" xml:space="preserve">
|
||||
<value>De opgegeven CurrentCulture is ongeldig, ConfigGenerator blijft draaien met de standaard!</value>
|
||||
</data>
|
||||
<data name="ErrorNameAlreadyUsed" xml:space="preserve">
|
||||
<value>Deze naam is al in gebruik!</value>
|
||||
<comment>This happens e.g. when user wants to create a bot with name that exists already</comment>
|
||||
</data>
|
||||
<data name="ErrorNameReserved" xml:space="preserve">
|
||||
<value>Deze naam is gereserveerd!</value>
|
||||
<comment>This happens e.g. when user wants to create a bot with reserved name, such as "ASF"</comment>
|
||||
</data>
|
||||
<data name="ErrorObjectIsNull" xml:space="preserve">
|
||||
<value>{0} is null!</value>
|
||||
<comment>{0} will be replaced by object's name</comment>
|
||||
</data>
|
||||
<data name="ErrorVersionMismatch" xml:space="preserve">
|
||||
<value>Je hebt geprobeerd om een ongeldige ConfigGenerator versie te gebruiken voor ASF!
|
||||
|
||||
ASF: {0} | ConfigGenerator: {1}
|
||||
|
||||
Gebruik een zelfde versie ConfigGenerator voor je ASF bestand. Je wordt verwezen naar de juiste release...</value>
|
||||
<comment>{0} will be replaced by ASF version (string), {1} will be replaced by ConfigGenerator version (string). Please note that this string should include newlines for formatting.</comment>
|
||||
</data>
|
||||
<data name="New" xml:space="preserve">
|
||||
<value>Nieuw</value>
|
||||
<comment>This is used as MessageBox title</comment>
|
||||
</data>
|
||||
<data name="Removal" xml:space="preserve">
|
||||
<value>Verwijderen</value>
|
||||
<comment>This is used as MessageBox title</comment>
|
||||
</data>
|
||||
<data name="Rename" xml:space="preserve">
|
||||
<value>Hernoemen</value>
|
||||
<comment>This is used as MessageBox title</comment>
|
||||
</data>
|
||||
<data name="TutorialBotFormEnabled" xml:space="preserve">
|
||||
<value>Proficiat! Je bot instance is actief. Feitelijk was dat alles dat je moest doen om deze bot in ASF te gebruiken, maar je wilt misschien nog 2 andere config waardes instellen: {0} en {1}.
|
||||
Je kan, als je wilt, doorgaan met deze tutorial. Vergeet niet de wiki te gebruiken als je niet zeker weet hoe een waarde moet worden ingesteld. Dit geldt ook als je meer hulp nodig hebt.</value>
|
||||
<comment>{0} will be replaced by "SteamLogin" configuration property, {1} will be replaced by "SteamPassword" configuration property</comment>
|
||||
</data>
|
||||
<data name="TutorialBotFormReady" xml:space="preserve">
|
||||
<value>Je ASF is nu klaar! Simpelweg ASF.exe starten en als je alles correct hebt ingevuld, zul je merken dat ASF aan het inloggen en begonnen is met idlen. Als je SteamGuard twee factor authenticatie aan hebt staan, kan het zijn dat ASF voor deze gegevens vraagt tijdens het starten.</value>
|
||||
</data>
|
||||
<data name="TutorialFinished" xml:space="preserve">
|
||||
<value>Proficiat! Je hebt alles gedaan dat nodig is om ASF bruikbaar te maken, hiermee is deze tutorial die we hebben klaargezet ook afgerond. Het wordt sterk aanbevolen om de hele 'configuration' sectie op de wiki te lezen, aangezien ASF leuke eigenschappen heeft die geconfigureerd kunnen worden. Zoals offline farmen of afstemmen van ASF voor het meest efficiënte idling algoritme voor je account. Dit alles is optioneel en je kan de ConfigGenerator afsluiten als je dit wilt. We hopen dat je zult genieten van de software die we voor jou hebben geschreven!</value>
|
||||
</data>
|
||||
<data name="TutorialMainFormBotsManagementButtons" xml:space="preserve">
|
||||
<value>Bovenaan het venster zie je de huidig geladen configuraties en 3 extra knoppen voor verwijderen [-], hernoemen [~] en toevoegen van nieuwe configuraties [+].</value>
|
||||
<comment>If possible, try to keep visual representation of buttons: [-], [~] and [+]</comment>
|
||||
</data>
|
||||
<data name="TutorialMainFormConfigurationWiki" xml:space="preserve">
|
||||
<value>Hou rekening dat alle informatie met betrekking tot alle beschikbare config eigenschappen, inclusief hun uitleg, doel en geaccepteerde waardes, beschikbaar is op onze GitHub wiki. Graag dit als referentie gebruiken.</value>
|
||||
</data>
|
||||
<data name="TutorialMainFormConfigurationWindow" xml:space="preserve">
|
||||
<value>In het midden van de venster kan alle config eigenschappen die beschikbaar zijn configureren. Dit geldt voor de huidig geselecteerde config.</value>
|
||||
</data>
|
||||
<data name="TutorialMainFormFinished" xml:space="preserve">
|
||||
<value>Laten we beginnen met het configureren van ASF. Klik op de plus [+] knop om je eerste Steam account toe te voegen!</value>
|
||||
<comment>If possible, try to keep visual representation of [+] button</comment>
|
||||
</data>
|
||||
<data name="TutorialMainFormHelpButton" xml:space="preserve">
|
||||
<value>In de bovenrechter hoek vindt je de help knop [?] die je doorverwijst naar de ASF wiki voor meer informatie.</value>
|
||||
<comment>If possible, try to keep visual representation of [?] button</comment>
|
||||
</data>
|
||||
<data name="TutorialMainFormShown" xml:space="preserve">
|
||||
<value>Dit is de hoofd ASF ConfigGenerator scherm, het is heel simpel in gebruik!</value>
|
||||
</data>
|
||||
<data name="TutorialNewBotFormFinished" xml:space="preserve">
|
||||
<value>Zoals je ziet, je bot is nu gereed voor configuratie! Het eerste dat je wilt doen is {0} eigenschap schakelen van false naar true, probeer het!</value>
|
||||
<comment>{0} will be replaced by name of the configuration property ("Enabled")</comment>
|
||||
</data>
|
||||
<data name="TutorialNewBotFormShown" xml:space="preserve">
|
||||
<value>Goed gedaan! Je wordt nu gevraagd voor een naam voor je bot. Een goede voorbeeld is de nickname die je voor je Steam account gebruikt. Of elk ander naam die makkelijk voor jou is om te herinneren om welke bot het gaat.</value>
|
||||
</data>
|
||||
<data name="TutorialStart" xml:space="preserve">
|
||||
<value>Welkom! Ik zie dat dit de eerste keer is dat je ASF ConfigGenerator gebruikt, laat me je daar een beetje mee helpen.</value>
|
||||
</data>
|
||||
<data name="UserInputBotName" xml:space="preserve">
|
||||
<value>Voer een nieuwe naam in voor de bot: </value>
|
||||
<comment>Please note that this translation should end with space</comment>
|
||||
</data>
|
||||
<data name="WarningConfigPropertyModified" xml:space="preserve">
|
||||
<value>{0} staat nu op: {1}</value>
|
||||
<comment>{0} will be replaced by name of the configuration property, {1} will be replaced by new value</comment>
|
||||
</data>
|
||||
</root>
|
||||
@@ -158,7 +158,7 @@
|
||||
<value>De opgegeven CurrentCulture is ongeldig, ConfigGenerator blijft draaien met de standaard!</value>
|
||||
</data>
|
||||
<data name="ErrorNameAlreadyUsed" xml:space="preserve">
|
||||
<value>Deze naam is al gebruikt!</value>
|
||||
<value>Deze naam is al in gebruik!</value>
|
||||
<comment>This happens e.g. when user wants to create a bot with name that exists already</comment>
|
||||
</data>
|
||||
<data name="ErrorNameReserved" xml:space="preserve">
|
||||
|
||||
@@ -44,8 +44,6 @@ namespace ArchiSteamFarm {
|
||||
AvatarPictureBox.LoadAsync();
|
||||
}
|
||||
|
||||
private void AvatarPictureBox_LoadCompleted(object sender, AsyncCompletedEventArgs e) {
|
||||
MainForm.UpdateBotAvatar(Bot.BotName, AvatarPictureBox.Image);
|
||||
}
|
||||
private void AvatarPictureBox_LoadCompleted(object sender, AsyncCompletedEventArgs e) => MainForm.UpdateBotAvatar(Bot.BotName, AvatarPictureBox.Image);
|
||||
}
|
||||
}
|
||||
@@ -30,7 +30,7 @@ namespace ArchiSteamFarm {
|
||||
|
||||
internal static void OnPersonaState(Bot bot, SteamFriends.PersonaStateCallback callback) {
|
||||
if (bot == null) {
|
||||
Program.ArchiLogger.LogNullError(nameof(bot));
|
||||
ASF.ArchiLogger.LogNullError(nameof(bot));
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -48,10 +48,34 @@
|
||||
<HintPath>..\packages\HtmlAgilityPack.1.4.9.5\lib\Net45\HtmlAgilityPack.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.Threading.Tasks, Version=1.0.12.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.Threading.Tasks.Extensions, Version=1.0.12.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.Extensions.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.Threading.Tasks.Extensions.Desktop, Version=1.0.168.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.Extensions.Desktop.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="Newtonsoft.Json, Version=9.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Newtonsoft.Json.9.0.2-beta2\lib\net45\Newtonsoft.Json.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="Nito.AsyncEx, Version=4.0.1.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Nito.AsyncEx.4.0.1\lib\net45\Nito.AsyncEx.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="Nito.AsyncEx.Concurrent, Version=4.0.1.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Nito.AsyncEx.4.0.1\lib\net45\Nito.AsyncEx.Concurrent.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="Nito.AsyncEx.Enlightenment, Version=4.0.1.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Nito.AsyncEx.4.0.1\lib\net45\Nito.AsyncEx.Enlightenment.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="NLog, Version=5.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\NLog.5.0.0-beta05-test\lib\net45\NLog.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
@@ -71,6 +95,7 @@
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.IO.Compression" />
|
||||
<Reference Include="System.Net" />
|
||||
<Reference Include="System.Security" />
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="System.Drawing" />
|
||||
@@ -148,6 +173,9 @@
|
||||
<Compile Include="..\ArchiSteamFarm\MobileAuthenticator.cs">
|
||||
<Link>MobileAuthenticator.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\ArchiSteamFarm\OS.cs">
|
||||
<Link>OS.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\ArchiSteamFarm\Runtime.cs">
|
||||
<Link>Runtime.cs</Link>
|
||||
</Compile>
|
||||
@@ -251,6 +279,9 @@
|
||||
<EmbeddedResource Include="..\ArchiSteamFarm\Localization\Strings.mk-MK.resx">
|
||||
<Link>Localization\Strings.mk-MK.resx</Link>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="..\ArchiSteamFarm\Localization\Strings.nl-BE.resx">
|
||||
<Link>Localization\Strings.nl-BE.resx</Link>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="..\ArchiSteamFarm\Localization\Strings.nl-NL.resx">
|
||||
<Link>Localization\Strings.nl-NL.resx</Link>
|
||||
</EmbeddedResource>
|
||||
@@ -349,11 +380,17 @@
|
||||
copy "$(TargetDir)$(TargetName).exe" "$(SolutionDir)out\ASF-GUI.exe"
|
||||
</PostBuildEvent>
|
||||
<PostBuildEvent Condition=" '$(OS)' == 'Unix' AND '$(ConfigurationName)' == 'Release' ">
|
||||
set -e
|
||||
if [ -f "$(SolutionDir)mono_envsetup.sh" ]; then
|
||||
. "$(SolutionDir)mono_envsetup.sh"
|
||||
fi
|
||||
|
||||
mono "$(SolutionDir)tools/ILRepack/ILRepack.exe" /ndebug /internalize /parallel /targetplatform:v4 /wildcards /out:"$(SolutionDir)out/ASF-GUI.exe" "$(TargetDir)$(TargetName).exe" "$(TargetDir)*.dll"
|
||||
if [ -n "$MONO_FACADES" ]; then
|
||||
mono "$(SolutionDir)tools/ILRepack/ILRepack.exe" "/lib:$MONO_FACADES" /ndebug /internalize /parallel /targetplatform:v4 /wildcards /out:"$(SolutionDir)out/ASF-GUI.exe" "$(TargetDir)$(TargetName).exe" "$(TargetDir)*.dll"
|
||||
else
|
||||
mono "$(SolutionDir)tools/ILRepack/ILRepack.exe" /ndebug /internalize /parallel /targetplatform:v4 /wildcards /out:"$(SolutionDir)out/ASF-GUI.exe" "$(TargetDir)$(TargetName).exe" "$(TargetDir)*.dll"
|
||||
fi
|
||||
|
||||
rm "$(SolutionDir)out/ASF-GUI.exe.config"
|
||||
</PostBuildEvent>
|
||||
</PropertyGroup>
|
||||
@@ -364,10 +401,12 @@
|
||||
<Error Condition="!Exists('..\packages\Fody.1.30.0-beta01\build\dotnet\Fody.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Fody.1.30.0-beta01\build\dotnet\Fody.targets'))" />
|
||||
<Error Condition="!Exists('..\packages\Costura.Fody.2.0.0-beta0018\build\Costura.Fody.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Costura.Fody.2.0.0-beta0018\build\Costura.Fody.targets'))" />
|
||||
<Error Condition="!Exists('..\packages\Resource.Embedder.1.2.2\build\Resource.Embedder.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Resource.Embedder.1.2.2\build\Resource.Embedder.targets'))" />
|
||||
<Error Condition="!Exists('..\packages\Microsoft.Bcl.Build.1.0.21\build\Microsoft.Bcl.Build.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.Bcl.Build.1.0.21\build\Microsoft.Bcl.Build.targets'))" />
|
||||
</Target>
|
||||
<Import Project="..\packages\Fody.1.30.0-beta01\build\dotnet\Fody.targets" Condition="'$(OS)' != 'Unix' AND '$(ConfigurationName)' == 'Release' AND Exists('..\packages\Fody.1.30.0-beta01\build\dotnet\Fody.targets')" />
|
||||
<Import Project="..\packages\Costura.Fody.2.0.0-beta0018\build\Costura.Fody.targets" Condition="'$(OS)' != 'Unix' AND '$(ConfigurationName)' == 'Release' AND Exists('..\packages\Costura.Fody.2.0.0-beta0018\build\Costura.Fody.targets')" />
|
||||
<Import Project="..\packages\Resource.Embedder.1.2.2\build\Resource.Embedder.targets" Condition="'$(OS)' != 'Unix' AND '$(ConfigurationName)' == 'Release' AND Exists('..\packages\Resource.Embedder.1.2.2\build\Resource.Embedder.targets')" />
|
||||
<Import Project="..\packages\Microsoft.Bcl.Build.1.0.21\build\Microsoft.Bcl.Build.targets" Condition="Exists('..\packages\Microsoft.Bcl.Build.1.0.21\build\Microsoft.Bcl.Build.targets')" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
|
||||
@@ -22,7 +22,6 @@
|
||||
|
||||
*/
|
||||
|
||||
using System.Linq;
|
||||
using NLog;
|
||||
using NLog.Config;
|
||||
using NLog.Targets;
|
||||
@@ -30,46 +29,34 @@ using NLog.Windows.Forms;
|
||||
|
||||
namespace ArchiSteamFarm {
|
||||
internal static class Logging {
|
||||
private const string GeneralLayout = @"${date:format=yyyy-MM-dd HH\:mm\:ss} | ${level:uppercase=true} | ${logger} | ${message}${onexception:inner= | ${exception:format=toString,Data}}";
|
||||
private const string GeneralLayout = @"${date:format=yyyy-MM-dd HH\:mm\:ss}|${processname}-${processid}|${level:uppercase=true}|${logger}|${message}${onexception:inner= ${exception:format=toString,Data}}";
|
||||
|
||||
private static bool IsUsingCustomConfiguration;
|
||||
|
||||
internal static void InitCoreLoggers() {
|
||||
if (LogManager.Configuration == null) {
|
||||
LogManager.Configuration = new LoggingConfiguration();
|
||||
} else {
|
||||
// User provided custom NLog config, but we still need to define our own logger
|
||||
IsUsingCustomConfiguration = true;
|
||||
if (LogManager.Configuration.AllTargets.Any(target => target is MessageBoxTarget)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
MessageBoxTarget messageBoxTarget = new MessageBoxTarget {
|
||||
Name = "MessageBox",
|
||||
Layout = GeneralLayout
|
||||
};
|
||||
|
||||
LogManager.Configuration.AddTarget(messageBoxTarget);
|
||||
LogManager.Configuration.LoggingRules.Add(new LoggingRule("*", LogLevel.Fatal, messageBoxTarget));
|
||||
LogManager.ReconfigExistingLoggers();
|
||||
}
|
||||
|
||||
internal static void InitEnhancedLoggers() {
|
||||
if (IsUsingCustomConfiguration) {
|
||||
internal static void InitLoggers() {
|
||||
if (LogManager.Configuration != null) {
|
||||
// User provided custom NLog config, or we have it set already, so don't override it
|
||||
return;
|
||||
}
|
||||
|
||||
LoggingConfiguration config = new LoggingConfiguration();
|
||||
|
||||
FileTarget fileTarget = new FileTarget("File") {
|
||||
DeleteOldFileOnStartup = true,
|
||||
FileName = SharedInfo.LogFile,
|
||||
Layout = GeneralLayout
|
||||
};
|
||||
|
||||
LogManager.Configuration.AddTarget(fileTarget);
|
||||
LogManager.Configuration.LoggingRules.Add(new LoggingRule("*", LogLevel.Debug, fileTarget));
|
||||
config.AddTarget(fileTarget);
|
||||
config.LoggingRules.Add(new LoggingRule("*", LogLevel.Debug, fileTarget));
|
||||
|
||||
LogManager.ReconfigExistingLoggers();
|
||||
MessageBoxTarget messageBoxTarget = new MessageBoxTarget {
|
||||
Name = "MessageBox",
|
||||
Layout = GeneralLayout
|
||||
};
|
||||
|
||||
config.AddTarget(messageBoxTarget);
|
||||
config.LoggingRules.Add(new LoggingRule("*", LogLevel.Fatal, messageBoxTarget));
|
||||
|
||||
LogManager.Configuration = config;
|
||||
}
|
||||
|
||||
internal static void InitFormLogger() {
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Drawing2D;
|
||||
using System.Drawing.Imaging;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace ArchiSteamFarm {
|
||||
@@ -22,7 +20,7 @@ namespace ArchiSteamFarm {
|
||||
|
||||
internal static void UpdateBotAvatar(string botName, Image image) {
|
||||
if (string.IsNullOrEmpty(botName) || (image == null)) {
|
||||
Program.ArchiLogger.LogNullError(nameof(botName) + " || " + nameof(image));
|
||||
ASF.ArchiLogger.LogNullError(nameof(botName) + " || " + nameof(image));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -62,55 +60,36 @@ namespace ArchiSteamFarm {
|
||||
private async void MainForm_FormClosed(object sender, FormClosedEventArgs e) => await Program.InitShutdownSequence().ConfigureAwait(false);
|
||||
|
||||
private async void MainForm_Load(object sender, EventArgs e) {
|
||||
Logging.InitFormLogger();
|
||||
|
||||
BotListView.LargeImageList = BotListView.SmallImageList = AvatarImageList;
|
||||
|
||||
await Task.Run(async () => {
|
||||
Program.ArchiLogger.LogGenericInfo("ASF V" + SharedInfo.Version);
|
||||
Program.InitCore();
|
||||
Logging.InitFormLogger();
|
||||
await Program.InitASF(); // No ConfigureAwait, we need GUI thread
|
||||
|
||||
if (!Directory.Exists(SharedInfo.ConfigDirectory)) {
|
||||
Program.ArchiLogger.LogGenericError("Config directory could not be found!");
|
||||
Environment.Exit(1);
|
||||
}
|
||||
foreach (KeyValuePair<string, Bot> bot in Bot.Bots) {
|
||||
BotStatusForm botStatusForm = new BotStatusForm(bot.Value);
|
||||
|
||||
await ASF.CheckForUpdate().ConfigureAwait(false);
|
||||
BotIndexes[bot.Key] = AvatarImageList.Images.Count;
|
||||
|
||||
// Before attempting to connect, initialize our list of CMs
|
||||
await Bot.InitializeCMs(Program.GlobalDatabase.CellID, Program.GlobalDatabase.ServerListProvider).ConfigureAwait(false);
|
||||
});
|
||||
|
||||
foreach (string botName in Directory.EnumerateFiles(SharedInfo.ConfigDirectory, "*.json").Select(Path.GetFileNameWithoutExtension)) {
|
||||
switch (botName) {
|
||||
case SharedInfo.ASF:
|
||||
case "example":
|
||||
case "minimal":
|
||||
continue;
|
||||
}
|
||||
|
||||
Bot bot = new Bot(botName);
|
||||
|
||||
BotStatusForm botStatusForm = new BotStatusForm(bot);
|
||||
|
||||
BotIndexes[botName] = AvatarImageList.Images.Count;
|
||||
|
||||
AvatarImageList.Images.Add(botName, botStatusForm.AvatarPictureBox.Image);
|
||||
AvatarImageList.Images.Add(bot.Key, botStatusForm.AvatarPictureBox.Image);
|
||||
|
||||
botStatusForm.TopLevel = false;
|
||||
BotStatusPanel.Controls.Add(botStatusForm);
|
||||
|
||||
ListViewItem botListViewItem = new ListViewItem {
|
||||
ImageIndex = BotIndexes[botName],
|
||||
Text = botName
|
||||
ImageIndex = BotIndexes[bot.Key],
|
||||
Text = bot.Key
|
||||
};
|
||||
|
||||
BotListView.Items.Add(botListViewItem);
|
||||
}
|
||||
|
||||
if (BotListView.Items.Count > 0) {
|
||||
BotListView.Items[0].Selected = true;
|
||||
BotListView.Select();
|
||||
if (BotListView.Items.Count <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
BotListView.Items[0].Selected = true;
|
||||
BotListView.Select();
|
||||
}
|
||||
|
||||
private void MainForm_Resize(object sender, EventArgs e) {
|
||||
@@ -132,7 +111,7 @@ namespace ArchiSteamFarm {
|
||||
|
||||
private static Bitmap ResizeImage(Image image, int width, int height) {
|
||||
if ((image == null) || (width <= 0) || (height <= 0)) {
|
||||
Program.ArchiLogger.LogNullError(nameof(image) + " || " + nameof(width) + " || " + nameof(height));
|
||||
ASF.ArchiLogger.LogNullError(nameof(image) + " || " + nameof(width) + " || " + nameof(height));
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
177
GUI/Program.cs
177
GUI/Program.cs
@@ -1,18 +1,18 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Threading;
|
||||
using System.Resources;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
using ArchiSteamFarm.Localization;
|
||||
using NLog.Targets;
|
||||
using SteamKit2;
|
||||
|
||||
namespace ArchiSteamFarm {
|
||||
internal static class Program {
|
||||
internal static readonly ArchiLogger ArchiLogger = new ArchiLogger(SharedInfo.ASF);
|
||||
|
||||
internal static GlobalConfig GlobalConfig { get; private set; }
|
||||
internal static GlobalDatabase GlobalDatabase { get; private set; }
|
||||
internal static WebBrowser WebBrowser { get; private set; }
|
||||
@@ -25,11 +25,68 @@ namespace ArchiSteamFarm {
|
||||
}
|
||||
|
||||
await Shutdown().ConfigureAwait(false);
|
||||
Environment.Exit(exitCode);
|
||||
Application.Exit();
|
||||
}
|
||||
|
||||
internal static string GetUserInput(ASF.EUserInputType userInputType, string botName = SharedInfo.ASF, string extraInformation = null) {
|
||||
return null; // TODO
|
||||
internal static string GetUserInput(ASF.EUserInputType userInputType, string botName = SharedInfo.ASF, string extraInformation = null) => null; // TODO
|
||||
|
||||
internal static async Task InitASF() {
|
||||
ASF.ArchiLogger.LogGenericInfo("ASF V" + SharedInfo.Version);
|
||||
|
||||
await InitGlobalConfigAndLanguage().ConfigureAwait(false);
|
||||
|
||||
if (!Runtime.IsRuntimeSupported) {
|
||||
ASF.ArchiLogger.LogGenericError(Strings.WarningRuntimeUnsupported);
|
||||
await Task.Delay(60 * 1000).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
await InitGlobalDatabaseAndServices().ConfigureAwait(false);
|
||||
|
||||
// If debugging is on, we prepare debug directory prior to running
|
||||
if (GlobalConfig.Debug) {
|
||||
if (Directory.Exists(SharedInfo.DebugDirectory)) {
|
||||
try {
|
||||
Directory.Delete(SharedInfo.DebugDirectory, true);
|
||||
await Task.Delay(1000).ConfigureAwait(false); // Dirty workaround giving Windows some time to sync
|
||||
} catch (IOException e) {
|
||||
ASF.ArchiLogger.LogGenericException(e);
|
||||
}
|
||||
}
|
||||
|
||||
Directory.CreateDirectory(SharedInfo.DebugDirectory);
|
||||
|
||||
DebugLog.AddListener(new Debugging.DebugListener());
|
||||
DebugLog.Enabled = true;
|
||||
}
|
||||
|
||||
await ASF.CheckForUpdate().ConfigureAwait(false);
|
||||
await ASF.InitBots().ConfigureAwait(false);
|
||||
ASF.InitFileWatcher();
|
||||
}
|
||||
|
||||
internal static void InitCore() {
|
||||
string homeDirectory = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);
|
||||
if (!string.IsNullOrEmpty(homeDirectory)) {
|
||||
Directory.SetCurrentDirectory(homeDirectory);
|
||||
|
||||
// Allow loading configs from source tree if it's a debug build
|
||||
if (Debugging.IsDebugBuild) {
|
||||
// Common structure is bin/(x64/)Debug/ArchiSteamFarm.exe, so we allow up to 4 directories up
|
||||
for (byte i = 0; i < 4; i++) {
|
||||
Directory.SetCurrentDirectory("..");
|
||||
if (Directory.Exists(SharedInfo.ConfigDirectory)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// If config directory doesn't exist after our adjustment, abort all of that
|
||||
if (!Directory.Exists(SharedInfo.ConfigDirectory)) {
|
||||
Directory.SetCurrentDirectory(homeDirectory);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Logging.InitLoggers();
|
||||
}
|
||||
|
||||
internal static async Task<bool> InitShutdownSequence() {
|
||||
@@ -53,79 +110,77 @@ namespace ArchiSteamFarm {
|
||||
Application.Restart();
|
||||
}
|
||||
|
||||
private static async Task Init() {
|
||||
private static void Init() {
|
||||
AppDomain.CurrentDomain.UnhandledException += UnhandledExceptionHandler;
|
||||
TaskScheduler.UnobservedTaskException += UnobservedTaskExceptionHandler;
|
||||
|
||||
Logging.InitCoreLoggers();
|
||||
// We must register our logging target as soon as possible
|
||||
Target.Register<SteamTarget>("Steam");
|
||||
|
||||
if (!Runtime.IsRuntimeSupported) {
|
||||
ArchiLogger.LogGenericError("ASF detected unsupported runtime version, program might NOT run correctly in current environment. You're running it at your own risk!");
|
||||
}
|
||||
|
||||
string homeDirectory = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);
|
||||
if (!string.IsNullOrEmpty(homeDirectory)) {
|
||||
Directory.SetCurrentDirectory(homeDirectory);
|
||||
|
||||
// Allow loading configs from source tree if it's a debug build
|
||||
if (Debugging.IsDebugBuild) {
|
||||
// Common structure is bin/(x64/)Debug/ArchiSteamFarm.exe, so we allow up to 4 directories up
|
||||
for (byte i = 0; i < 4; i++) {
|
||||
Directory.SetCurrentDirectory("..");
|
||||
if (!Directory.Exists(SharedInfo.ASFDirectory)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Directory.SetCurrentDirectory(SharedInfo.ASFDirectory);
|
||||
break;
|
||||
}
|
||||
|
||||
// If config directory doesn't exist after our adjustment, abort all of that
|
||||
if (!Directory.Exists(SharedInfo.ConfigDirectory)) {
|
||||
Directory.SetCurrentDirectory(homeDirectory);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
await InitServices().ConfigureAwait(false);
|
||||
|
||||
// If debugging is on, we prepare debug directory prior to running
|
||||
if (GlobalConfig.Debug) {
|
||||
if (Directory.Exists(SharedInfo.DebugDirectory)) {
|
||||
Directory.Delete(SharedInfo.DebugDirectory, true);
|
||||
Thread.Sleep(1000); // Dirty workaround giving Windows some time to sync
|
||||
}
|
||||
|
||||
Directory.CreateDirectory(SharedInfo.DebugDirectory);
|
||||
|
||||
DebugLog.AddListener(new Debugging.DebugListener());
|
||||
DebugLog.Enabled = true;
|
||||
}
|
||||
|
||||
Logging.InitEnhancedLoggers();
|
||||
// The rest of ASF is initialized from MainForm.cs
|
||||
}
|
||||
|
||||
private static async Task InitServices() {
|
||||
private static async Task InitGlobalConfigAndLanguage() {
|
||||
string globalConfigFile = Path.Combine(SharedInfo.ConfigDirectory, SharedInfo.GlobalConfigFileName);
|
||||
|
||||
GlobalConfig = GlobalConfig.Load(globalConfigFile);
|
||||
if (GlobalConfig == null) {
|
||||
ArchiLogger.LogGenericError("Global config could not be loaded, please make sure that " + globalConfigFile + " exists and is valid!");
|
||||
ASF.ArchiLogger.LogGenericError(string.Format(Strings.ErrorGlobalConfigNotLoaded, globalConfigFile));
|
||||
await Task.Delay(5 * 1000).ConfigureAwait(false);
|
||||
await Exit(1).ConfigureAwait(false);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(GlobalConfig.CurrentCulture)) {
|
||||
try {
|
||||
// GetCultureInfo() would be better but we can't use it for specifying neutral cultures such as "en"
|
||||
CultureInfo culture = CultureInfo.CreateSpecificCulture(GlobalConfig.CurrentCulture);
|
||||
CultureInfo.DefaultThreadCurrentCulture = CultureInfo.DefaultThreadCurrentUICulture = culture;
|
||||
} catch (CultureNotFoundException) {
|
||||
ASF.ArchiLogger.LogGenericError(Strings.ErrorInvalidCurrentCulture);
|
||||
}
|
||||
}
|
||||
|
||||
int defaultResourceSetCount = 0;
|
||||
ResourceSet defaultResourceSet = Strings.ResourceManager.GetResourceSet(CultureInfo.GetCultureInfo("en-US"), true, true);
|
||||
if (defaultResourceSet != null) {
|
||||
defaultResourceSetCount = defaultResourceSet.Cast<object>().Count();
|
||||
}
|
||||
|
||||
int currentResourceSetCount = 0;
|
||||
ResourceSet currentResourceSet = Strings.ResourceManager.GetResourceSet(CultureInfo.CurrentCulture, true, false);
|
||||
if (currentResourceSet != null) {
|
||||
currentResourceSetCount = currentResourceSet.Cast<object>().Count();
|
||||
}
|
||||
|
||||
if (currentResourceSetCount < defaultResourceSetCount) {
|
||||
float translationCompleteness = currentResourceSetCount / (float) defaultResourceSetCount;
|
||||
ASF.ArchiLogger.LogGenericInfo(string.Format(Strings.TranslationIncomplete, CultureInfo.CurrentCulture.Name, translationCompleteness.ToString("P1")));
|
||||
}
|
||||
}
|
||||
|
||||
private static async Task InitGlobalDatabaseAndServices() {
|
||||
string globalDatabaseFile = Path.Combine(SharedInfo.ConfigDirectory, SharedInfo.GlobalDatabaseFileName);
|
||||
|
||||
if (!File.Exists(globalDatabaseFile)) {
|
||||
ASF.ArchiLogger.LogGenericInfo(Strings.Welcome);
|
||||
ASF.ArchiLogger.LogGenericWarning(Strings.WarningPrivacyPolicy);
|
||||
await Task.Delay(15 * 1000).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
GlobalDatabase = GlobalDatabase.Load(globalDatabaseFile);
|
||||
if (GlobalDatabase == null) {
|
||||
ArchiLogger.LogGenericError("Global database could not be loaded, if issue persists, please remove " + globalDatabaseFile + " in order to recreate database!");
|
||||
ASF.ArchiLogger.LogGenericError(string.Format(Strings.ErrorDatabaseInvalid, globalDatabaseFile));
|
||||
await Task.Delay(5 * 1000).ConfigureAwait(false);
|
||||
await Exit(1).ConfigureAwait(false);
|
||||
return;
|
||||
}
|
||||
|
||||
ArchiWebHandler.Init();
|
||||
OS.Init();
|
||||
WebBrowser.Init();
|
||||
|
||||
WebBrowser = new WebBrowser(ArchiLogger);
|
||||
WebBrowser = new WebBrowser(ASF.ArchiLogger);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -133,7 +188,7 @@ namespace ArchiSteamFarm {
|
||||
/// </summary>
|
||||
[STAThread]
|
||||
private static void Main() {
|
||||
Init().Wait();
|
||||
Init();
|
||||
Application.EnableVisualStyles();
|
||||
Application.SetCompatibleTextRenderingDefault(false);
|
||||
Application.Run(new MainForm());
|
||||
@@ -149,22 +204,22 @@ namespace ArchiSteamFarm {
|
||||
|
||||
private static async void UnhandledExceptionHandler(object sender, UnhandledExceptionEventArgs args) {
|
||||
if (args?.ExceptionObject == null) {
|
||||
ArchiLogger.LogNullError(nameof(args) + " || " + nameof(args.ExceptionObject));
|
||||
ASF.ArchiLogger.LogNullError(nameof(args) + " || " + nameof(args.ExceptionObject));
|
||||
return;
|
||||
}
|
||||
|
||||
ArchiLogger.LogFatalException((Exception) args.ExceptionObject);
|
||||
ASF.ArchiLogger.LogFatalException((Exception) args.ExceptionObject);
|
||||
await Task.Delay(5000).ConfigureAwait(false);
|
||||
await Exit(1).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
private static void UnobservedTaskExceptionHandler(object sender, UnobservedTaskExceptionEventArgs args) {
|
||||
if (args?.Exception == null) {
|
||||
ArchiLogger.LogNullError(nameof(args) + " || " + nameof(args.Exception));
|
||||
ASF.ArchiLogger.LogNullError(nameof(args) + " || " + nameof(args.Exception));
|
||||
return;
|
||||
}
|
||||
|
||||
ArchiLogger.LogFatalException(args.Exception);
|
||||
ASF.ArchiLogger.LogFatalException(args.Exception);
|
||||
// Normally we should abort the application here, but many tasks are in fact failing in SK2 code which we can't easily fix
|
||||
// Thanks Valve.
|
||||
}
|
||||
|
||||
@@ -3,7 +3,11 @@
|
||||
<package id="Costura.Fody" version="2.0.0-beta0018" targetFramework="net461" developmentDependency="true" />
|
||||
<package id="Fody" version="1.30.0-beta01" targetFramework="net461" developmentDependency="true" />
|
||||
<package id="HtmlAgilityPack" version="1.4.9.5" targetFramework="net461" />
|
||||
<package id="Microsoft.Bcl" version="1.1.10" targetFramework="net461" />
|
||||
<package id="Microsoft.Bcl.Async" version="1.0.168" targetFramework="net461" />
|
||||
<package id="Microsoft.Bcl.Build" version="1.0.21" targetFramework="net461" />
|
||||
<package id="Newtonsoft.Json" version="9.0.2-beta2" targetFramework="net461" />
|
||||
<package id="Nito.AsyncEx" version="4.0.1" targetFramework="net461" />
|
||||
<package id="NLog" version="5.0.0-beta05-test" targetFramework="net461" />
|
||||
<package id="NLog.Windows.Forms" version="4.2.3" targetFramework="net461" />
|
||||
<package id="protobuf-net" version="2.0.0.668" targetFramework="net461" />
|
||||
|
||||
@@ -71,4 +71,11 @@ else
|
||||
echo "INFO: Skipping setting of MONO_ENV_OPTIONS as it's already declared with value: $MONO_ENV_OPTIONS"
|
||||
fi
|
||||
|
||||
MONO_FACADES=""
|
||||
if [ -d "/usr/lib/mono/4.5/Facades" ]; then
|
||||
export MONO_FACADES="/usr/lib/mono/4.5/Facades"
|
||||
else
|
||||
echo "WARN: Could not find Mono facades!"
|
||||
fi
|
||||
|
||||
echo "INFO: Mono environment setup finished!"
|
||||
|
||||
118
packages/Microsoft.Bcl.1.1.10/License-Stable.rtf
vendored
Normal file
118
packages/Microsoft.Bcl.1.1.10/License-Stable.rtf
vendored
Normal file
@@ -0,0 +1,118 @@
|
||||
{\rtf1\ansi\ansicpg1252\deff0\nouicompat\deflang1033{\fonttbl{\f0\fswiss\fprq2\fcharset0 Tahoma;}{\f1\froman\fprq2\fcharset0 Times New Roman;}{\f2\fswiss\fprq2\fcharset0 Calibri;}{\f3\fnil\fcharset0 Calibri;}{\f4\fnil\fcharset2 Symbol;}}
|
||||
{\colortbl ;\red31\green73\blue125;\red0\green0\blue255;}
|
||||
{\*\listtable
|
||||
{\list\listhybrid
|
||||
{\listlevel\levelnfc0\leveljc0\levelstartat1{\leveltext\'02\'00.;}{\levelnumbers\'01;}\jclisttab\tx360}
|
||||
{\listlevel\levelnfc4\leveljc0\levelstartat1{\leveltext\'02\'01.;}{\levelnumbers\'01;}\jclisttab\tx363}
|
||||
{\listlevel\levelnfc2\leveljc0\levelstartat1{\leveltext\'02\'02.;}{\levelnumbers\'01;}\jclisttab\tx720}\listid1 }
|
||||
{\list\listhybrid
|
||||
{\listlevel\levelnfc0\leveljc0\levelstartat1{\leveltext\'02\'00.;}{\levelnumbers\'01;}\jclisttab\tx363}
|
||||
{\listlevel\levelnfc4\leveljc0\levelstartat1{\leveltext\'02\'01.;}{\levelnumbers\'01;}\jclisttab\tx363}\listid2 }}
|
||||
{\*\listoverridetable{\listoverride\listid1\listoverridecount0\ls1}{\listoverride\listid2\listoverridecount0\ls2}}
|
||||
{\stylesheet{ Normal;}{\s1 heading 1;}{\s2 heading 2;}{\s3 heading 3;}}
|
||||
{\*\generator Riched20 6.2.9200}\viewkind4\uc1
|
||||
\pard\nowidctlpar\sb120\sa120\b\f0\fs24 MICROSOFT SOFTWARE LICENSE TERMS\par
|
||||
|
||||
\pard\brdrb\brdrs\brdrw10\brsp20 \nowidctlpar\sb120\sa120 MICROSOFT .NET LIBRARY \par
|
||||
|
||||
\pard\nowidctlpar\sb120\sa120\fs19 These license terms are an agreement between Microsoft Corporation (or based on where you live, one of its affiliates) and you. Please read them. They apply to the software named above, which includes the media on which you received it, if any. The terms also apply to any Microsoft\par
|
||||
|
||||
\pard{\pntext\f4\'B7\tab}{\*\pn\pnlvlblt\pnf4\pnindent363{\pntxtb\'B7}}\nowidctlpar\fi-363\li720\sb120\sa120\b0 updates,\par
|
||||
{\pntext\f4\'B7\tab}supplements,\par
|
||||
{\pntext\f4\'B7\tab}Internet-based services, and\par
|
||||
{\pntext\f4\'B7\tab}support services\par
|
||||
|
||||
\pard\nowidctlpar\sb120\sa120\b for this software, unless other terms accompany those items. If so, those terms apply.\par
|
||||
BY USING THE SOFTWARE, YOU ACCEPT THESE TERMS. IF YOU DO NOT ACCEPT THEM, DO NOT USE THE SOFTWARE.\par
|
||||
|
||||
\pard\brdrt\brdrs\brdrw10\brsp20 \nowidctlpar\sb120\sa120 IF YOU COMPLY WITH THESE LICENSE TERMS, YOU HAVE THE PERPETUAL RIGHTS BELOW.\par
|
||||
|
||||
\pard
|
||||
{\listtext\f0 1.\tab}\jclisttab\tx360\ls1\nowidctlpar\s1\fi-357\li357\sb120\sa120 INSTALLATION AND USE RIGHTS. \par
|
||||
|
||||
\pard
|
||||
{\listtext\f0 a.\tab}\jclisttab\tx363\ls1\ilvl1\nowidctlpar\s2\fi-363\li720\sb120\sa120 Installation and Use.\b0\fs20 You may install and use any number of copies of the software to design, develop and test your programs.\par
|
||||
{\listtext\f0 b.\tab}\b\fs19 Third Party Programs.\b0\fs20 The software may include third party programs that Microsoft, not the third party, licenses to you under this agreement. Notices, if any, for the third party program are included for your information only.\b\fs19\par
|
||||
|
||||
\pard
|
||||
{\listtext\f0 2.\tab}\jclisttab\tx360\ls1\nowidctlpar\s1\fi-357\li357\sb120\sa120\fs20 ADDITIONAL LICENSING REQUIREMENTS AND/OR USE RIGHTS.\par
|
||||
|
||||
\pard
|
||||
{\listtext\f0 a.\tab}\jclisttab\tx363\ls1\ilvl1\nowidctlpar\s2\fi-363\li720\sb120\sa120 DISTRIBUTABLE CODE.\~ \b0 The software is comprised of Distributable Code. \f1\ldblquote\f0 Distributable Code\f1\rdblquote\f0 is code that you are permitted to distribute in programs you develop if you comply with the terms below.\b\par
|
||||
|
||||
\pard
|
||||
{\listtext\f0 i.\tab}\jclisttab\tx720\ls1\ilvl2\nowidctlpar\s3\fi-357\li1077\sb120\sa120\tx1077 Right to Use and Distribute. \par
|
||||
|
||||
\pard{\pntext\f4\'B7\tab}{\*\pn\pnlvlblt\pnf4\pnindent360{\pntxtb\'B7}}\nowidctlpar\fi-357\li1434\sb120\sa120\b0 You may copy and distribute the object code form of the software.\par
|
||||
{\pntext\f4\'B7\tab}Third Party Distribution. You may permit distributors of your programs to copy and distribute the Distributable Code as part of those programs.\par
|
||||
|
||||
\pard\nowidctlpar\s3\fi-357\li1077\sb120\sa120\tx1077\b ii.\tab Distribution Requirements.\b0 \b For any Distributable Code you distribute, you must\par
|
||||
|
||||
\pard{\pntext\f4\'B7\tab}{\*\pn\pnlvlblt\pnf4\pnindent360{\pntxtb\'B7}}\nowidctlpar\fi-357\li1434\sb120\sa120\b0 add significant primary functionality to it in your programs;\par
|
||||
{\pntext\f4\'B7\tab}require distributors and external end users to agree to terms that protect it at least as much as this agreement;\par
|
||||
{\pntext\f4\'B7\tab}display your valid copyright notice on your programs; and\par
|
||||
{\pntext\f4\'B7\tab}indemnify, defend, and hold harmless Microsoft from any claims, including attorneys\rquote fees, related to the distribution or use of your programs.\par
|
||||
|
||||
\pard\nowidctlpar\s3\fi-357\li1077\sb120\sa120\tx1077\b iii.\tab Distribution Restrictions.\b0 \b You may not\par
|
||||
|
||||
\pard{\pntext\f4\'B7\tab}{\*\pn\pnlvlblt\pnf4\pnindent360{\pntxtb\'B7}}\nowidctlpar\fi-357\li1434\sb120\sa120\b0 alter any copyright, trademark or patent notice in the Distributable Code;\par
|
||||
{\pntext\f4\'B7\tab}use Microsoft\rquote s trademarks in your programs\rquote names or in a way that suggests your programs come from or are endorsed by Microsoft;\par
|
||||
{\pntext\f4\'B7\tab}include Distributable Code in malicious, deceptive or unlawful programs; or\par
|
||||
{\pntext\f4\'B7\tab}modify or distribute the source code of any Distributable Code so that any part of it becomes subject to an Excluded License. An Excluded License is one that requires, as a condition of use, modification or distribution, that\par
|
||||
|
||||
\pard{\pntext\f4\'B7\tab}{\*\pn\pnlvlblt\pnf4\pnindent360{\pntxtb\'B7}}\nowidctlpar\fi-358\li1792\sb120\sa120 the code be disclosed or distributed in source code form; or\cf1\f2\par
|
||||
{\pntext\f4\'B7\tab}\cf0\f0 others have the right to modify it.\cf1\f2\par
|
||||
|
||||
\pard\nowidctlpar\s1\fi-357\li357\sb120\sa120\cf0\b\f0 3.\tab\fs19 SCOPE OF LICENSE. \b0 The software is licensed, not sold. This agreement only gives you some rights to use the software. Microsoft reserves all other rights. Unless applicable law gives you more rights despite this limitation, you may use the software only as expressly permitted in this agreement. In doing so, you must comply with any technical limitations in the software that only allow you to use it in certain ways. You may not\par
|
||||
|
||||
\pard{\pntext\f4\'B7\tab}{\*\pn\pnlvlblt\pnf4\pnindent363{\pntxtb\'B7}}\nowidctlpar\fi-363\li720\sb120\sa120 work around any technical limitations in the software;\par
|
||||
{\pntext\f4\'B7\tab}reverse engineer, decompile or disassemble the software, except and only to the extent that applicable law expressly permits, despite this limitation;\par
|
||||
{\pntext\f4\'B7\tab}publish the software for others to copy;\par
|
||||
{\pntext\f4\'B7\tab}rent, lease or lend the software;\par
|
||||
{\pntext\f4\'B7\tab}transfer the software or this agreement to any third party; or\par
|
||||
{\pntext\f4\'B7\tab}use the software for commercial software hosting services.\par
|
||||
|
||||
\pard\nowidctlpar\s1\fi-357\li357\sb120\sa120\b\fs20 4.\tab\fs19 BACKUP COPY. \b0 You may make one backup copy of the software. You may use it only to reinstall the software.\par
|
||||
\b\fs20 5.\tab\fs19 DOCUMENTATION. \b0 Any person that has valid access to your computer or internal network may copy and use the documentation for your internal, reference purposes.\par
|
||||
\b\fs20 6.\tab\fs19 EXPORT RESTRICTIONS. \b0 The software is subject to United States export laws and regulations. You must comply with all domestic and international export laws and regulations that apply to the software. These laws include restrictions on destinations, end users and end use. For additional information, see {\cf2\ul\fs20{\field{\*\fldinst{HYPERLINK www.microsoft.com/exporting }}{\fldrslt{www.microsoft.com/exporting}}}}\f0\fs19 .\cf2\ul\fs20\par
|
||||
\cf0\ulnone\b 7.\tab\fs19 SUPPORT SERVICES. \b0 Because this software is \ldblquote as is,\rdblquote we may not provide support services for it.\par
|
||||
\b\fs20 8.\tab\fs19 ENTIRE AGREEMENT. \b0 This agreement, and the terms for supplements, updates, Internet-based services and support services that you use, are the entire agreement for the software and support services.\par
|
||||
\b\fs20 9.\tab\fs19 APPLICABLE LAW.\par
|
||||
|
||||
\pard
|
||||
{\listtext\f0 a.\tab}\jclisttab\tx363\ls2\ilvl1\nowidctlpar\s2\fi-363\li720\sb120\sa120 United States. \b0 If you acquired the software in the United States, Washington state law governs the interpretation of this agreement and applies to claims for breach of it, regardless of conflict of laws principles. The laws of the state where you live govern all other claims, including claims under state consumer protection laws, unfair competition laws, and in tort.\par
|
||||
{\listtext\f0 b.\tab}\b Outside the United States. If you acquired the software in any other country, the laws of that country apply.\par
|
||||
|
||||
\pard\nowidctlpar\s1\fi-357\li357\sb120\sa120\fs20 10.\tab\fs19 LEGAL EFFECT. \b0 This agreement describes certain legal rights. You may have other rights under the laws of your country. You may also have rights with respect to the party from whom you acquired the software. This agreement does not change your rights under the laws of your country if the laws of your country do not permit it to do so.\par
|
||||
\b\fs20 11.\tab\fs19 DISCLAIMER OF WARRANTY. THE SOFTWARE IS LICENSED \ldblquote AS-IS.\rdblquote YOU BEAR THE RISK OF USING IT. MICROSOFT GIVES NO EXPRESS WARRANTIES, GUARANTEES OR CONDITIONS. YOU MAY HAVE ADDITIONAL CONSUMER RIGHTS OR STATUTORY GUARANTEES UNDER YOUR LOCAL LAWS WHICH THIS AGREEMENT CANNOT CHANGE. TO THE EXTENT PERMITTED UNDER YOUR LOCAL LAWS, MICROSOFT EXCLUDES THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.\par
|
||||
|
||||
\pard\nowidctlpar\li357\sb120\sa120 FOR AUSTRALIA \endash YOU HAVE STATUTORY GUARANTEES UNDER THE AUSTRALIAN CONSUMER LAW AND NOTHING IN THESE TERMS IS INTENDED TO AFFECT THOSE RIGHTS.\par
|
||||
|
||||
\pard\nowidctlpar\s1\fi-357\li357\sb120\sa120\fs20 12.\tab\fs19 LIMITATION ON AND EXCLUSION OF REMEDIES AND DAMAGES. YOU CAN RECOVER FROM MICROSOFT AND ITS SUPPLIERS ONLY DIRECT DAMAGES UP TO U.S. $5.00. YOU CANNOT RECOVER ANY OTHER DAMAGES, INCLUDING CONSEQUENTIAL, LOST PROFITS, SPECIAL, INDIRECT OR INCIDENTAL DAMAGES.\par
|
||||
|
||||
\pard\nowidctlpar\li357\sb120\sa120\b0 This limitation applies to\par
|
||||
|
||||
\pard{\pntext\f4\'B7\tab}{\*\pn\pnlvlblt\pnf4\pnindent363{\pntxtb\'B7}}\nowidctlpar\fi-363\li720\sb120\sa120 anything related to the software, services, content (including code) on third party Internet sites, or third party programs; and\par
|
||||
{\pntext\f4\'B7\tab}claims for breach of contract, breach of warranty, guarantee or condition, strict liability, negligence, or other tort to the extent permitted by applicable law.\par
|
||||
|
||||
\pard\nowidctlpar\sb120\sa120 It also applies even if Microsoft knew or should have known about the possibility of the damages. The above limitation or exclusion may not apply to you because your country may not allow the exclusion or limitation of incidental, consequential or other damages.\par
|
||||
\lang9 Please note: As this software is distributed in Quebec, Canada, some of the clauses in this agreement are provided below in French.\par
|
||||
Remarque : Ce logiciel \'e9tant distribu\'e9 au Qu\'e9bec, Canada, certaines des clauses dans ce contrat sont fournies ci-dessous en fran\'e7ais.\par
|
||||
|
||||
\pard\nowidctlpar\s1\sb120\sa120\b\lang1033 EXON\'c9RATION DE GARANTIE. \b0 Le logiciel vis\'e9 par une licence est offert \'ab tel quel \'bb. Toute utilisation de ce logiciel est \'e0 votre seule risque et p\'e9ril. Microsoft n\rquote accorde aucune autre garantie expresse. Vous pouvez b\'e9n\'e9ficier de droits additionnels en vertu du droit local sur la protection des consommateurs, que ce contrat ne peut modifier. La ou elles sont permises par le droit locale, les garanties implicites de qualit\'e9 marchande, d\rquote ad\'e9quation \'e0 un usage particulier et d\rquote absence de contrefa\'e7on sont exclues.\par
|
||||
\b LIMITATION DES DOMMAGES-INT\'c9R\'caTS ET EXCLUSION DE RESPONSABILIT\'c9 POUR LES DOMMAGES. \b0 Vous pouvez obtenir de Microsoft et de ses fournisseurs une indemnisation en cas de dommages directs uniquement \'e0 hauteur de 5,00 $ US. Vous ne pouvez pr\'e9tendre \'e0 aucune indemnisation pour les autres dommages, y compris les dommages sp\'e9ciaux, indirects ou accessoires et pertes de b\'e9n\'e9fices.\par
|
||||
|
||||
\pard\nowidctlpar\sb120\sa120\lang9 Cette limitation concerne :\par
|
||||
|
||||
\pard{\pntext\f4\'B7\tab}{\*\pn\pnlvlblt\pnf4\pnindent360{\pntxtb\'B7}}\nowidctlpar\li720\sb120\sa120 tout ce qui est reli\'e9 au logiciel, aux services ou au contenu (y compris le code) figurant sur des sites Internet tiers ou dans des programmes tiers ; et\par
|
||||
{\pntext\f4\'B7\tab}les r\'e9clamations au titre de violation de contrat ou de garantie, ou au titre de responsabilit\'e9 stricte, de n\'e9gligence ou d\rquote une autre faute dans la limite autoris\'e9e par la loi en vigueur.\par
|
||||
|
||||
\pard\nowidctlpar\sb120\sa120 Elle s\rquote applique \'e9galement, m\'eame si Microsoft connaissait ou devrait conna\'eetre l\rquote\'e9ventualit\'e9 d\rquote un tel dommage. Si votre pays n\rquote autorise pas l\rquote exclusion ou la limitation de responsabilit\'e9 pour les dommages indirects, accessoires ou de quelque nature que ce soit, il se peut que la limitation ou l\rquote exclusion ci-dessus ne s\rquote appliquera pas \'e0 votre \'e9gard.\par
|
||||
|
||||
\pard\nowidctlpar\s1\sb120\sa120\b\lang1033 EFFET JURIDIQUE. \b0 Le pr\'e9sent contrat d\'e9crit certains droits juridiques. Vous pourriez avoir d\rquote autres droits pr\'e9vus par les lois de votre pays. Le pr\'e9sent contrat ne modifie pas les droits que vous conf\'e8rent les lois de votre pays si celles-ci ne le permettent pas.\par
|
||||
|
||||
\pard\nowidctlpar\sb120\sa120\b\fs20\lang1036\par
|
||||
|
||||
\pard\sa200\sl276\slmult1\b0\f3\fs22\lang9\par
|
||||
}
|
||||
| ||||