mirror of
https://github.com/JustArchiNET/ArchiSteamFarm.git
synced 2025-12-17 06:50:29 +00:00
Compare commits
25 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9a745ffb97 | ||
|
|
df95c6c6b0 | ||
|
|
9711187940 | ||
|
|
f009f1b834 | ||
|
|
f4187e194e | ||
|
|
32b2ea9fb7 | ||
|
|
6e87ee3718 | ||
|
|
a718d1cefe | ||
|
|
019f347be4 | ||
|
|
5b2b00a9f0 | ||
|
|
e6e1b6f061 | ||
|
|
88a7d2e7e9 | ||
|
|
b223fc2d97 | ||
|
|
589f4f5746 | ||
|
|
c4e7bbbf0c | ||
|
|
bbb43600e5 | ||
|
|
c602654800 | ||
|
|
7a49dc5188 | ||
|
|
f1b84e57e4 | ||
|
|
3db5830f7b | ||
|
|
4acc71485e | ||
|
|
7822210cc0 | ||
|
|
c46eee4499 | ||
|
|
ad09b1dec9 | ||
|
|
e640f82712 |
14
.travis.yml
14
.travis.yml
@@ -17,6 +17,8 @@ mono: none
|
||||
|
||||
# ASF requires .NET Core 2.0+
|
||||
# TODO: We should target stable 2.0.0 once it's released
|
||||
# TODO: Update at least to preview2 once https://github.com/travis-ci/travis-ci/issues/8037 is fixed
|
||||
# TODO: Add --no-restore to dotnet test when we get preview2+
|
||||
dotnet: 2.0.0-preview1-005977
|
||||
|
||||
env:
|
||||
@@ -28,6 +30,7 @@ script:
|
||||
- set -e
|
||||
- dotnet restore
|
||||
- dotnet build -c Release
|
||||
- dotnet test -c Release --no-build ArchiSteamFarm.Tests
|
||||
- dotnet publish -c Release -o out/generic
|
||||
- echo "generic" > "ArchiSteamFarm/out/generic/ArchiSteamFarm.version"
|
||||
- dotnet publish -c Release -r win-x64 -o out/win-x64
|
||||
@@ -39,16 +42,17 @@ script:
|
||||
- dotnet publish -c Release -r osx-x64 -o out/osx-x64
|
||||
- echo "osx-x64" > "ArchiSteamFarm/out/osx-x64/ArchiSteamFarm.version"
|
||||
|
||||
# This is our main build matrix
|
||||
matrix:
|
||||
# We can use fast finish, as we don't need to wait for all builds to mark it as failed/passed
|
||||
# We can use fast finish, as we don't need to wait for allow_failures builds to mark build as success
|
||||
fast_finish: true
|
||||
allow_failures:
|
||||
# We allow OS X to fail until https://github.com/travis-ci/travis-ci/issues/7757 is fixed
|
||||
# TODO: We allow OS X to fail until https://github.com/travis-ci/travis-ci/issues/7757 is fixed
|
||||
- os: osx
|
||||
include:
|
||||
# We're building ASF with dotnet on latest versions of Linux and OS X
|
||||
# Ref: https://docs.travis-ci.com/user/ci-environment/#Virtualization-environments
|
||||
# We're building ASF with dotnet on latest versions of Linux and OS X
|
||||
# Ref: https://docs.travis-ci.com/user/ci-environment/#Virtualization-environments
|
||||
# Ref: https://docs.travis-ci.com/user/trusty-ci-environment/
|
||||
# Ref: https://docs.travis-ci.com/user/osx-ci-environment/
|
||||
- os: linux
|
||||
dist: trusty
|
||||
sudo: false
|
||||
|
||||
30
ArchiSteamFarm.Tests/ArchiSteamFarm.Tests.csproj
Normal file
30
ArchiSteamFarm.Tests/ArchiSteamFarm.Tests.csproj
Normal file
@@ -0,0 +1,30 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>netcoreapp2.0</TargetFramework>
|
||||
<LangVersion>latest</LangVersion>
|
||||
<ErrorReport>none</ErrorReport>
|
||||
<RuntimeIdentifiers>win-x64;linux-x64;linux-arm;osx-x64</RuntimeIdentifiers>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
|
||||
<DebugType>none</DebugType>
|
||||
<DebugSymbols>false</DebugSymbols>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.3.0-preview-20170628-02" />
|
||||
<PackageReference Include="MSTest.TestAdapter" Version="1.2.0-beta" />
|
||||
<PackageReference Include="MSTest.TestFramework" Version="1.2.0-beta" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\ArchiSteamFarm\ArchiSteamFarm.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Service Include="{82a7f48d-3b50-4b1e-b82e-3ada8210c358}" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
175
ArchiSteamFarm.Tests/Trading.cs
Normal file
175
ArchiSteamFarm.Tests/Trading.cs
Normal file
@@ -0,0 +1,175 @@
|
||||
/*
|
||||
_ _ _ ____ _ _____
|
||||
/ \ _ __ ___ | |__ (_)/ ___| | |_ ___ __ _ _ __ ___ | ___|__ _ _ __ _ __ ___
|
||||
/ _ \ | '__|/ __|| '_ \ | |\___ \ | __|/ _ \ / _` || '_ ` _ \ | |_ / _` || '__|| '_ ` _ \
|
||||
/ ___ \ | | | (__ | | | || | ___) || |_| __/| (_| || | | | | || _|| (_| || | | | | | | |
|
||||
/_/ \_\|_| \___||_| |_||_||____/ \__|\___| \__,_||_| |_| |_||_| \__,_||_| |_| |_| |_|
|
||||
|
||||
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.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using ArchiSteamFarm.JSON;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
|
||||
namespace ArchiSteamFarm.Tests {
|
||||
[TestClass]
|
||||
public sealed class Trading {
|
||||
[TestMethod]
|
||||
public void TradingMultiGameBadReject() {
|
||||
Steam.Item item1Game1 = new Steam.Item(Steam.Item.SteamAppID, Steam.Item.SteamCommunityContextID, 1, 1, 570, Steam.Item.EType.TradingCard);
|
||||
Steam.Item item1Game1X9 = new Steam.Item(Steam.Item.SteamAppID, Steam.Item.SteamCommunityContextID, 1, 9, 570, Steam.Item.EType.TradingCard);
|
||||
Steam.Item item2Game1 = new Steam.Item(Steam.Item.SteamAppID, Steam.Item.SteamCommunityContextID, 2, 1, 570, Steam.Item.EType.TradingCard);
|
||||
|
||||
Steam.Item item1Game2 = new Steam.Item(Steam.Item.SteamAppID, Steam.Item.SteamCommunityContextID, 3, 1, 730, Steam.Item.EType.TradingCard);
|
||||
Steam.Item item2Game2 = new Steam.Item(Steam.Item.SteamAppID, Steam.Item.SteamCommunityContextID, 4, 1, 730, Steam.Item.EType.TradingCard);
|
||||
|
||||
HashSet<Steam.Item> inventory = new HashSet<Steam.Item> { item1Game1X9, item1Game2, item2Game2 };
|
||||
HashSet<Steam.Item> itemsToGive = new HashSet<Steam.Item> { item1Game1, item1Game2 };
|
||||
HashSet<Steam.Item> itemsToReceive = new HashSet<Steam.Item> { item2Game1, item2Game2 };
|
||||
|
||||
Assert.IsFalse(AcceptsTrade(inventory, itemsToGive, itemsToReceive));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void TradingMultiGameMultiTypeBadReject() {
|
||||
Steam.Item item1Type1Game1 = new Steam.Item(Steam.Item.SteamAppID, Steam.Item.SteamCommunityContextID, 1, 1, 570, Steam.Item.EType.TradingCard);
|
||||
Steam.Item item1Type1Game1X9 = new Steam.Item(Steam.Item.SteamAppID, Steam.Item.SteamCommunityContextID, 1, 9, 570, Steam.Item.EType.TradingCard);
|
||||
Steam.Item item2Type1Game1 = new Steam.Item(Steam.Item.SteamAppID, Steam.Item.SteamCommunityContextID, 2, 1, 570, Steam.Item.EType.TradingCard);
|
||||
|
||||
Steam.Item item3Type2Game2 = new Steam.Item(Steam.Item.SteamAppID, Steam.Item.SteamCommunityContextID, 3, 1, 730, Steam.Item.EType.Emoticon);
|
||||
Steam.Item item3Type2Game2X9 = new Steam.Item(Steam.Item.SteamAppID, Steam.Item.SteamCommunityContextID, 3, 9, 730, Steam.Item.EType.Emoticon);
|
||||
Steam.Item item4Type2Game2 = new Steam.Item(Steam.Item.SteamAppID, Steam.Item.SteamCommunityContextID, 4, 1, 730, Steam.Item.EType.Emoticon);
|
||||
|
||||
HashSet<Steam.Item> inventory = new HashSet<Steam.Item> { item1Type1Game1X9, item3Type2Game2X9, item4Type2Game2 };
|
||||
HashSet<Steam.Item> itemsToGive = new HashSet<Steam.Item> { item1Type1Game1, item4Type2Game2 };
|
||||
HashSet<Steam.Item> itemsToReceive = new HashSet<Steam.Item> { item2Type1Game1, item3Type2Game2 };
|
||||
|
||||
Assert.IsFalse(AcceptsTrade(inventory, itemsToGive, itemsToReceive));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void TradingMultiGameMultiTypeNeutralAccept() {
|
||||
Steam.Item item1Type1Game1 = new Steam.Item(Steam.Item.SteamAppID, Steam.Item.SteamCommunityContextID, 1, 1, 570, Steam.Item.EType.TradingCard);
|
||||
Steam.Item item1Type1Game1X9 = new Steam.Item(Steam.Item.SteamAppID, Steam.Item.SteamCommunityContextID, 1, 9, 570, Steam.Item.EType.TradingCard);
|
||||
Steam.Item item2Type1Game1 = new Steam.Item(Steam.Item.SteamAppID, Steam.Item.SteamCommunityContextID, 2, 1, 570, Steam.Item.EType.TradingCard);
|
||||
|
||||
Steam.Item item3Type2Game2 = new Steam.Item(Steam.Item.SteamAppID, Steam.Item.SteamCommunityContextID, 3, 1, 730, Steam.Item.EType.Emoticon);
|
||||
Steam.Item item4Type2Game2 = new Steam.Item(Steam.Item.SteamAppID, Steam.Item.SteamCommunityContextID, 4, 1, 730, Steam.Item.EType.Emoticon);
|
||||
|
||||
HashSet<Steam.Item> inventory = new HashSet<Steam.Item> { item1Type1Game1X9, item3Type2Game2 };
|
||||
HashSet<Steam.Item> itemsToGive = new HashSet<Steam.Item> { item1Type1Game1, item3Type2Game2 };
|
||||
HashSet<Steam.Item> itemsToReceive = new HashSet<Steam.Item> { item2Type1Game1, item4Type2Game2 };
|
||||
|
||||
Assert.IsTrue(AcceptsTrade(inventory, itemsToGive, itemsToReceive));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void TradingMultiGameNeutralAccept() {
|
||||
Steam.Item item1Game1 = new Steam.Item(Steam.Item.SteamAppID, Steam.Item.SteamCommunityContextID, 1, 1, 570, Steam.Item.EType.TradingCard);
|
||||
Steam.Item item1Game1X2 = new Steam.Item(Steam.Item.SteamAppID, Steam.Item.SteamCommunityContextID, 1, 2, 570, Steam.Item.EType.TradingCard);
|
||||
Steam.Item item2Game1 = new Steam.Item(Steam.Item.SteamAppID, Steam.Item.SteamCommunityContextID, 2, 1, 570, Steam.Item.EType.TradingCard);
|
||||
|
||||
Steam.Item item1Game2 = new Steam.Item(Steam.Item.SteamAppID, Steam.Item.SteamCommunityContextID, 1, 1, 730, Steam.Item.EType.TradingCard);
|
||||
Steam.Item item2Game2 = new Steam.Item(Steam.Item.SteamAppID, Steam.Item.SteamCommunityContextID, 2, 1, 730, Steam.Item.EType.TradingCard);
|
||||
|
||||
HashSet<Steam.Item> inventory = new HashSet<Steam.Item> { item1Game1X2, item1Game2 };
|
||||
HashSet<Steam.Item> itemsToGive = new HashSet<Steam.Item> { item1Game1, item1Game2 };
|
||||
HashSet<Steam.Item> itemsToReceive = new HashSet<Steam.Item> { item2Game1, item2Game2 };
|
||||
|
||||
Assert.IsTrue(AcceptsTrade(inventory, itemsToGive, itemsToReceive));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void TradingSingleGameBadReject() {
|
||||
Steam.Item item1 = new Steam.Item(Steam.Item.SteamAppID, Steam.Item.SteamCommunityContextID, 1, 1, 570, Steam.Item.EType.TradingCard);
|
||||
Steam.Item item2 = new Steam.Item(Steam.Item.SteamAppID, Steam.Item.SteamCommunityContextID, 2, 1, 570, Steam.Item.EType.TradingCard);
|
||||
|
||||
HashSet<Steam.Item> inventory = new HashSet<Steam.Item> { item1, item2 };
|
||||
HashSet<Steam.Item> itemsToGive = new HashSet<Steam.Item> { item1 };
|
||||
HashSet<Steam.Item> itemsToReceive = new HashSet<Steam.Item> { item2 };
|
||||
|
||||
Assert.IsFalse(AcceptsTrade(inventory, itemsToGive, itemsToReceive));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void TradingSingleGameGoodAccept() {
|
||||
Steam.Item item1 = new Steam.Item(Steam.Item.SteamAppID, Steam.Item.SteamCommunityContextID, 1, 1, 570, Steam.Item.EType.TradingCard);
|
||||
Steam.Item item1X2 = new Steam.Item(Steam.Item.SteamAppID, Steam.Item.SteamCommunityContextID, 1, 2, 570, Steam.Item.EType.TradingCard);
|
||||
Steam.Item item2 = new Steam.Item(Steam.Item.SteamAppID, Steam.Item.SteamCommunityContextID, 2, 1, 570, Steam.Item.EType.TradingCard);
|
||||
|
||||
HashSet<Steam.Item> inventory = new HashSet<Steam.Item> { item1X2 };
|
||||
HashSet<Steam.Item> itemsToGive = new HashSet<Steam.Item> { item1 };
|
||||
HashSet<Steam.Item> itemsToReceive = new HashSet<Steam.Item> { item2 };
|
||||
|
||||
Assert.IsTrue(AcceptsTrade(inventory, itemsToGive, itemsToReceive));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void TradingSingleGameMultiTypeBadReject() {
|
||||
Steam.Item item1Type1 = new Steam.Item(Steam.Item.SteamAppID, Steam.Item.SteamCommunityContextID, 1, 1, 570, Steam.Item.EType.TradingCard);
|
||||
Steam.Item item1Type1X9 = new Steam.Item(Steam.Item.SteamAppID, Steam.Item.SteamCommunityContextID, 1, 9, 570, Steam.Item.EType.TradingCard);
|
||||
Steam.Item item2Type1 = new Steam.Item(Steam.Item.SteamAppID, Steam.Item.SteamCommunityContextID, 2, 1, 570, Steam.Item.EType.TradingCard);
|
||||
|
||||
Steam.Item item3Type2 = new Steam.Item(Steam.Item.SteamAppID, Steam.Item.SteamCommunityContextID, 3, 1, 570, Steam.Item.EType.Emoticon);
|
||||
Steam.Item item3Type2X9 = new Steam.Item(Steam.Item.SteamAppID, Steam.Item.SteamCommunityContextID, 3, 9, 570, Steam.Item.EType.Emoticon);
|
||||
Steam.Item item4Type2 = new Steam.Item(Steam.Item.SteamAppID, Steam.Item.SteamCommunityContextID, 4, 1, 570, Steam.Item.EType.Emoticon);
|
||||
|
||||
HashSet<Steam.Item> inventory = new HashSet<Steam.Item> { item1Type1X9, item3Type2X9, item4Type2 };
|
||||
HashSet<Steam.Item> itemsToGive = new HashSet<Steam.Item> { item1Type1, item4Type2 };
|
||||
HashSet<Steam.Item> itemsToReceive = new HashSet<Steam.Item> { item2Type1, item3Type2 };
|
||||
|
||||
Assert.IsFalse(AcceptsTrade(inventory, itemsToGive, itemsToReceive));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void TradingSingleGameMultiTypeNeutralAccept() {
|
||||
Steam.Item item1Type1 = new Steam.Item(Steam.Item.SteamAppID, Steam.Item.SteamCommunityContextID, 1, 1, 570, Steam.Item.EType.TradingCard);
|
||||
Steam.Item item1Type1X9 = new Steam.Item(Steam.Item.SteamAppID, Steam.Item.SteamCommunityContextID, 1, 9, 570, Steam.Item.EType.TradingCard);
|
||||
Steam.Item item2Type1 = new Steam.Item(Steam.Item.SteamAppID, Steam.Item.SteamCommunityContextID, 2, 1, 570, Steam.Item.EType.TradingCard);
|
||||
|
||||
Steam.Item item3Type2 = new Steam.Item(Steam.Item.SteamAppID, Steam.Item.SteamCommunityContextID, 3, 1, 570, Steam.Item.EType.Emoticon);
|
||||
Steam.Item item4Type2 = new Steam.Item(Steam.Item.SteamAppID, Steam.Item.SteamCommunityContextID, 4, 1, 570, Steam.Item.EType.Emoticon);
|
||||
|
||||
HashSet<Steam.Item> inventory = new HashSet<Steam.Item> { item1Type1X9, item3Type2 };
|
||||
HashSet<Steam.Item> itemsToGive = new HashSet<Steam.Item> { item1Type1, item3Type2 };
|
||||
HashSet<Steam.Item> itemsToReceive = new HashSet<Steam.Item> { item2Type1, item4Type2 };
|
||||
|
||||
Assert.IsTrue(AcceptsTrade(inventory, itemsToGive, itemsToReceive));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void TradingSingleGameNeutralAccept() {
|
||||
Steam.Item item1 = new Steam.Item(Steam.Item.SteamAppID, Steam.Item.SteamCommunityContextID, 1, 1, 570, Steam.Item.EType.TradingCard);
|
||||
Steam.Item item2 = new Steam.Item(Steam.Item.SteamAppID, Steam.Item.SteamCommunityContextID, 2, 1, 570, Steam.Item.EType.TradingCard);
|
||||
|
||||
HashSet<Steam.Item> inventory = new HashSet<Steam.Item> { item1 };
|
||||
HashSet<Steam.Item> itemsToGive = new HashSet<Steam.Item> { item1 };
|
||||
HashSet<Steam.Item> itemsToReceive = new HashSet<Steam.Item> { item2 };
|
||||
|
||||
Assert.IsTrue(AcceptsTrade(inventory, itemsToGive, itemsToReceive));
|
||||
}
|
||||
|
||||
private static bool AcceptsTrade(HashSet<Steam.Item> inventory, HashSet<Steam.Item> itemsToGive, HashSet<Steam.Item> itemsToReceive) {
|
||||
Type trading = typeof(ArchiSteamFarm.Trading);
|
||||
MethodInfo method = trading.GetMethod("IsTradeNeutralOrBetter", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static);
|
||||
return (bool) method.Invoke(null, new object[] { inventory, itemsToGive, itemsToReceive });
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,12 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 15
|
||||
VisualStudioVersion = 15.0.26608.5
|
||||
VisualStudioVersion = 15.0.26621.2
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ArchiSteamFarm", "ArchiSteamFarm\ArchiSteamFarm.csproj", "{CF84911C-2C4C-4195-8AF3-ABBB6D3DE9AA}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ArchiSteamFarm.Tests", "ArchiSteamFarm.Tests\ArchiSteamFarm.Tests.csproj", "{91DC4C4F-3C23-4716-8CB2-BC7EAB65D759}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
@@ -15,8 +17,15 @@ Global
|
||||
{CF84911C-2C4C-4195-8AF3-ABBB6D3DE9AA}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{CF84911C-2C4C-4195-8AF3-ABBB6D3DE9AA}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{CF84911C-2C4C-4195-8AF3-ABBB6D3DE9AA}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{91DC4C4F-3C23-4716-8CB2-BC7EAB65D759}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{91DC4C4F-3C23-4716-8CB2-BC7EAB65D759}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{91DC4C4F-3C23-4716-8CB2-BC7EAB65D759}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{91DC4C4F-3C23-4716-8CB2-BC7EAB65D759}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {D7D54143-C857-4B76-A219-0E98C5BC4895}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
|
||||
@@ -117,7 +117,7 @@
|
||||
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/ALLOW_COMMENT_AFTER_LBRACE/@EntryValue">False</s:Boolean>
|
||||
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/ANONYMOUS_METHOD_DECLARATION_BRACES/@EntryValue">END_OF_LINE</s:String>
|
||||
<s:Int64 x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/BLANK_LINES_AFTER_CONTROL_TRANSFER_STATEMENTS/@EntryValue">1</s:Int64>
|
||||
<s:Int64 x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/BLANK_LINES_AROUND_FIELD/@EntryValue">0</s:Int64>
|
||||
<s:Int64 x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/BLANK_LINES_AROUND_FIELD/@EntryValue">1</s:Int64>
|
||||
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/CASE_BLOCK_BRACES/@EntryValue">END_OF_LINE</s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/EMPTY_BLOCK_STYLE/@EntryValue">TOGETHER_SAME_LINE</s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/INDENT_STYLE/@EntryValue">Tab</s:String>
|
||||
@@ -384,4 +384,5 @@
|
||||
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EAlwaysTreatStructAsNotReorderableMigration/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EMigrateBlankLinesAroundFieldToBlankLinesAroundProperty/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EMigrateThisQualifierSettings/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002EXml_002ECodeStyle_002EFormatSettingsUpgrade_002EXmlMoveToCommonFormatterSettingsUpgrade/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>
|
||||
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002EXml_002ECodeStyle_002EFormatSettingsUpgrade_002EXmlMoveToCommonFormatterSettingsUpgrade/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Int64 x:Key="/Default/Environment/UnitTesting/ParallelProcessesCount/@EntryValue">8</s:Int64></wpf:ResourceDictionary>
|
||||
@@ -46,32 +46,6 @@ namespace ArchiSteamFarm {
|
||||
private static FileSystemWatcher FileSystemWatcher;
|
||||
|
||||
internal static async Task CheckForUpdate(bool updateOverride = false) {
|
||||
string targetDirectory = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);
|
||||
|
||||
// Cleanup from previous update - update directory for old in-use runtime files
|
||||
string backupDirectory = Path.Combine(targetDirectory, SharedInfo.UpdateDirectory);
|
||||
if (Directory.Exists(backupDirectory)) {
|
||||
// It's entirely possible that old process is still running, wait at least a second for eventual cleanup
|
||||
await Task.Delay(1000).ConfigureAwait(false);
|
||||
|
||||
try {
|
||||
Directory.Delete(backupDirectory, true);
|
||||
} catch (Exception e) {
|
||||
ArchiLogger.LogGenericException(e);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Cleanup from previous update - old non-runtime in-use files
|
||||
foreach (string file in Directory.GetFiles(targetDirectory, "*.old", SearchOption.AllDirectories)) {
|
||||
try {
|
||||
File.Delete(file);
|
||||
} catch (Exception e) {
|
||||
ArchiLogger.LogGenericException(e);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (Program.GlobalConfig.UpdateChannel == GlobalConfig.EUpdateChannel.None) {
|
||||
return;
|
||||
}
|
||||
@@ -102,7 +76,7 @@ namespace ArchiSteamFarm {
|
||||
}
|
||||
|
||||
version = version.TrimEnd();
|
||||
if (string.IsNullOrEmpty(version) || !IsVersionValid(version)) {
|
||||
if (string.IsNullOrEmpty(version) || !IsValidVersion(version)) {
|
||||
ArchiLogger.LogGenericError(string.Format(Strings.ErrorIsInvalid, SharedInfo.VersionFile));
|
||||
return;
|
||||
}
|
||||
@@ -120,13 +94,39 @@ namespace ArchiSteamFarm {
|
||||
ArchiLogger.LogGenericInfo(string.Format(Strings.AutoUpdateCheckInfo, autoUpdatePeriod.ToHumanReadable()));
|
||||
}
|
||||
|
||||
ArchiLogger.LogGenericInfo(Strings.UpdateCheckingNewVersion);
|
||||
|
||||
string targetDirectory = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);
|
||||
|
||||
// Cleanup from previous update - update directory for old in-use runtime files
|
||||
string backupDirectory = Path.Combine(targetDirectory, SharedInfo.UpdateDirectory);
|
||||
if (Directory.Exists(backupDirectory)) {
|
||||
// It's entirely possible that old process is still running, wait a short moment for eventual cleanup
|
||||
await Task.Delay(5000).ConfigureAwait(false);
|
||||
|
||||
try {
|
||||
Directory.Delete(backupDirectory, true);
|
||||
} catch (Exception e) {
|
||||
ArchiLogger.LogGenericException(e);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Cleanup from previous update - old non-runtime in-use files
|
||||
foreach (string file in Directory.EnumerateFiles(targetDirectory, "*.old", SearchOption.AllDirectories)) {
|
||||
try {
|
||||
File.Delete(file);
|
||||
} catch (Exception e) {
|
||||
ArchiLogger.LogGenericException(e);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
string releaseURL = SharedInfo.GithubReleaseURL;
|
||||
if (Program.GlobalConfig.UpdateChannel == GlobalConfig.EUpdateChannel.Stable) {
|
||||
releaseURL += "/latest";
|
||||
}
|
||||
|
||||
ArchiLogger.LogGenericInfo(Strings.UpdateCheckingNewVersion);
|
||||
|
||||
GitHub.ReleaseResponse releaseResponse;
|
||||
|
||||
if (Program.GlobalConfig.UpdateChannel == GlobalConfig.EUpdateChannel.Stable) {
|
||||
@@ -189,7 +189,7 @@ namespace ArchiSteamFarm {
|
||||
return;
|
||||
}
|
||||
|
||||
ArchiLogger.LogGenericInfo(Strings.UpdateDownloadingNewVersion);
|
||||
ArchiLogger.LogGenericInfo(string.Format(Strings.UpdateDownloadingNewVersion, newVersion, binaryAsset.Size / 1024 / 1024));
|
||||
|
||||
byte[] result = await Program.WebBrowser.UrlGetToBytesRetry(binaryAsset.DownloadURL).ConfigureAwait(false);
|
||||
if (result == null) {
|
||||
@@ -217,14 +217,7 @@ namespace ArchiSteamFarm {
|
||||
// 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).Where(botName => !string.IsNullOrEmpty(botName) && (botName[0] != '.'))) {
|
||||
switch (botName) {
|
||||
case SharedInfo.ASF:
|
||||
case "example":
|
||||
case "minimal":
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach (string botName in Directory.EnumerateFiles(SharedInfo.ConfigDirectory, "*.json").Select(Path.GetFileNameWithoutExtension).Where(botName => !string.IsNullOrEmpty(botName) && IsValidBotName(botName)).OrderBy(botName => botName)) {
|
||||
Bot.RegisterBot(botName);
|
||||
}
|
||||
|
||||
@@ -270,7 +263,27 @@ namespace ArchiSteamFarm {
|
||||
Bot.RegisterBot(botName);
|
||||
}
|
||||
|
||||
private static bool IsVersionValid(string version) {
|
||||
private static bool IsValidBotName(string botName) {
|
||||
if (string.IsNullOrEmpty(botName)) {
|
||||
ArchiLogger.LogNullError(nameof(botName));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (botName[0] == '.') {
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (botName) {
|
||||
case SharedInfo.ASF:
|
||||
case "example":
|
||||
case "minimal":
|
||||
return false;
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
private static bool IsValidVersion(string version) {
|
||||
if (string.IsNullOrEmpty(version)) {
|
||||
ArchiLogger.LogNullError(nameof(version));
|
||||
return false;
|
||||
@@ -278,9 +291,10 @@ namespace ArchiSteamFarm {
|
||||
|
||||
switch (version) {
|
||||
case "generic":
|
||||
case "win-x64":
|
||||
case "linux-arm":
|
||||
case "linux-x64":
|
||||
case "osx-x64":
|
||||
case "win-x64":
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
@@ -438,7 +452,7 @@ namespace ArchiSteamFarm {
|
||||
|
||||
// Move top-level runtime in-use files to other directory
|
||||
// We must do it in order to not crash at later stage - all libraries/executables must keep original names
|
||||
foreach (string file in Directory.GetFiles(targetDirectory)) {
|
||||
foreach (string file in Directory.EnumerateFiles(targetDirectory)) {
|
||||
string target = Path.Combine(backupDirectory, Path.GetFileName(file));
|
||||
File.Move(file, target);
|
||||
}
|
||||
@@ -446,7 +460,7 @@ namespace ArchiSteamFarm {
|
||||
// In generic ASF variant there can also be "runtimes" directory in need of same approach
|
||||
string runtimesDirectory = Path.Combine(targetDirectory, "runtimes");
|
||||
if (Directory.Exists(runtimesDirectory)) {
|
||||
foreach (string file in Directory.GetFiles(runtimesDirectory, "*", SearchOption.AllDirectories)) {
|
||||
foreach (string file in Directory.EnumerateFiles(runtimesDirectory, "*", SearchOption.AllDirectories)) {
|
||||
string directory = Path.Combine(backupDirectory, Path.GetDirectoryName(Path.GetRelativePath(targetDirectory, file)));
|
||||
Directory.CreateDirectory(directory);
|
||||
|
||||
|
||||
@@ -336,6 +336,7 @@ namespace ArchiSteamFarm {
|
||||
[SuppressMessage("ReSharper", "UnusedMember.Global")]
|
||||
Unknown = 0,
|
||||
Trading = 1,
|
||||
|
||||
// Only custom below, different than ones available as user_notification_type
|
||||
Items = 254
|
||||
}
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>netcoreapp2.0</TargetFramework>
|
||||
<AssemblyVersion>3.0.0.1</AssemblyVersion>
|
||||
<FileVersion>3.0.0.1</FileVersion>
|
||||
<AssemblyVersion>3.0.0.4</AssemblyVersion>
|
||||
<FileVersion>3.0.0.4</FileVersion>
|
||||
<LangVersion>7</LangVersion>
|
||||
<ErrorReport>none</ErrorReport>
|
||||
<ApplicationIcon>ASF.ico</ApplicationIcon>
|
||||
@@ -19,7 +19,7 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="HtmlAgilityPack" Version="1.5.0" />
|
||||
<PackageReference Include="HtmlAgilityPack" Version="1.5.2-beta1" />
|
||||
<PackageReference Include="Humanizer" Version="2.2.0" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="10.0.3" />
|
||||
<PackageReference Include="Nito.AsyncEx.Coordination" Version="5.0.0-pre-02" />
|
||||
|
||||
@@ -50,10 +50,12 @@ namespace ArchiSteamFarm {
|
||||
|
||||
// We must use HTTPS for SteamCommunity, as http would make certain POST requests failing (trades)
|
||||
private const string SteamCommunityHost = "steamcommunity.com";
|
||||
|
||||
private const string SteamCommunityURL = "https://" + SteamCommunityHost;
|
||||
|
||||
// We could (and should) use HTTPS for SteamStore, but that would make certain POST requests failing
|
||||
private const string SteamStoreHost = "store.steampowered.com";
|
||||
|
||||
private const string SteamStoreURL = "http://" + SteamStoreHost;
|
||||
|
||||
private static readonly SemaphoreSlim InventorySemaphore = new SemaphoreSlim(1);
|
||||
@@ -177,7 +179,7 @@ namespace ArchiSteamFarm {
|
||||
}
|
||||
|
||||
KeyValue response = null;
|
||||
for (byte i = 0; (i < WebBrowser.MaxRetries) && (response == null); i++) {
|
||||
for (byte i = 0; (i < WebBrowser.MaxTries) && (response == null); i++) {
|
||||
await Task.Run(() => {
|
||||
using (dynamic iEconService = WebAPI.GetInterface(IEconService, steamApiKey)) {
|
||||
iEconService.Timeout = Timeout;
|
||||
@@ -196,7 +198,7 @@ namespace ArchiSteamFarm {
|
||||
}
|
||||
|
||||
if (response == null) {
|
||||
Bot.ArchiLogger.LogGenericWarning(string.Format(Strings.ErrorRequestFailedTooManyTimes, WebBrowser.MaxRetries));
|
||||
Bot.ArchiLogger.LogGenericWarning(string.Format(Strings.ErrorRequestFailedTooManyTimes, WebBrowser.MaxTries));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -228,7 +230,7 @@ namespace ArchiSteamFarm {
|
||||
}
|
||||
|
||||
KeyValue response = null;
|
||||
for (byte i = 0; (i < WebBrowser.MaxRetries) && (response == null); i++) {
|
||||
for (byte i = 0; (i < WebBrowser.MaxTries) && (response == null); i++) {
|
||||
await Task.Run(() => {
|
||||
using (dynamic iEconService = WebAPI.GetInterface(IEconService, steamApiKey)) {
|
||||
iEconService.Timeout = Timeout;
|
||||
@@ -249,7 +251,7 @@ namespace ArchiSteamFarm {
|
||||
}
|
||||
|
||||
if (response == null) {
|
||||
Bot.ArchiLogger.LogGenericWarning(string.Format(Strings.ErrorRequestFailedTooManyTimes, WebBrowser.MaxRetries));
|
||||
Bot.ArchiLogger.LogGenericWarning(string.Format(Strings.ErrorRequestFailedTooManyTimes, WebBrowser.MaxTries));
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -625,7 +627,7 @@ namespace ArchiSteamFarm {
|
||||
}
|
||||
|
||||
KeyValue response = null;
|
||||
for (byte i = 0; (i < WebBrowser.MaxRetries) && (response == null); i++) {
|
||||
for (byte i = 0; (i < WebBrowser.MaxTries) && (response == null); i++) {
|
||||
await Task.Run(() => {
|
||||
using (dynamic iPlayerService = WebAPI.GetInterface(IPlayerService, steamApiKey)) {
|
||||
iPlayerService.Timeout = Timeout;
|
||||
@@ -644,7 +646,7 @@ namespace ArchiSteamFarm {
|
||||
}
|
||||
|
||||
if (response == null) {
|
||||
Bot.ArchiLogger.LogGenericWarning(string.Format(Strings.ErrorRequestFailedTooManyTimes, WebBrowser.MaxRetries));
|
||||
Bot.ArchiLogger.LogGenericWarning(string.Format(Strings.ErrorRequestFailedTooManyTimes, WebBrowser.MaxTries));
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -664,7 +666,7 @@ namespace ArchiSteamFarm {
|
||||
|
||||
internal async Task<uint> GetServerTime() {
|
||||
KeyValue response = null;
|
||||
for (byte i = 0; (i < WebBrowser.MaxRetries) && (response == null); i++) {
|
||||
for (byte i = 0; (i < WebBrowser.MaxTries) && (response == null); i++) {
|
||||
await Task.Run(() => {
|
||||
using (dynamic iTwoFactorService = WebAPI.GetInterface(ITwoFactorService)) {
|
||||
iTwoFactorService.Timeout = Timeout;
|
||||
@@ -685,7 +687,7 @@ namespace ArchiSteamFarm {
|
||||
return response["server_time"].AsUnsignedInteger();
|
||||
}
|
||||
|
||||
Bot.ArchiLogger.LogGenericWarning(string.Format(Strings.ErrorRequestFailedTooManyTimes, WebBrowser.MaxRetries));
|
||||
Bot.ArchiLogger.LogGenericWarning(string.Format(Strings.ErrorRequestFailedTooManyTimes, WebBrowser.MaxTries));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
27
ArchiSteamFarm/AssemblyInfo.cs
Normal file
27
ArchiSteamFarm/AssemblyInfo.cs
Normal file
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
_ _ _ ____ _ _____
|
||||
/ \ _ __ ___ | |__ (_)/ ___| | |_ ___ __ _ _ __ ___ | ___|__ _ _ __ _ __ ___
|
||||
/ _ \ | '__|/ __|| '_ \ | |\___ \ | __|/ _ \ / _` || '_ ` _ \ | |_ / _` || '__|| '_ ` _ \
|
||||
/ ___ \ | | | (__ | | | || | ___) || |_| __/| (_| || | | | | || _|| (_| || | | | | | | |
|
||||
/_/ \_\|_| \___||_| |_||_||____/ \__|\___| \__,_||_| |_| |_||_| \__,_||_| |_| |_| |_|
|
||||
|
||||
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.Runtime.CompilerServices;
|
||||
|
||||
[assembly: InternalsVisibleTo("ArchiSteamFarm.Tests")]
|
||||
@@ -1276,7 +1276,7 @@ namespace ArchiSteamFarm {
|
||||
// This is pretty rare, but SK2 SteamFriends handler and this handler could execute at the same time
|
||||
// So we wait for nickname to be registered (with timeout of 5 tries/seconds)
|
||||
string nickname = SteamFriends.GetPersonaName();
|
||||
for (byte i = 0; (i < WebBrowser.MaxRetries) && (string.IsNullOrEmpty(nickname) || nickname.Equals("[unassigned]")); i++) {
|
||||
for (byte i = 0; (i < WebBrowser.MaxTries) && (string.IsNullOrEmpty(nickname) || nickname.Equals("[unassigned]")); i++) {
|
||||
await Task.Delay(1000).ConfigureAwait(false);
|
||||
nickname = SteamFriends.GetPersonaName();
|
||||
}
|
||||
@@ -2699,6 +2699,7 @@ namespace ArchiSteamFarm {
|
||||
response.Append(FormatBotResponse(string.Format(Strings.BotOwnedAlreadyWithName, ownedGame.Key, ownedGame.Value)));
|
||||
}
|
||||
} else {
|
||||
query = query.Replace('_', ' ');
|
||||
string[] games = query.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
|
||||
foreach (string game in games) {
|
||||
|
||||
@@ -92,6 +92,12 @@ namespace ArchiSteamFarm {
|
||||
Steam.Item.EType.TradingCard
|
||||
};
|
||||
|
||||
[JsonProperty(ObjectCreationHandling = ObjectCreationHandling.Replace, Required = Required.DisallowNull)]
|
||||
internal readonly HashSet<Steam.Item.EType> MatchableTypes = new HashSet<Steam.Item.EType> {
|
||||
Steam.Item.EType.FoilTradingCard,
|
||||
Steam.Item.EType.TradingCard
|
||||
};
|
||||
|
||||
[JsonProperty(Required = Required.DisallowNull)]
|
||||
internal readonly CryptoHelper.ECryptoMethod PasswordFormat = CryptoHelper.ECryptoMethod.PlainText;
|
||||
|
||||
|
||||
@@ -26,7 +26,6 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace ArchiSteamFarm {
|
||||
@@ -152,21 +151,19 @@ namespace ArchiSteamFarm {
|
||||
return;
|
||||
}
|
||||
|
||||
// This call verifies if JSON is alright
|
||||
// We don't wrap it in try catch as it should always be the case
|
||||
// And if it's not, we want to know about it (in a crash) and correct it in future version
|
||||
JsonConvert.DeserializeObject<BotDatabase>(json);
|
||||
|
||||
lock (FileLock) {
|
||||
for (byte i = 0; i < 5; i++) {
|
||||
try {
|
||||
File.WriteAllText(FilePath, json);
|
||||
break;
|
||||
} catch (Exception e) {
|
||||
ASF.ArchiLogger.LogGenericException(e);
|
||||
}
|
||||
string newFilePath = FilePath + ".new";
|
||||
|
||||
Thread.Sleep(1000);
|
||||
try {
|
||||
File.WriteAllText(newFilePath, json);
|
||||
|
||||
if (File.Exists(FilePath)) {
|
||||
File.Replace(newFilePath, FilePath, null);
|
||||
} else {
|
||||
File.Move(newFilePath, FilePath);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
ASF.ArchiLogger.LogGenericException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,7 +41,7 @@ namespace ArchiSteamFarm {
|
||||
internal const string UlongStringPrefix = "s_";
|
||||
|
||||
// This is hardcoded blacklist which should not be possible to change
|
||||
internal static readonly HashSet<uint> GlobalBlacklist = new HashSet<uint> { 267420, 303700, 335590, 368020, 425280, 480730, 566020, 639900 };
|
||||
internal static readonly HashSet<uint> GlobalBlacklist = new HashSet<uint> { 267420, 303700, 335590, 368020, 402590, 425280, 480730, 566020, 639900 };
|
||||
|
||||
[JsonProperty(Required = Required.DisallowNull)]
|
||||
internal readonly bool AutoRestart = true;
|
||||
|
||||
@@ -25,7 +25,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace ArchiSteamFarm {
|
||||
@@ -114,21 +113,19 @@ namespace ArchiSteamFarm {
|
||||
return;
|
||||
}
|
||||
|
||||
// This call verifies if JSON is alright
|
||||
// We don't wrap it in try catch as it should always be the case
|
||||
// And if it's not, we want to know about it (in a crash) and correct it in future version
|
||||
JsonConvert.DeserializeObject<GlobalDatabase>(json, CustomSerializerSettings);
|
||||
|
||||
lock (FileLock) {
|
||||
for (byte i = 0; i < 5; i++) {
|
||||
try {
|
||||
File.WriteAllText(FilePath, json);
|
||||
break;
|
||||
} catch (Exception e) {
|
||||
ASF.ArchiLogger.LogGenericException(e);
|
||||
}
|
||||
string newFilePath = FilePath + ".new";
|
||||
|
||||
Thread.Sleep(1000);
|
||||
try {
|
||||
File.WriteAllText(newFilePath, json);
|
||||
|
||||
if (File.Exists(FilePath)) {
|
||||
File.Replace(newFilePath, FilePath, null);
|
||||
} else {
|
||||
File.Move(newFilePath, FilePath);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
ASF.ArchiLogger.LogGenericException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,11 +50,11 @@ namespace ArchiSteamFarm {
|
||||
}
|
||||
|
||||
internal static void Start() {
|
||||
if (KeepRunning) {
|
||||
if (KeepRunning || (HttpListener.Prefixes.Count == 0)) {
|
||||
return;
|
||||
}
|
||||
|
||||
ASF.ArchiLogger.LogGenericInfo(string.Format(Strings.IPCStarting, HttpListener.Prefixes.FirstOrDefault()));
|
||||
ASF.ArchiLogger.LogGenericInfo(string.Format(Strings.IPCStarting, HttpListener.Prefixes.First()));
|
||||
|
||||
try {
|
||||
HttpListener.Start();
|
||||
@@ -84,56 +84,60 @@ namespace ArchiSteamFarm {
|
||||
return;
|
||||
}
|
||||
|
||||
if (Program.GlobalConfig.SteamOwnerID == 0) {
|
||||
ASF.ArchiLogger.LogGenericInfo(Strings.ErrorIPCAccessDenied);
|
||||
await context.Response.WriteAsync(HttpStatusCode.Forbidden, Strings.ErrorIPCAccessDenied).ConfigureAwait(false);
|
||||
return;
|
||||
}
|
||||
try {
|
||||
if (Program.GlobalConfig.SteamOwnerID == 0) {
|
||||
ASF.ArchiLogger.LogGenericWarning(Strings.ErrorIPCAccessDenied);
|
||||
await context.Response.WriteAsync(HttpStatusCode.Forbidden, Strings.ErrorIPCAccessDenied).ConfigureAwait(false);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!context.Request.RawUrl.StartsWith("/" + nameof(IPC), StringComparison.Ordinal)) {
|
||||
await context.Response.WriteAsync(HttpStatusCode.BadRequest, nameof(HttpStatusCode.BadRequest)).ConfigureAwait(false);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (context.Request.HttpMethod) {
|
||||
case WebRequestMethods.Http.Get:
|
||||
for (int i = 0; i < context.Request.QueryString.Count; i++) {
|
||||
string key = context.Request.QueryString.GetKey(i);
|
||||
|
||||
switch (key) {
|
||||
case "command":
|
||||
string command = context.Request.QueryString.Get(i);
|
||||
if (string.IsNullOrEmpty(command)) {
|
||||
break;
|
||||
}
|
||||
|
||||
Bot bot = Bot.Bots.Values.FirstOrDefault();
|
||||
if (bot == null) {
|
||||
await context.Response.WriteAsync(HttpStatusCode.NotAcceptable, Strings.ErrorNoBotsDefined).ConfigureAwait(false);
|
||||
return;
|
||||
}
|
||||
|
||||
if (command[0] != '!') {
|
||||
command = "!" + command;
|
||||
}
|
||||
|
||||
string response = await bot.Response(Program.GlobalConfig.SteamOwnerID, command).ConfigureAwait(false);
|
||||
|
||||
ASF.ArchiLogger.LogGenericInfo(string.Format(Strings.IPCAnswered, command, response));
|
||||
|
||||
await context.Response.WriteAsync(HttpStatusCode.OK, response).ConfigureAwait(false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
default:
|
||||
if (!context.Request.RawUrl.StartsWith("/" + nameof(IPC), StringComparison.Ordinal)) {
|
||||
await context.Response.WriteAsync(HttpStatusCode.BadRequest, nameof(HttpStatusCode.BadRequest)).ConfigureAwait(false);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (context.Response.ContentLength64 == 0) {
|
||||
await context.Response.WriteAsync(HttpStatusCode.MethodNotAllowed, nameof(HttpStatusCode.MethodNotAllowed)).ConfigureAwait(false);
|
||||
switch (context.Request.HttpMethod) {
|
||||
case WebRequestMethods.Http.Get:
|
||||
for (int i = 0; i < context.Request.QueryString.Count; i++) {
|
||||
string key = context.Request.QueryString.GetKey(i);
|
||||
|
||||
switch (key) {
|
||||
case "command":
|
||||
string command = context.Request.QueryString.Get(i);
|
||||
if (string.IsNullOrEmpty(command)) {
|
||||
break;
|
||||
}
|
||||
|
||||
Bot bot = Bot.Bots.Values.FirstOrDefault();
|
||||
if (bot == null) {
|
||||
await context.Response.WriteAsync(HttpStatusCode.NotAcceptable, Strings.ErrorNoBotsDefined).ConfigureAwait(false);
|
||||
return;
|
||||
}
|
||||
|
||||
if (command[0] != '!') {
|
||||
command = "!" + command;
|
||||
}
|
||||
|
||||
string response = await bot.Response(Program.GlobalConfig.SteamOwnerID, command).ConfigureAwait(false);
|
||||
|
||||
ASF.ArchiLogger.LogGenericInfo(string.Format(Strings.IPCAnswered, command, response));
|
||||
|
||||
await context.Response.WriteAsync(HttpStatusCode.OK, response).ConfigureAwait(false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
default:
|
||||
await context.Response.WriteAsync(HttpStatusCode.BadRequest, nameof(HttpStatusCode.BadRequest)).ConfigureAwait(false);
|
||||
return;
|
||||
}
|
||||
|
||||
if (context.Response.ContentLength64 == 0) {
|
||||
await context.Response.WriteAsync(HttpStatusCode.MethodNotAllowed, nameof(HttpStatusCode.MethodNotAllowed)).ConfigureAwait(false);
|
||||
}
|
||||
} finally {
|
||||
context.Response.Close();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -148,8 +152,7 @@ namespace ArchiSteamFarm {
|
||||
continue;
|
||||
}
|
||||
|
||||
await HandleRequest(context).ConfigureAwait(false);
|
||||
context.Response.Close();
|
||||
Utilities.StartBackgroundFunction(() => HandleRequest(context), false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -164,8 +167,14 @@ namespace ArchiSteamFarm {
|
||||
response.StatusCode = (ushort) statusCode;
|
||||
}
|
||||
|
||||
byte[] buffer = Encoding.UTF8.GetBytes(message);
|
||||
Encoding encoding = Encoding.UTF8;
|
||||
response.ContentEncoding = encoding;
|
||||
|
||||
string html = "<html><head><meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\"></head><body><p>" + message + "</p></body></html>";
|
||||
|
||||
byte[] buffer = encoding.GetBytes(html);
|
||||
response.ContentLength64 = buffer.Length;
|
||||
|
||||
await response.OutputStream.WriteAsync(buffer, 0, buffer.Length).ConfigureAwait(false);
|
||||
} catch (Exception e) {
|
||||
response.StatusCode = (ushort) HttpStatusCode.InternalServerError;
|
||||
|
||||
@@ -55,6 +55,11 @@ namespace ArchiSteamFarm.JSON {
|
||||
internal readonly string Name;
|
||||
#pragma warning restore 649
|
||||
|
||||
#pragma warning disable 649
|
||||
[JsonProperty(PropertyName = "size", Required = Required.Always)]
|
||||
internal readonly uint Size;
|
||||
#pragma warning restore 649
|
||||
|
||||
// Deserialized from JSON
|
||||
private Asset() { }
|
||||
}
|
||||
|
||||
@@ -486,7 +486,15 @@ namespace ArchiSteamFarm.JSON {
|
||||
return true;
|
||||
}
|
||||
|
||||
internal bool IsSteamCardsRequest() => ItemsToGive.All(item => (item.AppID == Item.SteamAppID) && (item.ContextID == Item.SteamCommunityContextID) && (item.Type == Item.EType.TradingCard));
|
||||
internal bool IsValidSteamItemsRequest(HashSet<Item.EType> acceptedTypes) {
|
||||
if ((acceptedTypes == null) || (acceptedTypes.Count == 0)) {
|
||||
ASF.ArchiLogger.LogNullError(nameof(acceptedTypes));
|
||||
return false;
|
||||
}
|
||||
|
||||
bool result = ItemsToGive.All(item => (item.AppID == Item.SteamAppID) && (item.ContextID == Item.SteamCommunityContextID) && acceptedTypes.Contains(item.Type));
|
||||
return result;
|
||||
}
|
||||
|
||||
[SuppressMessage("ReSharper", "UnusedMember.Global")]
|
||||
internal enum ETradeOfferState : byte {
|
||||
|
||||
2
ArchiSteamFarm/Localization/Strings.Designer.cs
generated
2
ArchiSteamFarm/Localization/Strings.Designer.cs
generated
@@ -1306,7 +1306,7 @@ namespace ArchiSteamFarm.Localization {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Wyszukuje zlokalizowany ciąg podobny do ciągu Downloading new version... While waiting, consider donating if you appreciate the work being done! :).
|
||||
/// Wyszukuje zlokalizowany ciąg podobny do ciągu Downloading new version: {0} ({1} MB)... While waiting, consider donating if you appreciate the work being done! :).
|
||||
/// </summary>
|
||||
internal static string UpdateDownloadingNewVersion {
|
||||
get {
|
||||
|
||||
@@ -191,9 +191,7 @@
|
||||
<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>
|
||||
|
||||
@@ -235,9 +235,7 @@
|
||||
<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>
|
||||
|
||||
@@ -241,9 +241,7 @@ StackTrace:
|
||||
<data name="UpdateCheckingNewVersion" xml:space="preserve">
|
||||
<value>Kontrola nové verze...</value>
|
||||
</data>
|
||||
<data name="UpdateDownloadingNewVersion" xml:space="preserve">
|
||||
<value>Probíhá stahování nové verze... Během čekání zvažte podpotu tohoto projektu! :)</value>
|
||||
</data>
|
||||
|
||||
<data name="UpdateFinished" xml:space="preserve">
|
||||
<value>Úspěšně aktualizováno.</value>
|
||||
</data>
|
||||
|
||||
@@ -240,9 +240,7 @@ StackTrace:
|
||||
<data name="UpdateCheckingNewVersion" xml:space="preserve">
|
||||
<value>Undersøger for ny version...</value>
|
||||
</data>
|
||||
<data name="UpdateDownloadingNewVersion" xml:space="preserve">
|
||||
<value>Downloader ny version... Mens du venter, overvej at donere hvis du sætter pris på det arbejde der bliver gjort! :)</value>
|
||||
</data>
|
||||
|
||||
<data name="UpdateFinished" xml:space="preserve">
|
||||
<value>Opdateringsprocessen er færdig!</value>
|
||||
</data>
|
||||
|
||||
@@ -183,14 +183,19 @@ StackTrace:
|
||||
<data name="ErrorUpdateCheckFailed" xml:space="preserve">
|
||||
<value>Neueste Version konnte nicht überprüft werden!</value>
|
||||
</data>
|
||||
|
||||
<data name="ErrorUpdateNoAssetForThisVersion" xml:space="preserve">
|
||||
<value>Konnte mit der Aktualisierung nicht fortfahren, weil es keine Anlage gibt, welche sich auf die aktuell betriebene Version bezieht! Automatische Aktualisierung auf diese Version ist nicht möglich.</value>
|
||||
</data>
|
||||
<data name="ErrorUpdateNoAssets" xml:space="preserve">
|
||||
<value>Konnte nicht mit Aktualisierung fortfahren, weil diese Version keine Anlage enthält!</value>
|
||||
</data>
|
||||
<data name="ErrorUserInputRunningInHeadlessMode" xml:space="preserve">
|
||||
<value>Anfrage für Benutzereingabe erhalten, aber der Prozess läuft im Headless-Modus!</value>
|
||||
</data>
|
||||
|
||||
<data name="ErrorIPCAccessDenied" xml:space="preserve">
|
||||
<value>Verweigere die Bearbeitung dieser Anfrage, weil die SteamOwnerID nicht festgelegt wurde!</value>
|
||||
<comment>SteamOwnerID is name of bot config property, it should not be translated</comment>
|
||||
</data>
|
||||
<data name="Exiting" xml:space="preserve">
|
||||
<value>Vorgang wird beendet...</value>
|
||||
</data>
|
||||
@@ -241,7 +246,8 @@ StackTrace:
|
||||
<value>Prüfe auf neue Version...</value>
|
||||
</data>
|
||||
<data name="UpdateDownloadingNewVersion" xml:space="preserve">
|
||||
<value>Lade neue Version herunter... Während du wartest, denk darüber nach zu spenden, wenn du die geleistete Arbeit zu schätzen weißt! :)</value>
|
||||
<value>Lade neue Version herunter: {0} ({1} MB)... Während du wartest, denk darüber nach zu spenden, wenn du die geleistete Arbeit zu schätzen weißt! :)</value>
|
||||
<comment>{0} will be replaced by version string, {1} will be replaced by update size (in megabytes)</comment>
|
||||
</data>
|
||||
<data name="UpdateFinished" xml:space="preserve">
|
||||
<value>Aktualisierung abgeschlossen!</value>
|
||||
@@ -281,7 +287,10 @@ StackTrace:
|
||||
<value>Bitte gebe undokumentierten Wert von {0} ein: </value>
|
||||
<comment>{0} will be replaced by property name. Please note that this translation should end with space</comment>
|
||||
</data>
|
||||
|
||||
<data name="UserInputIPCHost" xml:space="preserve">
|
||||
<value>Bitte gebe deinen IPC-Host ein: </value>
|
||||
<comment>Please note that this translation should end with space</comment>
|
||||
</data>
|
||||
<data name="WarningUnknownValuePleaseReport" xml:space="preserve">
|
||||
<value>Unbekannten Wert für {0} erhalten, bitte melde folgendes: {1}</value>
|
||||
<comment>{0} will be replaced by object's name, {1} will be replaced by value for that object</comment>
|
||||
@@ -290,10 +299,20 @@ StackTrace:
|
||||
<value>Das Spielen von mehr als {0} Spielen gleichzeitig ist nicht möglich, nur die ersten {0} Einträge von {1} werden verwendet!</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="ErrorIPCAddressAccessDeniedException" xml:space="preserve">
|
||||
<value>Der IPC-Dienst konnte wegen einer AddressAccessDeniedException nicht gestartet werden! Wenn du den IPC-Service von ASF nutzen möchtest, erwäge es ASF als Administrator auszuführen oder die korrekten Berechtigungen zu erteilen!</value>
|
||||
</data>
|
||||
<data name="IPCAnswered" xml:space="preserve">
|
||||
<value>Auf IPC-Befehl geantwortet: {0} mit {1}</value>
|
||||
<comment>{0} will be replaced by IPC command, {1} will be replaced by IPC answer</comment>
|
||||
</data>
|
||||
<data name="IPCReady" xml:space="preserve">
|
||||
<value>ICP-Server bereit!</value>
|
||||
</data>
|
||||
<data name="IPCStarting" xml:space="preserve">
|
||||
<value>Starte IPC-Server auf {0}...</value>
|
||||
<comment>{0} will be replaced by IPC hostname</comment>
|
||||
</data>
|
||||
<data name="BotAlreadyStopped" xml:space="preserve">
|
||||
<value>Dieser Bot hat bereits angehalten!</value>
|
||||
</data>
|
||||
|
||||
@@ -184,14 +184,19 @@ StackTrace:
|
||||
<data name="ErrorUpdateCheckFailed" xml:space="preserve">
|
||||
<value>Konnte aktuellste Version nicht überprüfen!</value>
|
||||
</data>
|
||||
|
||||
<data name="ErrorUpdateNoAssetForThisVersion" xml:space="preserve">
|
||||
<value>Konnte mit der Aktualisierung nicht fortfahren, weil es keine Anlage gibt, welche sich auf die aktuell betriebene Version bezieht! Automatische Aktualisierung auf diese Version ist nicht möglich.</value>
|
||||
</data>
|
||||
<data name="ErrorUpdateNoAssets" xml:space="preserve">
|
||||
<value>Konnte nicht mit Aktualisierung fortfahren, weil diese Version keine Anlage enthält!</value>
|
||||
</data>
|
||||
<data name="ErrorUserInputRunningInHeadlessMode" xml:space="preserve">
|
||||
<value>Anfrage für Benutzereingabe erhalten, aber der Prozess läuft im Headless-Modus!</value>
|
||||
</data>
|
||||
|
||||
<data name="ErrorIPCAccessDenied" xml:space="preserve">
|
||||
<value>Verweigere die Bearbeitung dieser Anfrage, weil die SteamOwnerID nicht festgelegt wurde!</value>
|
||||
<comment>SteamOwnerID is name of bot config property, it should not be translated</comment>
|
||||
</data>
|
||||
<data name="Exiting" xml:space="preserve">
|
||||
<value>Beende...</value>
|
||||
</data>
|
||||
@@ -242,7 +247,8 @@ StackTrace:
|
||||
<value>Prüfe auf neue Version...</value>
|
||||
</data>
|
||||
<data name="UpdateDownloadingNewVersion" xml:space="preserve">
|
||||
<value>Lade neue Version herunter... Während du wartest, denk darüber nach zu spenden, wenn du die geleistete Arbeit zu schätzen weißt! :)</value>
|
||||
<value>Lade neue Version herunter: {0} ({1} MB)... Während du wartest, denk darüber nach zu spenden, wenn du die geleistete Arbeit zu schätzen weißt! :)</value>
|
||||
<comment>{0} will be replaced by version string, {1} will be replaced by update size (in megabytes)</comment>
|
||||
</data>
|
||||
<data name="UpdateFinished" xml:space="preserve">
|
||||
<value>Aktualisierung abgeschlossen!</value>
|
||||
@@ -282,7 +288,10 @@ StackTrace:
|
||||
<value>Bitte gebe undokumentierten Wert von {0} ein: </value>
|
||||
<comment>{0} will be replaced by property name. Please note that this translation should end with space</comment>
|
||||
</data>
|
||||
|
||||
<data name="UserInputIPCHost" xml:space="preserve">
|
||||
<value>Bitte gebe deinen IPC-Host ein: </value>
|
||||
<comment>Please note that this translation should end with space</comment>
|
||||
</data>
|
||||
<data name="WarningUnknownValuePleaseReport" xml:space="preserve">
|
||||
<value>Unbekannten Wert für {0} erhalten, bitte melde folgendes: {1}</value>
|
||||
<comment>{0} will be replaced by object's name, {1} will be replaced by value for that object</comment>
|
||||
@@ -291,10 +300,20 @@ StackTrace:
|
||||
<value>Das Spielen von mehr als {0} Spielen gleichzeitig ist nicht möglich, nur die ersten {0} Einträge von {1} werden verwendet!</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="ErrorIPCAddressAccessDeniedException" xml:space="preserve">
|
||||
<value>Der IPC-Dienst konnte wegen einer AddressAccessDeniedException nicht gestartet werden! Wenn du den IPC-Service von ASF nutzen möchtest, erwäge es ASF als Administrator auszuführen oder die korrekten Berechtigungen zu erteilen!</value>
|
||||
</data>
|
||||
<data name="IPCAnswered" xml:space="preserve">
|
||||
<value>Auf IPC-Befehl geantwortet: {0} mit {1}</value>
|
||||
<comment>{0} will be replaced by IPC command, {1} will be replaced by IPC answer</comment>
|
||||
</data>
|
||||
<data name="IPCReady" xml:space="preserve">
|
||||
<value>ICP-Server bereit!</value>
|
||||
</data>
|
||||
<data name="IPCStarting" xml:space="preserve">
|
||||
<value>Starte IPC-Server auf {0}...</value>
|
||||
<comment>{0} will be replaced by IPC hostname</comment>
|
||||
</data>
|
||||
<data name="BotAlreadyStopped" xml:space="preserve">
|
||||
<value>Dieser Bot hat bereits angehalten!</value>
|
||||
</data>
|
||||
|
||||
@@ -235,9 +235,7 @@ StackTrace:
|
||||
<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>
|
||||
|
||||
@@ -183,14 +183,19 @@ Trazo de pila:
|
||||
<data name="ErrorUpdateCheckFailed" xml:space="preserve">
|
||||
<value>¡No se pudo comprobar la última versión!</value>
|
||||
</data>
|
||||
|
||||
<data name="ErrorUpdateNoAssetForThisVersion" xml:space="preserve">
|
||||
<value>No se ha podido proceder con la actualización porque no hay ninguna opcion que se relacione con la version actual! La actualización automatica a esa version no es posible.</value>
|
||||
</data>
|
||||
<data name="ErrorUpdateNoAssets" xml:space="preserve">
|
||||
<value>¡No se puede continuar con una actualización porque esa versión no incluye ningún recurso!</value>
|
||||
</data>
|
||||
<data name="ErrorUserInputRunningInHeadlessMode" xml:space="preserve">
|
||||
<value>Recibida una solicitud de entrada del usuario, ¡pero el proceso se está ejecutando en modo servidor!</value>
|
||||
</data>
|
||||
|
||||
<data name="ErrorIPCAccessDenied" xml:space="preserve">
|
||||
<value>¡Solicitud denegada porque SteamOwnerID no esta establecido!</value>
|
||||
<comment>SteamOwnerID is name of bot config property, it should not be translated</comment>
|
||||
</data>
|
||||
<data name="Exiting" xml:space="preserve">
|
||||
<value>Saliendo...</value>
|
||||
</data>
|
||||
@@ -241,7 +246,8 @@ Trazo de pila:
|
||||
<value>Comprobando si existe una nueva versión...</value>
|
||||
</data>
|
||||
<data name="UpdateDownloadingNewVersion" xml:space="preserve">
|
||||
<value>Descargando la nueva versión... ¡Mientras espera, considere donar si aprecia el trabajo que se está realizando! :)</value>
|
||||
<value>Descargando la nueva versión: {0} ({1} MB)... ¡Mientras espera, considere donar si aprecia el trabajo que se está realizando! :)</value>
|
||||
<comment>{0} will be replaced by version string, {1} will be replaced by update size (in megabytes)</comment>
|
||||
</data>
|
||||
<data name="UpdateFinished" xml:space="preserve">
|
||||
<value>¡Proceso de actualización finalizado!</value>
|
||||
@@ -281,7 +287,10 @@ Trazo de pila:
|
||||
<value>Por favor ingresa el valor indocumentado de {0}: </value>
|
||||
<comment>{0} will be replaced by property name. Please note that this translation should end with space</comment>
|
||||
</data>
|
||||
|
||||
<data name="UserInputIPCHost" xml:space="preserve">
|
||||
<value>Por favor ingresa tu host WFC: </value>
|
||||
<comment>Please note that this translation should end with space</comment>
|
||||
</data>
|
||||
<data name="WarningUnknownValuePleaseReport" xml:space="preserve">
|
||||
<value>Recibido valor desconocido para {0}. Por favor, informa de ello: {1}</value>
|
||||
<comment>{0} will be replaced by object's name, {1} will be replaced by value for that object</comment>
|
||||
@@ -290,10 +299,20 @@ Trazo de pila:
|
||||
<value>¡Ejecutar más de {0} juegos a la vez no es posible, sólo se usarán las primeras {0} entradas de {1}!</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="ErrorIPCAddressAccessDeniedException" xml:space="preserve">
|
||||
<value>¡El servicio de WCF no pudo ser iniciado por un error en AddressAccessDeniedException! Si deseas usar el servicio de WCF proporcionado por ASF, intenta iniciar ASF como administrador, o dar los permisos adecuados!</value>
|
||||
</data>
|
||||
<data name="IPCAnswered" xml:space="preserve">
|
||||
<value>Se ha respondido al comando WCF: {0} con: {1}</value>
|
||||
<comment>{0} will be replaced by IPC command, {1} will be replaced by IPC answer</comment>
|
||||
</data>
|
||||
<data name="IPCReady" xml:space="preserve">
|
||||
<value>¡Servidor WCF listo!</value>
|
||||
</data>
|
||||
<data name="IPCStarting" xml:space="preserve">
|
||||
<value>Iniciando servidor WCF en {0}...</value>
|
||||
<comment>{0} will be replaced by IPC hostname</comment>
|
||||
</data>
|
||||
<data name="BotAlreadyStopped" xml:space="preserve">
|
||||
<value>¡Este bot ya se ha detenido!</value>
|
||||
</data>
|
||||
@@ -649,6 +668,12 @@ Trazo de pila:
|
||||
<value>Uso de memoria actual: {0} MB.</value>
|
||||
<comment>{0} will be replaced by number (in megabytes) of memory being used</comment>
|
||||
</data>
|
||||
|
||||
|
||||
<data name="ClearingDiscoveryQueue" xml:space="preserve">
|
||||
<value>Haciendo la lista de descubrimientos de Steam #{0}...</value>
|
||||
<comment>{0} will be replaced by queue number</comment>
|
||||
</data>
|
||||
<data name="DoneClearingDiscoveryQueue" xml:space="preserve">
|
||||
<value>Lista de decubrimientos de Steam #{0} completada.</value>
|
||||
<comment>{0} will be replaced by queue number</comment>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -201,9 +201,7 @@
|
||||
<data name="UpdateCheckingNewVersion" xml:space="preserve">
|
||||
<value>Tarkistetaan päivityksiä...</value>
|
||||
</data>
|
||||
<data name="UpdateDownloadingNewVersion" xml:space="preserve">
|
||||
<value>Ladataan päivityksiä... Odottaessa, harkitse lahjoittamista kiittääksesi työhön käytetystä ajasta! :)</value>
|
||||
</data>
|
||||
|
||||
<data name="UpdateFinished" xml:space="preserve">
|
||||
<value>Päivitys valmis!</value>
|
||||
</data>
|
||||
|
||||
@@ -191,7 +191,10 @@ StackTrace :
|
||||
<data name="ErrorUserInputRunningInHeadlessMode" xml:space="preserve">
|
||||
<value>Réception d'une demande d'entrée utilisateur, mais le processus en cours tourne en mode non-interactif!</value>
|
||||
</data>
|
||||
|
||||
<data name="ErrorIPCAccessDenied" xml:space="preserve">
|
||||
<value>Refus de traiter la requête car le paramètre SteamOwnerID n’est pas défini !</value>
|
||||
<comment>SteamOwnerID is name of bot config property, it should not be translated</comment>
|
||||
</data>
|
||||
<data name="Exiting" xml:space="preserve">
|
||||
<value>Fermeture...</value>
|
||||
</data>
|
||||
@@ -242,7 +245,8 @@ StackTrace :
|
||||
<value>Recherche d'une nouvelle version...</value>
|
||||
</data>
|
||||
<data name="UpdateDownloadingNewVersion" xml:space="preserve">
|
||||
<value>Téléchargement de la nouvelle version en cours... En attendant, vous pouvez faire un don si vous appréciez le travail effectué ! :)</value>
|
||||
<value>Téléchargement de la nouvelle version en cours: {0} ({1} MB)... En attendant, envisagez de faire un don si vous appréciez le travail effectué ! :)</value>
|
||||
<comment>{0} will be replaced by version string, {1} will be replaced by update size (in megabytes)</comment>
|
||||
</data>
|
||||
<data name="UpdateFinished" xml:space="preserve">
|
||||
<value>Mise à jour terminée !</value>
|
||||
@@ -650,6 +654,12 @@ StackTrace :
|
||||
<value>Mémoire actuellement utilisée : {0} MB.</value>
|
||||
<comment>{0} will be replaced by number (in megabytes) of memory being used</comment>
|
||||
</data>
|
||||
|
||||
|
||||
<data name="ClearingDiscoveryQueue" xml:space="preserve">
|
||||
<value>Consultation de la liste de découvertes en cours #{0}...</value>
|
||||
<comment>{0} will be replaced by queue number</comment>
|
||||
</data>
|
||||
<data name="DoneClearingDiscoveryQueue" xml:space="preserve">
|
||||
<value>Fini de consulter la liste de découvertes #{0}.</value>
|
||||
<comment>{0} will be replaced by queue number</comment>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -191,7 +191,10 @@ StackTrace :
|
||||
<data name="ErrorUserInputRunningInHeadlessMode" xml:space="preserve">
|
||||
<value>Réception d'une demande d'entrée utilisateur, mais le processus en cours tourne en mode non-interactif !</value>
|
||||
</data>
|
||||
|
||||
<data name="ErrorIPCAccessDenied" xml:space="preserve">
|
||||
<value>Refus de traiter la requête car le paramètre SteamOwnerID n’est pas défini !</value>
|
||||
<comment>SteamOwnerID is name of bot config property, it should not be translated</comment>
|
||||
</data>
|
||||
<data name="Exiting" xml:space="preserve">
|
||||
<value>Fermeture...</value>
|
||||
</data>
|
||||
@@ -242,7 +245,8 @@ StackTrace :
|
||||
<value>Recherche d'une nouvelle version...</value>
|
||||
</data>
|
||||
<data name="UpdateDownloadingNewVersion" xml:space="preserve">
|
||||
<value>Téléchargement de la nouvelle version en cours... En attendant, vous pouvez faire un don si vous appréciez le travail effectué ! :)</value>
|
||||
<value>Téléchargement de la nouvelle version en cours: {0} ({1} MB)... En attendant, envisagez de faire un don si vous appréciez le travail effectué ! :)</value>
|
||||
<comment>{0} will be replaced by version string, {1} will be replaced by update size (in megabytes)</comment>
|
||||
</data>
|
||||
<data name="UpdateFinished" xml:space="preserve">
|
||||
<value>Mise à jour terminée !</value>
|
||||
@@ -251,7 +255,7 @@ StackTrace :
|
||||
<value>Une nouvelle version d'ASF est disponible ! Envisagez de la mettre à jour !</value>
|
||||
</data>
|
||||
<data name="UpdateVersionInfo" xml:space="preserve">
|
||||
<value>Version installée : {0} | Version la plus récente : {1}</value>
|
||||
<value>Version locale : {0} | Version la plus récente : {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">
|
||||
@@ -650,6 +654,12 @@ StackTrace :
|
||||
<value>Mémoire actuellement utilisée : {0} MB.</value>
|
||||
<comment>{0} will be replaced by number (in megabytes) of memory being used</comment>
|
||||
</data>
|
||||
|
||||
|
||||
<data name="ClearingDiscoveryQueue" xml:space="preserve">
|
||||
<value>Consultation de la liste de découvertes en cours #{0}...</value>
|
||||
<comment>{0} will be replaced by queue number</comment>
|
||||
</data>
|
||||
<data name="DoneClearingDiscoveryQueue" xml:space="preserve">
|
||||
<value>Fini de consulter la liste de découvertes #{0}.</value>
|
||||
<comment>{0} will be replaced by queue number</comment>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -228,9 +228,7 @@ StackTrace:
|
||||
<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>
|
||||
|
||||
@@ -239,9 +239,7 @@ 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>
|
||||
|
||||
@@ -239,9 +239,7 @@
|
||||
<data name="UpdateCheckingNewVersion" xml:space="preserve">
|
||||
<value>Sedang mengecek versi terbaru...</value>
|
||||
</data>
|
||||
<data name="UpdateDownloadingNewVersion" xml:space="preserve">
|
||||
<value>Mengunduh versi baru... Sambil menunggu, pertimbangkan untuk mengapresiasi seluruh kerja keras dengan mendonasi! :)</value>
|
||||
</data>
|
||||
|
||||
<data name="UpdateFinished" xml:space="preserve">
|
||||
<value>Proses update selesai!</value>
|
||||
</data>
|
||||
|
||||
@@ -239,9 +239,7 @@
|
||||
<data name="UpdateCheckingNewVersion" xml:space="preserve">
|
||||
<value>Verifica della nuova versione...</value>
|
||||
</data>
|
||||
<data name="UpdateDownloadingNewVersion" xml:space="preserve">
|
||||
<value>Scaricando la nuova versione... Durante l'attesa, considera una donazione se apprezzi il lavoro svolto! :)</value>
|
||||
</data>
|
||||
|
||||
<data name="UpdateFinished" xml:space="preserve">
|
||||
<value>Aggiornamento completato!</value>
|
||||
</data>
|
||||
|
||||
@@ -238,9 +238,7 @@
|
||||
<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>
|
||||
|
||||
@@ -241,9 +241,7 @@ StackTrace:
|
||||
<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>
|
||||
|
||||
@@ -181,14 +181,19 @@
|
||||
<data name="ErrorUpdateCheckFailed" xml:space="preserve">
|
||||
<value>Nepavyko patikrinti naujausios versijos!</value>
|
||||
</data>
|
||||
|
||||
<data name="ErrorUpdateNoAssetForThisVersion" xml:space="preserve">
|
||||
<value>Nebuvo galima tęsti naujinimo, nes nėra jokio objekto, kuris yra susijęs su šiuo metu įdiegta versija! Automatinis naujinimas į tą versija yra neįmanoma.</value>
|
||||
</data>
|
||||
<data name="ErrorUpdateNoAssets" xml:space="preserve">
|
||||
<value>Nebuvo galima tęsti su atnaujinimu, nes ta versija neapima jokios informacijos!</value>
|
||||
</data>
|
||||
<data name="ErrorUserInputRunningInHeadlessMode" xml:space="preserve">
|
||||
<value>Gautas prašymas reikalaujantis naudotojo įvesties, bet procesas veikia "headless" mode!</value>
|
||||
</data>
|
||||
|
||||
<data name="ErrorIPCAccessDenied" xml:space="preserve">
|
||||
<value>Atsisakoma apdoroti užklausa, nes SteamOwnerID nėra nustatytas!</value>
|
||||
<comment>SteamOwnerID is name of bot config property, it should not be translated</comment>
|
||||
</data>
|
||||
<data name="Exiting" xml:space="preserve">
|
||||
<value>Stabdoma...</value>
|
||||
</data>
|
||||
@@ -239,7 +244,8 @@
|
||||
<value>Ieškoma naujos versijos...</value>
|
||||
</data>
|
||||
<data name="UpdateDownloadingNewVersion" xml:space="preserve">
|
||||
<value>Atsiunčiama nauja versija... Kol laukiate, apsvarstykite, gal norite paaukoti jei vertinate daromą darbą! :)</value>
|
||||
<value>Atsiunčiama nauja versija: {0} ({1} MB)... Kol laukiate, apsvarstykite, gal norite paaukoti jei vertinate daromą darbą! :)</value>
|
||||
<comment>{0} will be replaced by version string, {1} will be replaced by update size (in megabytes)</comment>
|
||||
</data>
|
||||
<data name="UpdateFinished" xml:space="preserve">
|
||||
<value>Naujinimo procesas baigtas!</value>
|
||||
@@ -279,7 +285,10 @@
|
||||
<value>Prašome įvesti nedokumentuotą {0} reikšmę: </value>
|
||||
<comment>{0} will be replaced by property name. Please note that this translation should end with space</comment>
|
||||
</data>
|
||||
|
||||
<data name="UserInputIPCHost" xml:space="preserve">
|
||||
<value>Prašome įvesti savo IPC hostingą: </value>
|
||||
<comment>Please note that this translation should end with space</comment>
|
||||
</data>
|
||||
<data name="WarningUnknownValuePleaseReport" xml:space="preserve">
|
||||
<value>Gauta nežinoma reikšmė, {0}, prašome pranešti apie tai: {1}</value>
|
||||
<comment>{0} will be replaced by object's name, {1} will be replaced by value for that object</comment>
|
||||
@@ -288,10 +297,20 @@
|
||||
<value>Žaisti daugiau negu {0} žaidimų vienu metu yra neįmanoma, bus naudojamas tik pirmasis {0} įrašas iš {1}!</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="ErrorIPCAddressAccessDeniedException" xml:space="preserve">
|
||||
<value>IPC tarnybos nepavyko paleisti dėl "AddressAccessDeniedException"! Jei norite naudotis IPC tarnybomis kurias teikia ASF, apsvarstykite pradėti ASF kaip administratorius, arba suteikti atitinkamus leidimus!</value>
|
||||
</data>
|
||||
<data name="IPCAnswered" xml:space="preserve">
|
||||
<value>Atsakyta į IPC komandą: {0} su: {1}</value>
|
||||
<comment>{0} will be replaced by IPC command, {1} will be replaced by IPC answer</comment>
|
||||
</data>
|
||||
<data name="IPCReady" xml:space="preserve">
|
||||
<value>IPC serveris paruoštas!</value>
|
||||
</data>
|
||||
<data name="IPCStarting" xml:space="preserve">
|
||||
<value>Paleidžiamas IPC serveris {0}...</value>
|
||||
<comment>{0} will be replaced by IPC hostname</comment>
|
||||
</data>
|
||||
<data name="BotAlreadyStopped" xml:space="preserve">
|
||||
<value>Šis botas jau sustabdytas!</value>
|
||||
</data>
|
||||
|
||||
@@ -183,14 +183,19 @@ StackTrace:
|
||||
<data name="ErrorUpdateCheckFailed" xml:space="preserve">
|
||||
<value>Controle voor de laatste versie is mislukt!</value>
|
||||
</data>
|
||||
|
||||
<data name="ErrorUpdateNoAssetForThisVersion" xml:space="preserve">
|
||||
<value>Kon niet verdergaan met updaten, omdat er geen bestand gerelateerd is aan de reeds werkende versie! Automatisch updaten van deze versie is niet mogelijk.</value>
|
||||
</data>
|
||||
<data name="ErrorUpdateNoAssets" xml:space="preserve">
|
||||
<value>Kon niet verdergaan met updaten, omdat deze updateversie geen bestanden bevat!</value>
|
||||
</data>
|
||||
<data name="ErrorUserInputRunningInHeadlessMode" xml:space="preserve">
|
||||
<value>Aanvraag voor gebruikersinvoer ontvangen, maar het proces draait in de headless mode!</value>
|
||||
</data>
|
||||
|
||||
<data name="ErrorIPCAccessDenied" xml:space="preserve">
|
||||
<value>Het verzoek wordt niet in behandeling genomen omdat het 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>
|
||||
@@ -241,7 +246,8 @@ StackTrace:
|
||||
<value>Controleren op nieuwe versie...</value>
|
||||
</data>
|
||||
<data name="UpdateDownloadingNewVersion" xml:space="preserve">
|
||||
<value>Nieuwe versie wordt gedownload... Als je het gedane werk waardeert, overweeg dan tijdens het wachten om te doneren! :)</value>
|
||||
<value>Nieuwe versie wordt gedownload: {0} ({1} MB)... Als je het gedane werk waardeert, overweeg dan tijdens het wachten om te doneren! :)</value>
|
||||
<comment>{0} will be replaced by version string, {1} will be replaced by update size (in megabytes)</comment>
|
||||
</data>
|
||||
<data name="UpdateFinished" xml:space="preserve">
|
||||
<value>Update is afgerond!</value>
|
||||
@@ -282,7 +288,10 @@ StackTrace:
|
||||
<value>Geef de ongedocumenteerde waarde van {0} op: </value>
|
||||
<comment>{0} will be replaced by property name. Please note that this translation should end with space</comment>
|
||||
</data>
|
||||
|
||||
<data name="UserInputIPCHost" xml:space="preserve">
|
||||
<value>Voer je IPC host in: </value>
|
||||
<comment>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>
|
||||
@@ -291,10 +300,20 @@ StackTrace:
|
||||
<value>Het gelijktijdig spelen van meer dan {0} spellen is niet mogelijk, alleen de eerste {0} spellen van {1} worden gespeeld!</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="ErrorIPCAddressAccessDeniedException" xml:space="preserve">
|
||||
<value>IPC service kan niet worden gestart vanwege de AddressAccessDeniedException! Als je gebruik wilt maken van de IPC service van ASF, start ASF als administrator of geef de juiste machtigingen!</value>
|
||||
</data>
|
||||
<data name="IPCAnswered" xml:space="preserve">
|
||||
<value>Gereageerd op IPC opdracht: {0} met: {1}</value>
|
||||
<comment>{0} will be replaced by IPC command, {1} will be replaced by IPC answer</comment>
|
||||
</data>
|
||||
<data name="IPCReady" xml:space="preserve">
|
||||
<value>IPC server gereed!</value>
|
||||
</data>
|
||||
<data name="IPCStarting" xml:space="preserve">
|
||||
<value>IPC server starten op {0}...</value>
|
||||
<comment>{0} will be replaced by IPC hostname</comment>
|
||||
</data>
|
||||
<data name="BotAlreadyStopped" xml:space="preserve">
|
||||
<value>Deze bot is al gestopt!</value>
|
||||
</data>
|
||||
|
||||
@@ -183,14 +183,19 @@ StackTrace:
|
||||
<data name="ErrorUpdateCheckFailed" xml:space="preserve">
|
||||
<value>Laatste versie kon niet worden gecontroleerd!</value>
|
||||
</data>
|
||||
|
||||
<data name="ErrorUpdateNoAssetForThisVersion" xml:space="preserve">
|
||||
<value>Kon niet verdergaan met updaten, omdat er geen bestand gerelateerd is aan de reeds werkende versie! Automatisch updaten van deze versie is niet mogelijk.</value>
|
||||
</data>
|
||||
<data name="ErrorUpdateNoAssets" xml:space="preserve">
|
||||
<value>Kon niet verdergaan met updaten, omdat deze updateversie geen bestanden bevat!</value>
|
||||
</data>
|
||||
<data name="ErrorUserInputRunningInHeadlessMode" xml:space="preserve">
|
||||
<value>Aanvraag voor gebruikersinvoer ontvangen, maar het proces draait in de headless mode!</value>
|
||||
</data>
|
||||
|
||||
<data name="ErrorIPCAccessDenied" xml:space="preserve">
|
||||
<value>Het verzoek wordt niet in behandeling genomen omdat het 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>
|
||||
@@ -241,7 +246,8 @@ StackTrace:
|
||||
<value>Controleren op nieuwe versie...</value>
|
||||
</data>
|
||||
<data name="UpdateDownloadingNewVersion" xml:space="preserve">
|
||||
<value>Nieuwe versie wordt gedownload... Als je het gedane werk waardeert, overweeg dan tijdens het wachten om te doneren! :)</value>
|
||||
<value>Nieuwe versie wordt gedownload: {0} ({1} MB)... Als je het gedane werk waardeert, overweeg dan tijdens het wachten om te doneren! :)</value>
|
||||
<comment>{0} will be replaced by version string, {1} will be replaced by update size (in megabytes)</comment>
|
||||
</data>
|
||||
<data name="UpdateFinished" xml:space="preserve">
|
||||
<value>Update is afgerond!</value>
|
||||
@@ -282,7 +288,10 @@ StackTrace:
|
||||
<value>Geef de ongedocumenteerde waarde van {0} op: </value>
|
||||
<comment>{0} will be replaced by property name. Please note that this translation should end with space</comment>
|
||||
</data>
|
||||
|
||||
<data name="UserInputIPCHost" xml:space="preserve">
|
||||
<value>Voer je IPC host in: </value>
|
||||
<comment>Please note that this translation should end with space</comment>
|
||||
</data>
|
||||
<data name="WarningUnknownValuePleaseReport" xml:space="preserve">
|
||||
<value>Onbekende waarde ontvangen voor {0}, graag dit melden: {1}</value>
|
||||
<comment>{0} will be replaced by object's name, {1} will be replaced by value for that object</comment>
|
||||
@@ -291,10 +300,20 @@ StackTrace:
|
||||
<value>Het gelijktijdig spelen van meer dan {0} spellen is niet mogelijk, alleen de eerste {0} spellen van {1} worden gespeeld!</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="ErrorIPCAddressAccessDeniedException" xml:space="preserve">
|
||||
<value>IPC service kan niet worden gestart vanwege de AddressAccessDeniedException! Als je gebruik wilt maken van de IPC service van ASF, start ASF als administrator of geef de juiste machtigingen!</value>
|
||||
</data>
|
||||
<data name="IPCAnswered" xml:space="preserve">
|
||||
<value>Gereageerd op IPC opdracht: {0} met: {1}</value>
|
||||
<comment>{0} will be replaced by IPC command, {1} will be replaced by IPC answer</comment>
|
||||
</data>
|
||||
<data name="IPCReady" xml:space="preserve">
|
||||
<value>IPC server gereed!</value>
|
||||
</data>
|
||||
<data name="IPCStarting" xml:space="preserve">
|
||||
<value>IPC server starten op {0}...</value>
|
||||
<comment>{0} will be replaced by IPC hostname</comment>
|
||||
</data>
|
||||
<data name="BotAlreadyStopped" xml:space="preserve">
|
||||
<value>Deze bot is al gestopt!</value>
|
||||
</data>
|
||||
|
||||
@@ -247,7 +247,8 @@ StackTrace:
|
||||
<value>Wyszukiwanie nowej wersji...</value>
|
||||
</data>
|
||||
<data name="UpdateDownloadingNewVersion" xml:space="preserve">
|
||||
<value>Pobieranie nowej wersji... Podczas czekania rozważ dotację, jeśli doceniasz naszą pracę! :)</value>
|
||||
<value>Pobieranie nowej wersji: {0} ({1} MB)... Podczas czekania rozważ dotację, jeśli doceniasz naszą pracę! :)</value>
|
||||
<comment>{0} will be replaced by version string, {1} will be replaced by update size (in megabytes)</comment>
|
||||
</data>
|
||||
<data name="UpdateFinished" xml:space="preserve">
|
||||
<value>Aktualizacja została zakończona!</value>
|
||||
|
||||
@@ -184,14 +184,19 @@ StackTrace:
|
||||
<data name="ErrorUpdateCheckFailed" xml:space="preserve">
|
||||
<value>Não foi possível verificar a última versão!</value>
|
||||
</data>
|
||||
|
||||
<data name="ErrorUpdateNoAssetForThisVersion" xml:space="preserve">
|
||||
<value>Não foi possível prosseguir com a atualização porque não há nenhum recurso relacionado a versão atualmente em execução! Atualização automática para esta versão não é possível.</value>
|
||||
</data>
|
||||
<data name="ErrorUpdateNoAssets" xml:space="preserve">
|
||||
<value>Não foi possível prosseguir com a atualização pois esta versão não inclui nenhum arquivo!</value>
|
||||
</data>
|
||||
<data name="ErrorUserInputRunningInHeadlessMode" xml:space="preserve">
|
||||
<value>Recebido um pedido de entrada feito pelo usuário, mas o processo está sendo executado em modo headless!</value>
|
||||
</data>
|
||||
|
||||
<data name="ErrorIPCAccessDenied" xml:space="preserve">
|
||||
<value>Recusando-se a lidar com a requisição porque SteamOwnerID não está configurado!</value>
|
||||
<comment>SteamOwnerID is name of bot config property, it should not be translated</comment>
|
||||
</data>
|
||||
<data name="Exiting" xml:space="preserve">
|
||||
<value>Saindo...</value>
|
||||
</data>
|
||||
@@ -242,7 +247,8 @@ StackTrace:
|
||||
<value>Verificando se há atualizações...</value>
|
||||
</data>
|
||||
<data name="UpdateDownloadingNewVersion" xml:space="preserve">
|
||||
<value>Baixando nova versão... Enquanto aguarda, considere fazer uma doação caso aprecie o trabalho que está sendo feito! :)</value>
|
||||
<value>Baixando uma nova versão: {0} ({1} MB)... Enquanto aguarda, considere doar se você aprecia o nosso trabalho! :)</value>
|
||||
<comment>{0} will be replaced by version string, {1} will be replaced by update size (in megabytes)</comment>
|
||||
</data>
|
||||
<data name="UpdateFinished" xml:space="preserve">
|
||||
<value>Processo de atualização finalizado!</value>
|
||||
@@ -282,7 +288,10 @@ StackTrace:
|
||||
<value>Por favor, insira o valor não documentado de {0}: </value>
|
||||
<comment>{0} will be replaced by property name. Please note that this translation should end with space</comment>
|
||||
</data>
|
||||
|
||||
<data name="UserInputIPCHost" xml:space="preserve">
|
||||
<value>Por favor insira o seu host IPC: </value>
|
||||
<comment>Please note that this translation should end with space</comment>
|
||||
</data>
|
||||
<data name="WarningUnknownValuePleaseReport" xml:space="preserve">
|
||||
<value>Valor desconhecido recebido para {0}. Por favor, reporte isto: {1}</value>
|
||||
<comment>{0} will be replaced by object's name, {1} will be replaced by value for that object</comment>
|
||||
@@ -291,10 +300,20 @@ StackTrace:
|
||||
<value>Não é possível jogar mais de {0} jogos ao mesmo tempo, apenas os primeiros {0} jogos de {1} serão usados!</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="ErrorIPCAddressAccessDeniedException" xml:space="preserve">
|
||||
<value>Não foi possível iniciar o serviço IPC devido a AddressAccessDeniedException! Se você quer utilizar o serviço IPC fornecido pelo ASF, considere iniciar o ASF como administrador, ou dando as permissões necessárias!</value>
|
||||
</data>
|
||||
<data name="IPCAnswered" xml:space="preserve">
|
||||
<value>Respondeu ao comando IPC: {0} com: {1}</value>
|
||||
<comment>{0} will be replaced by IPC command, {1} will be replaced by IPC answer</comment>
|
||||
</data>
|
||||
<data name="IPCReady" xml:space="preserve">
|
||||
<value>Servidor IPC pronto!</value>
|
||||
</data>
|
||||
<data name="IPCStarting" xml:space="preserve">
|
||||
<value>Iniciando servidor IPC em {0}...</value>
|
||||
<comment>{0} will be replaced by IPC hostname</comment>
|
||||
</data>
|
||||
<data name="BotAlreadyStopped" xml:space="preserve">
|
||||
<value>Este bot já parou!</value>
|
||||
</data>
|
||||
|
||||
@@ -121,7 +121,10 @@
|
||||
<value>Aceitando a troca: {0}</value>
|
||||
<comment>{0} will be replaced by trade number</comment>
|
||||
</data>
|
||||
|
||||
<data name="AutoUpdateCheckInfo" xml:space="preserve">
|
||||
<value>ASF vai automaticamente procurar por novas versões a cada {0}.</value>
|
||||
<comment>{0} will be replaced by translated TimeSpan string (such as "24 hours")</comment>
|
||||
</data>
|
||||
<data name="Content" xml:space="preserve">
|
||||
<value>Conteúdo:
|
||||
{0}</value>
|
||||
@@ -132,7 +135,7 @@
|
||||
<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} foi executado em exceção fatal antes do núcleo do módulo de log foi capaz de inicializar!</value>
|
||||
<value>ASF V{0} encontrou uma exceção fatal antes que o núcleo do módulo de log foi sequer capaz de inicializar!</value>
|
||||
<comment>{0} will be replaced by version number</comment>
|
||||
</data>
|
||||
<data name="ErrorEarlyFatalExceptionPrint" xml:space="preserve">
|
||||
@@ -181,16 +184,21 @@ StackTrace:
|
||||
<data name="ErrorUpdateCheckFailed" xml:space="preserve">
|
||||
<value>Não foi possível verificar a ultima versão!</value>
|
||||
</data>
|
||||
|
||||
<data name="ErrorUpdateNoAssetForThisVersion" xml:space="preserve">
|
||||
<value>Não se conseguiu prosseguir com a atualização porque não há nenhum recurso que se relacione com a versão atual! Foi impossível atualizar automaticamente para essa versão.</value>
|
||||
</data>
|
||||
<data name="ErrorUpdateNoAssets" xml:space="preserve">
|
||||
<value>Não foi possível prosseguir com uma atualização!</value>
|
||||
<value>Não foi possível prosseguir com a atualização porque essa versão não incluí recursos!</value>
|
||||
</data>
|
||||
<data name="ErrorUserInputRunningInHeadlessMode" xml:space="preserve">
|
||||
<value>O pedido de entrada do usuário foi recebido, mas o processo está sendo executado no modo não-interativo!</value>
|
||||
</data>
|
||||
|
||||
<data name="ErrorIPCAccessDenied" xml:space="preserve">
|
||||
<value>Recusando-se a lidar com o pedido, porque SteamOwnerID não está definido!</value>
|
||||
<comment>SteamOwnerID is name of bot config property, it should not be translated</comment>
|
||||
</data>
|
||||
<data name="Exiting" xml:space="preserve">
|
||||
<value>A sair...</value>
|
||||
<value>Saindo...</value>
|
||||
</data>
|
||||
<data name="WarningFailed" xml:space="preserve">
|
||||
<value>Erro!</value>
|
||||
@@ -206,27 +214,27 @@ StackTrace:
|
||||
<comment>{0} will be replaced by trade number</comment>
|
||||
</data>
|
||||
<data name="LoggingIn" xml:space="preserve">
|
||||
<value>A entrar em {0}...</value>
|
||||
<value>A iniciar sessão em {0}...</value>
|
||||
<comment>{0} will be replaced by service's name</comment>
|
||||
</data>
|
||||
<data name="NoBotsAreRunning" xml:space="preserve">
|
||||
<value>Sem bots ligados, a sair...</value>
|
||||
</data>
|
||||
<data name="RefreshingOurSession" xml:space="preserve">
|
||||
<value>Atualizando a nossa sessão!</value>
|
||||
<value>A atualizar a nossa sessão!</value>
|
||||
</data>
|
||||
<data name="RejectingTrade" xml:space="preserve">
|
||||
<value>Rejeitando a troca: {0}</value>
|
||||
<comment>{0} will be replaced by trade number</comment>
|
||||
</data>
|
||||
<data name="Restarting" xml:space="preserve">
|
||||
<value>Reniciando...</value>
|
||||
<value>Reiniciando...</value>
|
||||
</data>
|
||||
<data name="Starting" xml:space="preserve">
|
||||
<value>A iniciar...</value>
|
||||
<value>Iniciando...</value>
|
||||
</data>
|
||||
<data name="StatusCode" xml:space="preserve">
|
||||
<value>Estado do código: {0}</value>
|
||||
<value>Código de estado: {0}</value>
|
||||
<comment>{0} will be replaced by status code number/name</comment>
|
||||
</data>
|
||||
<data name="Success" xml:space="preserve">
|
||||
@@ -239,13 +247,14 @@ StackTrace:
|
||||
<value>A verificar por novas versões...</value>
|
||||
</data>
|
||||
<data name="UpdateDownloadingNewVersion" xml:space="preserve">
|
||||
<value>A obter a nova versão... Enquanto espera, considere doar algo se aprecias o trabalho feito! :)</value>
|
||||
<value>Obtendo a nova versão: {0} ({1} MB)... Enquanto esperas, considera doar algo se aprecias o trabalho feito! :)</value>
|
||||
<comment>{0} will be replaced by version string, {1} will be replaced by update size (in megabytes)</comment>
|
||||
</data>
|
||||
<data name="UpdateFinished" xml:space="preserve">
|
||||
<value>Processo de actualização terminada!</value>
|
||||
</data>
|
||||
<data name="UpdateNewVersionAvailable" xml:space="preserve">
|
||||
<value>Nova versão do ASF está disponível! Considere obter-la!</value>
|
||||
<value>Há uma nova versão do ASF disponível! Considere atualizar!</value>
|
||||
</data>
|
||||
<data name="UpdateVersionInfo" xml:space="preserve">
|
||||
<value>Versão local: {0} | Versão remota: {1}</value>
|
||||
@@ -279,7 +288,10 @@ StackTrace:
|
||||
<value>Por favor, insira o valor não-documentado de {0}: </value>
|
||||
<comment>{0} will be replaced by property name. Please note that this translation should end with space</comment>
|
||||
</data>
|
||||
|
||||
<data name="UserInputIPCHost" xml:space="preserve">
|
||||
<value>Por favor insira o seu anfitrião de IPC: </value>
|
||||
<comment>Please note that this translation should end with space</comment>
|
||||
</data>
|
||||
<data name="WarningUnknownValuePleaseReport" xml:space="preserve">
|
||||
<value>Valor desconhecido recebido por {0}, por favor reporte isto: {1}</value>
|
||||
<comment>{0} will be replaced by object's name, {1} will be replaced by value for that object</comment>
|
||||
@@ -288,10 +300,20 @@ StackTrace:
|
||||
<value>Não é possível jogar {0} ao mesmo tempo, apenas {0} jogos vão usados com {1}!</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="ErrorIPCAddressAccessDeniedException" xml:space="preserve">
|
||||
<value>Serviço de IPC não pode ser iniciado devido a AddressAccessDeniedException! Se quiser usar o serviço IPC fornecido pelo ASF, considere iniciar o ASF como administrador, ou dando permissões adequadas!</value>
|
||||
</data>
|
||||
<data name="IPCAnswered" xml:space="preserve">
|
||||
<value>Respondeu ao comando do IPC: {0} com: {1}</value>
|
||||
<comment>{0} will be replaced by IPC command, {1} will be replaced by IPC answer</comment>
|
||||
</data>
|
||||
<data name="IPCReady" xml:space="preserve">
|
||||
<value>Servidor IPC pronto!</value>
|
||||
</data>
|
||||
<data name="IPCStarting" xml:space="preserve">
|
||||
<value>Iniciando o servidor IPC em {0}...</value>
|
||||
<comment>{0} will be replaced by IPC hostname</comment>
|
||||
</data>
|
||||
<data name="BotAlreadyStopped" xml:space="preserve">
|
||||
<value>Este bot já parou!</value>
|
||||
</data>
|
||||
@@ -429,7 +451,10 @@ StackTrace:
|
||||
<data name="BotAutomaticIdlingPausedAlready" xml:space="preserve">
|
||||
<value>A coleta automática está pausada!</value>
|
||||
</data>
|
||||
|
||||
<data name="BotAutomaticIdlingPausedWithCountdown" xml:space="preserve">
|
||||
<value>A coleta automática está agora em pausa. Tens {0} para iniciar um jogo.</value>
|
||||
<comment>{0} will be replaced by translated TimeSpan string (such as "5 minutes")</comment>
|
||||
</data>
|
||||
<data name="BotAutomaticIdlingResumedAlready" xml:space="preserve">
|
||||
<value>A coleta automática já foi resumida!</value>
|
||||
</data>
|
||||
@@ -489,7 +514,7 @@ inválidas, abortando!</value>
|
||||
<value>Looting está temporariamente desligado!</value>
|
||||
</data>
|
||||
<data name="BotLootingYourself" xml:space="preserve">
|
||||
<value>Não se pode bloquear a si mesmo!</value>
|
||||
<value>Não podes colecionar os seus próprios itens!</value>
|
||||
</data>
|
||||
<data name="BotNoASFAuthenticator" xml:space="preserve">
|
||||
<value>Este bot não tem a ASF 2FA ligada! Esqueceu-se de importar seu autenticador como ASF 2FA?</value>
|
||||
@@ -505,7 +530,10 @@ inválidas, abortando!</value>
|
||||
<value>Já adquirido: {0} | {1}</value>
|
||||
<comment>{0} will be replaced by game's ID (number), {1} will be replaced by game's name</comment>
|
||||
</data>
|
||||
|
||||
<data name="BotRateLimitExceeded" xml:space="preserve">
|
||||
<value>Taxa limite excedida, tentaremos novamente daqui a {0}...</value>
|
||||
<comment>{0} will be replaced by translated TimeSpan string (such as "25 minutes")</comment>
|
||||
</data>
|
||||
<data name="BotReconnecting" xml:space="preserve">
|
||||
<value>Reconectando...</value>
|
||||
</data>
|
||||
@@ -635,8 +663,19 @@ inválidas, abortando!</value>
|
||||
<data name="ErrorAccessDenied" xml:space="preserve">
|
||||
<value>Acesso negado!</value>
|
||||
</data>
|
||||
|
||||
|
||||
|
||||
|
||||
<data name="WarningPreReleaseVersion" xml:space="preserve">
|
||||
<value>Estás a usar uma versão mais recente que a última versão do teu canal de atualização. Por favor considera que as versões de pré-lançamento são dedicados a utilizadores que sabem reportar erros, lidar com problemas e dar feedback - não irás receber suporte técnico.</value>
|
||||
</data>
|
||||
<data name="BotStats" xml:space="preserve">
|
||||
<value>Uso de memória atual: {0} MB.</value>
|
||||
<comment>{0} will be replaced by number (in megabytes) of memory being used</comment>
|
||||
</data>
|
||||
<data name="ClearingDiscoveryQueue" xml:space="preserve">
|
||||
<value>Passando a Fila de Exploração da Steam #{0}...</value>
|
||||
<comment>{0} will be replaced by queue number</comment>
|
||||
</data>
|
||||
<data name="DoneClearingDiscoveryQueue" xml:space="preserve">
|
||||
<value>Fila de exploração da Steam feita #{0}.</value>
|
||||
<comment>{0} will be replaced by queue number</comment>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -247,7 +247,8 @@ StackTrace:
|
||||
<value>Checking for new version...</value>
|
||||
</data>
|
||||
<data name="UpdateDownloadingNewVersion" xml:space="preserve">
|
||||
<value>Downloading new version... While waiting, consider donating if you appreciate the work being done! :)</value>
|
||||
<value>Downloading new version: {0} ({1} MB)... While waiting, consider donating if you appreciate the work being done! :)</value>
|
||||
<comment>{0} will be replaced by version string, {1} will be replaced by update size (in megabytes)</comment>
|
||||
</data>
|
||||
<data name="UpdateFinished" xml:space="preserve">
|
||||
<value>Update process finished!</value>
|
||||
|
||||
@@ -241,9 +241,7 @@ StackTrace:
|
||||
<data name="UpdateCheckingNewVersion" xml:space="preserve">
|
||||
<value>Se caută versiune nouă...</value>
|
||||
</data>
|
||||
<data name="UpdateDownloadingNewVersion" xml:space="preserve">
|
||||
<value>Se descarcă o versiune nouă... Cât timp aștepți, dacă consideri, poți dona dacă apreciezi toată munca depusă! :)</value>
|
||||
</data>
|
||||
|
||||
<data name="UpdateFinished" xml:space="preserve">
|
||||
<value>Proces de actualizare finalizat!</value>
|
||||
</data>
|
||||
|
||||
@@ -184,14 +184,19 @@
|
||||
<data name="ErrorUpdateCheckFailed" xml:space="preserve">
|
||||
<value>Не удалось проверить последнюю версию!</value>
|
||||
</data>
|
||||
|
||||
<data name="ErrorUpdateNoAssetForThisVersion" xml:space="preserve">
|
||||
<value>Невозможно произвести обновление, так как нет подходящих файлов, которые относятся к текущей запущенной версии! Автоматическое обновление до этой версии невозможно.</value>
|
||||
</data>
|
||||
<data name="ErrorUpdateNoAssets" xml:space="preserve">
|
||||
<value>Не могу обновиться, поскольку эта версия не содержит никаких файлов!</value>
|
||||
</data>
|
||||
<data name="ErrorUserInputRunningInHeadlessMode" xml:space="preserve">
|
||||
<value>Получен запрос на ввод данных пользователем, однако процесс идёт в безынтерфейсном режиме!</value>
|
||||
</data>
|
||||
|
||||
<data name="ErrorIPCAccessDenied" xml:space="preserve">
|
||||
<value>Отказ от обработки запроса, поскольку SteamOwnerID не задан!</value>
|
||||
<comment>SteamOwnerID is name of bot config property, it should not be translated</comment>
|
||||
</data>
|
||||
<data name="Exiting" xml:space="preserve">
|
||||
<value>Выход...</value>
|
||||
</data>
|
||||
@@ -242,7 +247,8 @@
|
||||
<value>Проверка новой версии...</value>
|
||||
</data>
|
||||
<data name="UpdateDownloadingNewVersion" xml:space="preserve">
|
||||
<value>Загрузка новой версии... Во время ожидания подумайте о пожертвовании в пользу разработчиков, если вы цените проделанную работу! :)</value>
|
||||
<value>Скачивание новой версии: {0} ({1} MB)... В ожидании, подумайте о пожертвовании, если вам нравится проделанная работа! :)</value>
|
||||
<comment>{0} will be replaced by version string, {1} will be replaced by update size (in megabytes)</comment>
|
||||
</data>
|
||||
<data name="UpdateFinished" xml:space="preserve">
|
||||
<value>Процесс обновления завершён!</value>
|
||||
@@ -282,7 +288,10 @@
|
||||
<value>Пожалуйста, введите недокументированное значение {0}: </value>
|
||||
<comment>{0} will be replaced by property name. Please note that this translation should end with space</comment>
|
||||
</data>
|
||||
|
||||
<data name="UserInputIPCHost" xml:space="preserve">
|
||||
<value>Пожалуйста, введите ваш хост IPC: </value>
|
||||
<comment>Please note that this translation should end with space</comment>
|
||||
</data>
|
||||
<data name="WarningUnknownValuePleaseReport" xml:space="preserve">
|
||||
<value>Получено неизвестное значение для {0}, пожалуйста, сообщите об этом: {1}</value>
|
||||
<comment>{0} will be replaced by object's name, {1} will be replaced by value for that object</comment>
|
||||
@@ -291,10 +300,20 @@
|
||||
<value>Невозможен запуск более {0} игр одновременно, будут использованы только первые {0} записей из параметра {1}!</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="ErrorIPCAddressAccessDeniedException" xml:space="preserve">
|
||||
<value>Сервис IPC не может быть запущен, из-за "AddressAccessDeniedException" (исключение: отказ в доступе к адресу)! Если Вы желаете использовать сервис IPC, предоставляемый ASF, то попробуйте запустить ASF от имени администратора, или выдать необходимые права!</value>
|
||||
</data>
|
||||
<data name="IPCAnswered" xml:space="preserve">
|
||||
<value>На команду IPC: {0} был ответ: {1}</value>
|
||||
<comment>{0} will be replaced by IPC command, {1} will be replaced by IPC answer</comment>
|
||||
</data>
|
||||
<data name="IPCReady" xml:space="preserve">
|
||||
<value>IPC сервер готов!</value>
|
||||
</data>
|
||||
<data name="IPCStarting" xml:space="preserve">
|
||||
<value>Запуск IPC сервера на {0}...</value>
|
||||
<comment>{0} will be replaced by IPC hostname</comment>
|
||||
</data>
|
||||
<data name="BotAlreadyStopped" xml:space="preserve">
|
||||
<value>Этот бот уже остановлен!</value>
|
||||
</data>
|
||||
|
||||
@@ -241,9 +241,7 @@ StackTrace:
|
||||
<data name="UpdateCheckingNewVersion" xml:space="preserve">
|
||||
<value>Kontrola najnovšej verzie...</value>
|
||||
</data>
|
||||
<data name="UpdateDownloadingNewVersion" xml:space="preserve">
|
||||
<value>Sťahovanie najnovšej verzie... Zváž podporu tohto projektu počas čakania! :)</value>
|
||||
</data>
|
||||
|
||||
<data name="UpdateFinished" xml:space="preserve">
|
||||
<value>Aktualizácia úspešne dokončená!</value>
|
||||
</data>
|
||||
|
||||
@@ -225,9 +225,7 @@ StackTrace:
|
||||
<data name="UpdateCheckingNewVersion" xml:space="preserve">
|
||||
<value>Traženje nove verzije...</value>
|
||||
</data>
|
||||
<data name="UpdateDownloadingNewVersion" xml:space="preserve">
|
||||
<value>Skidanje nove verzije... Dok čekate, razmislite o podržavanju ovoh programa putem donacija ako cenite uložen rad! :)</value>
|
||||
</data>
|
||||
|
||||
<data name="UpdateFinished" xml:space="preserve">
|
||||
<value>Proces ažuriranja je završen!</value>
|
||||
</data>
|
||||
|
||||
@@ -241,10 +241,7 @@ StackTrace:
|
||||
<data name="UpdateCheckingNewVersion" xml:space="preserve">
|
||||
<value>Söker efter senaste versionen...</value>
|
||||
</data>
|
||||
<data name="UpdateDownloadingNewVersion" xml:space="preserve">
|
||||
<value>Laddar ner senaste versionen... Medan du väntar, fundera på att donera om du uppskattar arbetet som görs!
|
||||
:)</value>
|
||||
</data>
|
||||
|
||||
<data name="UpdateFinished" xml:space="preserve">
|
||||
<value>Uppdateringsprocessen klar!</value>
|
||||
</data>
|
||||
|
||||
@@ -184,14 +184,19 @@ Yığın izleme:
|
||||
<data name="ErrorUpdateCheckFailed" xml:space="preserve">
|
||||
<value>En son sürüm kontrol edilemedi!</value>
|
||||
</data>
|
||||
|
||||
<data name="ErrorUpdateNoAssetForThisVersion" xml:space="preserve">
|
||||
<value>Şu anda çalışan sürüme ait hiçbir dosya olmadığı için güncelleme işlemine devam edemedi! Bu sürüme otomatik güncelleme yapmak mümkün değil.</value>
|
||||
</data>
|
||||
<data name="ErrorUpdateNoAssets" xml:space="preserve">
|
||||
<value>Sürüm herhangi bir öğe içermediğinden güncelleme ile devam edemedi!</value>
|
||||
</data>
|
||||
<data name="ErrorUserInputRunningInHeadlessMode" xml:space="preserve">
|
||||
<value>Kullanıcı girdisi için bir istek alındı; ancak işlem headless modda çalışıyor!</value>
|
||||
</data>
|
||||
|
||||
<data name="ErrorIPCAccessDenied" xml:space="preserve">
|
||||
<value>SteamOwnerID ayarlanmadığı için istek reddedildi!</value>
|
||||
<comment>SteamOwnerID is name of bot config property, it should not be translated</comment>
|
||||
</data>
|
||||
<data name="Exiting" xml:space="preserve">
|
||||
<value>Çıkılıyor...</value>
|
||||
</data>
|
||||
@@ -242,7 +247,8 @@ Yığın izleme:
|
||||
<value>Yeni sürüm kontrol ediliyor...</value>
|
||||
</data>
|
||||
<data name="UpdateDownloadingNewVersion" xml:space="preserve">
|
||||
<value>Yeni sürüm indiriliyor... Beklerken, yaptığımız çalışmayı takdir ediyorsanız bağış yapmayı düşünün! :)</value>
|
||||
<value>Yeni sürüm indiriliyor: {0} ({1} MB)... Beklerken, yaptığımız çalışmayı takdir ediyorsanız bağış yapmayı düşünün! :)</value>
|
||||
<comment>{0} will be replaced by version string, {1} will be replaced by update size (in megabytes)</comment>
|
||||
</data>
|
||||
<data name="UpdateFinished" xml:space="preserve">
|
||||
<value>Güncelleme işlemi tamamlandı!</value>
|
||||
@@ -282,7 +288,10 @@ Yığın izleme:
|
||||
<value>Lütfen belgelenmemiş {0} değerini girin: </value>
|
||||
<comment>{0} will be replaced by property name. Please note that this translation should end with space</comment>
|
||||
</data>
|
||||
|
||||
<data name="UserInputIPCHost" xml:space="preserve">
|
||||
<value>Lütfen IPC sunucunuzu girin: </value>
|
||||
<comment>Please note that this translation should end with space</comment>
|
||||
</data>
|
||||
<data name="WarningUnknownValuePleaseReport" xml:space="preserve">
|
||||
<value>{0} için bilinmeyen değer alındı, lütfen bunu bildirin: {1}</value>
|
||||
<comment>{0} will be replaced by object's name, {1} will be replaced by value for that object</comment>
|
||||
@@ -291,10 +300,20 @@ Yığın izleme:
|
||||
<value>Eşzamanlı olarak {0} oyundan fazlasını oynamak mümkün değildir, yalnızca {1} yapılandırmasından ilk {0} girdisi kullanılacaktır!</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="ErrorIPCAddressAccessDeniedException" xml:space="preserve">
|
||||
<value>IPC hizmeti AddressAccessDeniedException nedeniyle başlatılamadı! ASF tarafından sağlanan IPC hizmetini kullanmak istiyorsanız, ASF'yi yönetici olarak başlatmayı veya uygun izinler vermeyi düşünün!</value>
|
||||
</data>
|
||||
<data name="IPCAnswered" xml:space="preserve">
|
||||
<value>IPC komutu {0} için cevap: {1}</value>
|
||||
<comment>{0} will be replaced by IPC command, {1} will be replaced by IPC answer</comment>
|
||||
</data>
|
||||
<data name="IPCReady" xml:space="preserve">
|
||||
<value>IPC sunucusu hazır!</value>
|
||||
</data>
|
||||
<data name="IPCStarting" xml:space="preserve">
|
||||
<value>{0} sunucusunda IPC sunucusu başlatılıyor...</value>
|
||||
<comment>{0} will be replaced by IPC hostname</comment>
|
||||
</data>
|
||||
<data name="BotAlreadyStopped" xml:space="preserve">
|
||||
<value>Bu bot zaten durdurulmuş!</value>
|
||||
</data>
|
||||
|
||||
@@ -241,9 +241,7 @@
|
||||
<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>
|
||||
|
||||
@@ -121,7 +121,10 @@
|
||||
<value>Chấp nhận giao dịch: {0}</value>
|
||||
<comment>{0} will be replaced by trade number</comment>
|
||||
</data>
|
||||
|
||||
<data name="AutoUpdateCheckInfo" xml:space="preserve">
|
||||
<value>ASF sẽ tự động kiểm tra phiên bản mới mỗi {0}.</value>
|
||||
<comment>{0} will be replaced by translated TimeSpan string (such as "24 hours")</comment>
|
||||
</data>
|
||||
<data name="Content" xml:space="preserve">
|
||||
<value>Nội dung:
|
||||
{0}</value>
|
||||
@@ -141,7 +144,9 @@ 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>Đang thoát với mã lỗi khác không!</value>
|
||||
</data>
|
||||
<data name="ErrorFailingRequest" xml:space="preserve">
|
||||
<value>Yêu cầu thất bại: {0}</value>
|
||||
<comment>{0} will be replaced by URL of the request</comment>
|
||||
@@ -179,14 +184,19 @@ StackTrace:
|
||||
<data name="ErrorUpdateCheckFailed" xml:space="preserve">
|
||||
<value>Không thể kiểm tra phiên bản mới nhất!</value>
|
||||
</data>
|
||||
|
||||
<data name="ErrorUpdateNoAssetForThisVersion" xml:space="preserve">
|
||||
<value>Không thể tiến hành cập nhật vì không có asset liên quan đến phiên bản đang chạy! Tự động cập nhật lên phiên bản đó là không thể.</value>
|
||||
</data>
|
||||
<data name="ErrorUpdateNoAssets" xml:space="preserve">
|
||||
<value>Không thể tiến hành với bản cập nhật vì phiên bản đó không gồm bất cứ tài sản nào!</value>
|
||||
</data>
|
||||
<data name="ErrorUserInputRunningInHeadlessMode" xml:space="preserve">
|
||||
<value>Nhận được yêu cầu nhập của người dùng, nhưng quá trình đang chạy trong chế độ không kiểm soát!</value>
|
||||
</data>
|
||||
|
||||
<data name="ErrorIPCAccessDenied" xml:space="preserve">
|
||||
<value>Từ chối xử lý yêu cầu do SteamOwnerID chưa được đặt!</value>
|
||||
<comment>SteamOwnerID is name of bot config property, it should not be translated</comment>
|
||||
</data>
|
||||
<data name="Exiting" xml:space="preserve">
|
||||
<value>Đang thoát...</value>
|
||||
</data>
|
||||
@@ -218,7 +228,7 @@ StackTrace:
|
||||
<comment>{0} will be replaced by trade number</comment>
|
||||
</data>
|
||||
<data name="Restarting" xml:space="preserve">
|
||||
<value>Khởi động lại...</value>
|
||||
<value>Đang khởi động lại...</value>
|
||||
</data>
|
||||
<data name="Starting" xml:space="preserve">
|
||||
<value>Bắt đầu...</value>
|
||||
@@ -237,7 +247,8 @@ StackTrace:
|
||||
<value>Kiểm tra phiên bản mới...</value>
|
||||
</data>
|
||||
<data name="UpdateDownloadingNewVersion" xml:space="preserve">
|
||||
<value>Tải xuống phiên bản mới... Trong khi chờ đợi, hãy xem xét quyên góp nếu bạn đánh giá cao công việc được thực hiện! :)</value>
|
||||
<value>Đang tải phiên bản mới: {0} ({1} MB)... Trong khi chờ, hãy xem xét quyên góp nếu bạn đánh giá cao sản phẩm được thực hiện! :)</value>
|
||||
<comment>{0} will be replaced by version string, {1} will be replaced by update size (in megabytes)</comment>
|
||||
</data>
|
||||
<data name="UpdateFinished" xml:space="preserve">
|
||||
<value>Quá trình cập nhật hoàn tất!</value>
|
||||
@@ -277,7 +288,10 @@ StackTrace:
|
||||
<value>Xin vui lòng nhập các giá trị không có giấy tờ của {0}: </value>
|
||||
<comment>{0} will be replaced by property name. Please note that this translation should end with space</comment>
|
||||
</data>
|
||||
|
||||
<data name="UserInputIPCHost" xml:space="preserve">
|
||||
<value>Vui lòng nhập IPC host của bạn: </value>
|
||||
<comment>Please note that this translation should end with space</comment>
|
||||
</data>
|
||||
<data name="WarningUnknownValuePleaseReport" xml:space="preserve">
|
||||
<value>Nhận được giá trị không rõ cho {0}, xin vui lòng báo cáo điều này: {1}</value>
|
||||
<comment>{0} will be replaced by object's name, {1} will be replaced by value for that object</comment>
|
||||
@@ -286,10 +300,20 @@ StackTrace:
|
||||
<value>Chơi nhiều hơn {0} trò chơi đồng thời là không thể, chỉ {0} trò chơi đầu tiên {1} sẽ được sử dụng!</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="ErrorIPCAddressAccessDeniedException" xml:space="preserve">
|
||||
<value>Dịch vụ IPC không thể chạy do AddressAccessDeniedException! Nếu bạn muốn dùng dịch vụ IPC được cung cấp bởi ASF, hãy chạy ASF bằng quyền admin, hoặc cấp quyền thích hợp!</value>
|
||||
</data>
|
||||
<data name="IPCAnswered" xml:space="preserve">
|
||||
<value>Đã trả lời lệnh IPC: {0} với: {1}</value>
|
||||
<comment>{0} will be replaced by IPC command, {1} will be replaced by IPC answer</comment>
|
||||
</data>
|
||||
<data name="IPCReady" xml:space="preserve">
|
||||
<value>IPC server đã sẵn sàng!</value>
|
||||
</data>
|
||||
<data name="IPCStarting" xml:space="preserve">
|
||||
<value>Khởi động IPC server trên {0}...</value>
|
||||
<comment>{0} will be replaced by IPC hostname</comment>
|
||||
</data>
|
||||
<data name="BotAlreadyStopped" xml:space="preserve">
|
||||
<value>Bot này đã được dừng lại!</value>
|
||||
</data>
|
||||
@@ -301,8 +325,14 @@ StackTrace:
|
||||
<value>Đang có {0}/{1} bot đang chạy, với tổng số {2} games ({3} cards) còn lại để chạy không.</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 đang cày game: {0} ({1}, {2} card còn lại) từ tổng cộng {3} game ({4} card) còn lại để cày (~{5} còn lại).</value>
|
||||
<comment>{0} will be replaced by game's ID (number), {1} will be replaced by game's name, {2} will be replaced by number of cards left to idle, {3} will be replaced by total number of games to idle, {4} will be replaced by total number of cards to idle, {5} will be replaced by translated TimeSpan string (such as "1 day, 5 hours and 30 minutes")</comment>
|
||||
</data>
|
||||
<data name="BotStatusIdlingList" xml:space="preserve">
|
||||
<value>Bot đang cày game: {0} từ tổng cộng {1} game ({2} card) còn lại để cày (~{3} còn lại).</value>
|
||||
<comment>{0} will be replaced by list of the games (IDs, numbers), {1} will be replaced by total number of games to idle, {2} will be replaced by total number of cards to idle, {3} will be replaced by translated TimeSpan string (such as "1 day, 5 hours and 30 minutes")</comment>
|
||||
</data>
|
||||
<data name="CheckingFirstBadgePage" xml:space="preserve">
|
||||
<value>Kiểm tra trang huy hiệu đầu tiên...</value>
|
||||
</data>
|
||||
@@ -388,8 +418,14 @@ StackTrace:
|
||||
<data name="BotAccountLimited" xml:space="preserve">
|
||||
<value>Tài khoản này bị giới hạn, quá trình chạy không sẽ không khả dụng cho đến khi những hạn chế sẽ bị gỡ bỏ!</value>
|
||||
</data>
|
||||
|
||||
|
||||
<data name="BotAddLicense" xml:space="preserve">
|
||||
<value>ID: {0} | Trạng thái: {1}</value>
|
||||
<comment>{0} will be replaced by game's ID (number), {1} will be replaced by status string</comment>
|
||||
</data>
|
||||
<data name="BotAddLicenseWithItems" xml:space="preserve">
|
||||
<value>ID: {0} | Trạng thái: {1} | Mục: {2}</value>
|
||||
<comment>{0} will be replaced by game's ID (number), {1} will be replaced by status string, {2} will be replaced by list of granted IDs (numbers), separated by a comma</comment>
|
||||
</data>
|
||||
<data name="BotAlreadyRunning" xml:space="preserve">
|
||||
<value>Bot này đang được chạy!</value>
|
||||
</data>
|
||||
@@ -406,12 +442,19 @@ StackTrace:
|
||||
<value>2FA Token: {0}</value>
|
||||
<comment>{0} will be replaced by generated 2FA token (string)</comment>
|
||||
</data>
|
||||
|
||||
|
||||
<data name="BotAutomaticIdlingNowPaused" xml:space="preserve">
|
||||
<value>Tự động idling đã tạm dừng!</value>
|
||||
</data>
|
||||
<data name="BotAutomaticIdlingNowResumed" xml:space="preserve">
|
||||
<value>Tự động idling đã tiếp tục trở lại!</value>
|
||||
</data>
|
||||
<data name="BotAutomaticIdlingPausedAlready" xml:space="preserve">
|
||||
<value>Tự động chạy không đã tạm dừng!</value>
|
||||
</data>
|
||||
|
||||
<data name="BotAutomaticIdlingPausedWithCountdown" xml:space="preserve">
|
||||
<value>Tự động cày đã tạm dừng! Bạn có {0} để bắt đầu 1 game.</value>
|
||||
<comment>{0} will be replaced by translated TimeSpan string (such as "5 minutes")</comment>
|
||||
</data>
|
||||
<data name="BotAutomaticIdlingResumedAlready" xml:space="preserve">
|
||||
<value>Tự động chạy không đã tiếp tục!</value>
|
||||
</data>
|
||||
@@ -451,7 +494,9 @@ StackTrace:
|
||||
<data name="BotLootingFailed" xml:space="preserve">
|
||||
<value>Lời mời giao dịch thất bại!</value>
|
||||
</data>
|
||||
|
||||
<data name="BotLootingMasterNotDefined" xml:space="preserve">
|
||||
<value>Giao dịch không thể gửi do không có user có quyền master xác định!</value>
|
||||
</data>
|
||||
<data name="BotLootingNoLootableTypes" xml:space="preserve">
|
||||
<value>Bạn không có bất kỳ cái gì có thể luộc được!</value>
|
||||
</data>
|
||||
@@ -476,17 +521,29 @@ StackTrace:
|
||||
<data name="BotNotConnected" xml:space="preserve">
|
||||
<value>Bot này không được kết nối!</value>
|
||||
</data>
|
||||
|
||||
<data name="BotNotOwnedYet" xml:space="preserve">
|
||||
<value>Chưa sở hữu: {0}</value>
|
||||
<comment>{0} will be replaced by query (string)</comment>
|
||||
</data>
|
||||
<data name="BotOwnedAlreadyWithName" xml:space="preserve">
|
||||
<value>Đã sở hữu: {0} | {1}</value>
|
||||
<comment>{0} will be replaced by game's ID (number), {1} will be replaced by game's name</comment>
|
||||
</data>
|
||||
|
||||
<data name="BotRateLimitExceeded" xml:space="preserve">
|
||||
<value>Vượt quá số lượng giới hạn; chúng tôi sẽ thử lại sau {0} đếm ngược...</value>
|
||||
<comment>{0} will be replaced by translated TimeSpan string (such as "25 minutes")</comment>
|
||||
</data>
|
||||
<data name="BotReconnecting" xml:space="preserve">
|
||||
<value>Đang kết nối lại...</value>
|
||||
</data>
|
||||
|
||||
|
||||
<data name="BotRedeem" xml:space="preserve">
|
||||
<value>Key: {0} | Status: {1}</value>
|
||||
<comment>{0} will be replaced by cd-key (string), {1} will be replaced by status string</comment>
|
||||
</data>
|
||||
<data name="BotRedeemWithItems" xml:space="preserve">
|
||||
<value>Key: {0} | Status: {1} | Items: {2}</value>
|
||||
<comment>{0} will be replaced by cd-key (string), {1} will be replaced by status string, {2} will be replaced by list of key-value pairs, separated by a comma</comment>
|
||||
</data>
|
||||
<data name="BotRemovedExpiredLoginKey" xml:space="preserve">
|
||||
<value>Gỡ bỏ key đăng nhập hết hạn!</value>
|
||||
</data>
|
||||
@@ -496,7 +553,9 @@ StackTrace:
|
||||
<data name="BotStatusLimited" xml:space="preserve">
|
||||
<value>Bot bị hạn chế và không thể rớt bất kỳ thẻ thông qua chạy không.</value>
|
||||
</data>
|
||||
|
||||
<data name="BotStatusConnecting" xml:space="preserve">
|
||||
<value>Bot đang kết nối với Steam network.</value>
|
||||
</data>
|
||||
<data name="BotStatusNotRunning" xml:space="preserve">
|
||||
<value>Bot không chạy.</value>
|
||||
</data>
|
||||
@@ -575,7 +634,10 @@ StackTrace:
|
||||
<value>ASF sẽ cố gắng sử dụng mã ngôn ngữ {0} ưa thích của bạn, nhưng bản dịch ngôn ngữ đó hoàn thiện chỉ được {1}. Có lẽ bạn có thể giúp chúng tôi cải thiện bản dịch ASF cho ngôn ngữ của bạn?</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="IdlingGameNotPossible" xml:space="preserve">
|
||||
<value>Việc cày {0} ({1}) tạm thời bị vô hiệu hóa, ASF không thể mở game đó lúc này.</value>
|
||||
<comment>{0} will be replaced by game's ID (number), {1} will be replaced by game's name</comment>
|
||||
</data>
|
||||
<data name="WarningIdlingGameMismatch" xml:space="preserve">
|
||||
<value>ASF phát hiện ID không khớp với {0} ({1}) và sẽ sử dụng ID {2} thay thế.</value>
|
||||
<comment>{0} will be replaced by game's ID (number), {1} will be replaced by game's name, {2} will be replaced by game's ID (number)</comment>
|
||||
@@ -584,18 +646,35 @@ StackTrace:
|
||||
<value>{0} V{1}</value>
|
||||
<comment>{0} will be replaced by program's name (e.g. "ASF"), {1} will be replaced by program's version (e.g. "1.0.0.0"). This string typically has nothing to translate and you should leave it as it is, unless you need to change the format, e.g. in RTL languages.</comment>
|
||||
</data>
|
||||
|
||||
<data name="BotAccountLocked" xml:space="preserve">
|
||||
<value>Tài khoản này bị khóa, quá trình cày card không chạy!</value>
|
||||
</data>
|
||||
<data name="BotStatusLocked" xml:space="preserve">
|
||||
<value>Bot bị khóa và không thể rớt bất kỳ thẻ thông qua chạy không.</value>
|
||||
</data>
|
||||
|
||||
<data name="ErrorFunctionOnlyInHeadlessMode" xml:space="preserve">
|
||||
<value>Chức năng này chỉ có sẵn trong headless mode!</value>
|
||||
</data>
|
||||
<data name="BotOwnedAlready" xml:space="preserve">
|
||||
<value>Đã sở hữu: {0}</value>
|
||||
<comment>{0} will be replaced by game's ID (number), {1} will be replaced by game's name</comment>
|
||||
</data>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<data name="ErrorAccessDenied" xml:space="preserve">
|
||||
<value>Truy cập bị từ chối!</value>
|
||||
</data>
|
||||
<data name="WarningPreReleaseVersion" xml:space="preserve">
|
||||
<value>Bạn đang dùng phiên bản mới hơn phiên bản chính thức mới nhất. Hãy chú ý rằng phiên bản phát hành trước là dành cho người dùng biết cách báo lỗi, xử lý vấn đề và gửi phản hồi - sẽ không có hỗ trợ kỹ thuật.</value>
|
||||
</data>
|
||||
<data name="BotStats" xml:space="preserve">
|
||||
<value>Bộ nhớ đang được sử dụng: {0} MB.</value>
|
||||
<comment>{0} will be replaced by number (in megabytes) of memory being used</comment>
|
||||
</data>
|
||||
<data name="ClearingDiscoveryQueue" xml:space="preserve">
|
||||
<value>Đã xóa hàng đợi khám phá Steam số #{0}...</value>
|
||||
<comment>{0} will be replaced by queue number</comment>
|
||||
</data>
|
||||
<data name="DoneClearingDiscoveryQueue" xml:space="preserve">
|
||||
<value>Đã xóa hàng đợi khám phá Steam số #{0}.</value>
|
||||
<comment>{0} will be replaced by queue number</comment>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -238,9 +238,7 @@
|
||||
<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>
|
||||
|
||||
@@ -238,9 +238,7 @@
|
||||
<data name="UpdateCheckingNewVersion" xml:space="preserve">
|
||||
<value>正在檢查新版本...</value>
|
||||
</data>
|
||||
<data name="UpdateDownloadingNewVersion" xml:space="preserve">
|
||||
<value>正在下載新版本... 等待期間,如果喜歡這個軟體,請考慮捐助ASF! :)</value>
|
||||
</data>
|
||||
|
||||
<data name="UpdateFinished" xml:space="preserve">
|
||||
<value>更新完成 !</value>
|
||||
</data>
|
||||
|
||||
@@ -94,8 +94,6 @@ namespace ArchiSteamFarm {
|
||||
internal enum EExecutionState : uint {
|
||||
Error = 0,
|
||||
SystemRequired = 0x00000001,
|
||||
//DisplayRequired = 0x00000002,
|
||||
//UserPresent = 0x00000004,
|
||||
AwayModeRequired = 0x00000040,
|
||||
Continuous = 0x80000000
|
||||
}
|
||||
|
||||
@@ -135,13 +135,17 @@ namespace ArchiSteamFarm {
|
||||
ASF.ArchiLogger.LogGenericException(e);
|
||||
}
|
||||
|
||||
// Give new process some time to take over the window (if needed)
|
||||
await Task.Delay(2000).ConfigureAwait(false);
|
||||
|
||||
ShutdownResetEvent.Set();
|
||||
Environment.Exit(0);
|
||||
}
|
||||
|
||||
private static async Task Init(string[] args) {
|
||||
AppDomain.CurrentDomain.UnhandledException += UnhandledExceptionHandler;
|
||||
TaskScheduler.UnobservedTaskException += UnobservedTaskExceptionHandler;
|
||||
AppDomain.CurrentDomain.ProcessExit += OnProcessExit;
|
||||
AppDomain.CurrentDomain.UnhandledException += OnUnhandledException;
|
||||
TaskScheduler.UnobservedTaskException += OnUnobservedTaskException;
|
||||
|
||||
// We must register our logging target as soon as possible
|
||||
Target.Register<SteamTarget>(SteamTarget.TargetName);
|
||||
@@ -306,7 +310,7 @@ namespace ArchiSteamFarm {
|
||||
OS.Init(GlobalConfig.Headless);
|
||||
WebBrowser.Init();
|
||||
|
||||
WebBrowser = new WebBrowser(ASF.ArchiLogger);
|
||||
WebBrowser = new WebBrowser(ASF.ArchiLogger, true);
|
||||
}
|
||||
|
||||
private static async Task<bool> InitShutdownSequence() {
|
||||
@@ -316,8 +320,6 @@ namespace ArchiSteamFarm {
|
||||
|
||||
ShutdownSequenceInitialized = true;
|
||||
|
||||
IPC.Stop();
|
||||
|
||||
if (Bot.Bots.Count == 0) {
|
||||
return true;
|
||||
}
|
||||
@@ -327,12 +329,12 @@ namespace ArchiSteamFarm {
|
||||
switch (GlobalConfig.OptimizationMode) {
|
||||
case GlobalConfig.EOptimizationMode.MinMemoryUsage:
|
||||
foreach (Task task in tasks) {
|
||||
await Task.WhenAny(task, Task.Delay(WebBrowser.MaxRetries * 1000)).ConfigureAwait(false);
|
||||
await Task.WhenAny(task, Task.Delay(WebBrowser.MaxTries * 1000)).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
break;
|
||||
default:
|
||||
await Task.WhenAny(Task.WhenAll(tasks), Task.Delay(Bot.Bots.Count * WebBrowser.MaxRetries * 1000)).ConfigureAwait(false);
|
||||
await Task.WhenAny(Task.WhenAll(tasks), Task.Delay(Bot.Bots.Count * WebBrowser.MaxTries * 1000)).ConfigureAwait(false);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -350,6 +352,31 @@ namespace ArchiSteamFarm {
|
||||
Exit().Wait();
|
||||
}
|
||||
|
||||
private static void OnProcessExit(object sender, EventArgs e) => IPC.Stop();
|
||||
|
||||
private static async void OnUnhandledException(object sender, UnhandledExceptionEventArgs e) {
|
||||
if (e?.ExceptionObject == null) {
|
||||
ASF.ArchiLogger.LogNullError(nameof(e) + " || " + nameof(e.ExceptionObject));
|
||||
return;
|
||||
}
|
||||
|
||||
ASF.ArchiLogger.LogFatalException((Exception) e.ExceptionObject);
|
||||
await Exit(1).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
private static void OnUnobservedTaskException(object sender, UnobservedTaskExceptionEventArgs e) {
|
||||
if (e?.Exception == null) {
|
||||
ASF.ArchiLogger.LogNullError(nameof(e) + " || " + nameof(e.Exception));
|
||||
return;
|
||||
}
|
||||
|
||||
ASF.ArchiLogger.LogFatalException(e.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.
|
||||
e.SetObserved();
|
||||
}
|
||||
|
||||
private static void ParsePostInitArgs(IEnumerable<string> args) {
|
||||
if (args == null) {
|
||||
ASF.ArchiLogger.LogNullError(nameof(args));
|
||||
@@ -404,28 +431,5 @@ namespace ArchiSteamFarm {
|
||||
|
||||
ShutdownResetEvent.Set();
|
||||
}
|
||||
|
||||
private static async void UnhandledExceptionHandler(object sender, UnhandledExceptionEventArgs e) {
|
||||
if (e?.ExceptionObject == null) {
|
||||
ASF.ArchiLogger.LogNullError(nameof(e) + " || " + nameof(e.ExceptionObject));
|
||||
return;
|
||||
}
|
||||
|
||||
ASF.ArchiLogger.LogFatalException((Exception) e.ExceptionObject);
|
||||
await Exit(1).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
private static void UnobservedTaskExceptionHandler(object sender, UnobservedTaskExceptionEventArgs e) {
|
||||
if (e?.Exception == null) {
|
||||
ASF.ArchiLogger.LogNullError(nameof(e) + " || " + nameof(e.Exception));
|
||||
return;
|
||||
}
|
||||
|
||||
ASF.ArchiLogger.LogFatalException(e.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.
|
||||
e.SetObserved();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -32,7 +32,7 @@ using ArchiSteamFarm.Localization;
|
||||
|
||||
namespace ArchiSteamFarm {
|
||||
internal sealed class Trading : IDisposable {
|
||||
internal const byte MaxItemsPerTrade = 150; // This is due to limit on POST size in WebBrowser
|
||||
internal const byte MaxItemsPerTrade = byte.MaxValue; // This is due to limit on POST size in WebBrowser
|
||||
internal const byte MaxTradesPerAccount = 5; // This is limit introduced by Valve
|
||||
|
||||
private readonly Bot Bot;
|
||||
@@ -173,7 +173,7 @@ namespace ArchiSteamFarm {
|
||||
return new ParseTradeResult(tradeOffer.TradeOfferID, tradeOffer.ItemsToGive.Count > 0 ? ParseTradeResult.EResult.AcceptedWithItemLose : ParseTradeResult.EResult.AcceptedWithoutItemLose);
|
||||
}
|
||||
|
||||
// Always deny trades from blacklistem steamIDs
|
||||
// Always deny trades from blacklisted steamIDs
|
||||
if (Bot.IsBlacklistedFromTrades(tradeOffer.OtherSteamID64)) {
|
||||
return new ParseTradeResult(tradeOffer.TradeOfferID, ParseTradeResult.EResult.RejectedPermanently);
|
||||
}
|
||||
@@ -214,8 +214,8 @@ namespace ArchiSteamFarm {
|
||||
return new ParseTradeResult(tradeOffer.TradeOfferID, ParseTradeResult.EResult.RejectedPermanently);
|
||||
}
|
||||
|
||||
// Decline trade if we're losing anything but steam cards, or if it's non-dupes trade
|
||||
if (!tradeOffer.IsSteamCardsRequest() || !tradeOffer.IsFairTypesExchange()) {
|
||||
// Decline trade if it's not fair games/types exchange or if we're requested to handle any not-accepted item type
|
||||
if (!tradeOffer.IsFairTypesExchange() || !tradeOffer.IsValidSteamItemsRequest(Bot.BotConfig.MatchableTypes)) {
|
||||
return new ParseTradeResult(tradeOffer.TradeOfferID, ParseTradeResult.EResult.RejectedPermanently);
|
||||
}
|
||||
|
||||
@@ -241,17 +241,35 @@ namespace ArchiSteamFarm {
|
||||
return new ParseTradeResult(tradeOffer.TradeOfferID, ParseTradeResult.EResult.AcceptedWithItemLose);
|
||||
}
|
||||
|
||||
// Get appIDs we're interested in
|
||||
HashSet<uint> appIDs = new HashSet<uint>(tradeOffer.ItemsToGive.Select(item => item.RealAppID));
|
||||
// Get appIDs/types we're interested in
|
||||
HashSet<uint> appIDs = new HashSet<uint>();
|
||||
HashSet<Steam.Item.EType> types = new HashSet<Steam.Item.EType>();
|
||||
|
||||
foreach (Steam.Item item in tradeOffer.ItemsToGive) {
|
||||
appIDs.Add(item.RealAppID);
|
||||
types.Add(item.Type);
|
||||
}
|
||||
|
||||
// Now check if it's worth for us to do the trade
|
||||
HashSet<Steam.Item> inventory = await Bot.ArchiWebHandler.GetMySteamInventory(false, new HashSet<Steam.Item.EType> { Steam.Item.EType.TradingCard }, appIDs).ConfigureAwait(false);
|
||||
HashSet<Steam.Item> inventory = await Bot.ArchiWebHandler.GetMySteamInventory(false, types, appIDs).ConfigureAwait(false);
|
||||
if ((inventory == null) || (inventory.Count == 0)) {
|
||||
// If we can't check our inventory when not using MatchEverything, this is a temporary failure
|
||||
Bot.ArchiLogger.LogGenericWarning(string.Format(Strings.ErrorIsEmpty, nameof(inventory)));
|
||||
return new ParseTradeResult(tradeOffer.TradeOfferID, ParseTradeResult.EResult.RejectedTemporarily);
|
||||
}
|
||||
|
||||
bool accept = IsTradeNeutralOrBetter(inventory, tradeOffer.ItemsToGive, tradeOffer.ItemsToReceive);
|
||||
|
||||
// Even if trade is not neutral+ for us right now, it might be in the future, unless we're bot account where we assume that inventory doesn't change
|
||||
return new ParseTradeResult(tradeOffer.TradeOfferID, accept ? ParseTradeResult.EResult.AcceptedWithItemLose : (Bot.BotConfig.IsBotAccount ? ParseTradeResult.EResult.RejectedPermanently : ParseTradeResult.EResult.RejectedTemporarily));
|
||||
}
|
||||
|
||||
private static bool IsTradeNeutralOrBetter(HashSet<Steam.Item> inventory, HashSet<Steam.Item> itemsToGive, HashSet<Steam.Item> itemsToReceive) {
|
||||
if ((inventory == null) || (inventory.Count == 0) || (itemsToGive == null) || (itemsToGive.Count == 0) || (itemsToReceive == null) || (itemsToReceive.Count == 0)) {
|
||||
ASF.ArchiLogger.LogNullError(nameof(inventory) + " || " + nameof(itemsToGive) + " || " + nameof(itemsToReceive));
|
||||
return false;
|
||||
}
|
||||
|
||||
// Now let's create a map which maps items to their amount in our EQ
|
||||
// This has to be done as we might have multiple items of given ClassID with multiple amounts
|
||||
Dictionary<ulong, uint> itemAmounts = new Dictionary<ulong, uint>();
|
||||
@@ -264,12 +282,12 @@ namespace ArchiSteamFarm {
|
||||
}
|
||||
|
||||
// Calculate our value of items to give on per-game basis
|
||||
Dictionary<uint, List<uint>> itemAmountToGivePerGame = new Dictionary<uint, List<uint>>(appIDs.Count);
|
||||
Dictionary<(Steam.Item.EType Type, uint AppID), List<uint>> itemAmountToGivePerGame = new Dictionary<(Steam.Item.EType Type, uint AppID), List<uint>>();
|
||||
Dictionary<ulong, uint> itemAmountsToGive = new Dictionary<ulong, uint>(itemAmounts);
|
||||
foreach (Steam.Item item in tradeOffer.ItemsToGive) {
|
||||
if (!itemAmountToGivePerGame.TryGetValue(item.RealAppID, out List<uint> amountsToGive)) {
|
||||
foreach (Steam.Item item in itemsToGive) {
|
||||
if (!itemAmountToGivePerGame.TryGetValue((item.Type, item.RealAppID), out List<uint> amountsToGive)) {
|
||||
amountsToGive = new List<uint>();
|
||||
itemAmountToGivePerGame[item.RealAppID] = amountsToGive;
|
||||
itemAmountToGivePerGame[(item.Type, item.RealAppID)] = amountsToGive;
|
||||
}
|
||||
|
||||
if (!itemAmountsToGive.TryGetValue(item.ClassID, out uint amount)) {
|
||||
@@ -287,12 +305,12 @@ namespace ArchiSteamFarm {
|
||||
}
|
||||
|
||||
// Calculate our value of items to receive on per-game basis
|
||||
Dictionary<uint, List<uint>> itemAmountToReceivePerGame = new Dictionary<uint, List<uint>>(appIDs.Count);
|
||||
Dictionary<(Steam.Item.EType Type, uint AppID), List<uint>> itemAmountToReceivePerGame = new Dictionary<(Steam.Item.EType Type, uint AppID), List<uint>>();
|
||||
Dictionary<ulong, uint> itemAmountsToReceive = new Dictionary<ulong, uint>(itemAmounts);
|
||||
foreach (Steam.Item item in tradeOffer.ItemsToReceive) {
|
||||
if (!itemAmountToReceivePerGame.TryGetValue(item.RealAppID, out List<uint> amountsToReceive)) {
|
||||
foreach (Steam.Item item in itemsToReceive) {
|
||||
if (!itemAmountToReceivePerGame.TryGetValue((item.Type, item.RealAppID), out List<uint> amountsToReceive)) {
|
||||
amountsToReceive = new List<uint>();
|
||||
itemAmountToReceivePerGame[item.RealAppID] = amountsToReceive;
|
||||
itemAmountToReceivePerGame[(item.Type, item.RealAppID)] = amountsToReceive;
|
||||
}
|
||||
|
||||
if (!itemAmountsToReceive.TryGetValue(item.ClassID, out uint amount)) {
|
||||
@@ -313,10 +331,7 @@ namespace ArchiSteamFarm {
|
||||
// This is quite complex operation of taking minimum difference from all differences on per-game basis
|
||||
// When calculating per-game difference, we sum only amounts at proper indexes, because user might be overpaying
|
||||
int difference = itemAmountToGivePerGame.Min(kv => kv.Value.Select((t, i) => (int) (t - itemAmountToReceivePerGame[kv.Key][i])).Sum());
|
||||
|
||||
// Trade is neutral+ for us if the difference is greater than 0
|
||||
// If not, we assume that the trade might be good for us in the future, unless we're bot account where we assume that inventory doesn't change
|
||||
return new ParseTradeResult(tradeOffer.TradeOfferID, difference > 0 ? ParseTradeResult.EResult.AcceptedWithItemLose : (Bot.BotConfig.IsBotAccount ? ParseTradeResult.EResult.RejectedPermanently : ParseTradeResult.EResult.RejectedTemporarily));
|
||||
return difference > 0;
|
||||
}
|
||||
|
||||
private sealed class ParseTradeResult {
|
||||
|
||||
@@ -95,22 +95,34 @@ namespace ArchiSteamFarm {
|
||||
}
|
||||
}
|
||||
|
||||
internal static void StartBackgroundAction(Action action) {
|
||||
internal static void StartBackgroundAction(Action action, bool longRunning = true) {
|
||||
if (action == null) {
|
||||
ASF.ArchiLogger.LogNullError(nameof(action));
|
||||
return;
|
||||
}
|
||||
|
||||
Task.Factory.StartNew(action, TaskCreationOptions.DenyChildAttach | TaskCreationOptions.LongRunning).Forget();
|
||||
TaskCreationOptions options = TaskCreationOptions.DenyChildAttach;
|
||||
|
||||
if (longRunning) {
|
||||
options |= TaskCreationOptions.LongRunning;
|
||||
}
|
||||
|
||||
Task.Factory.StartNew(action, options).Forget();
|
||||
}
|
||||
|
||||
internal static void StartBackgroundFunction(Func<Task> function) {
|
||||
internal static void StartBackgroundFunction(Func<Task> function, bool longRunning = true) {
|
||||
if (function == null) {
|
||||
ASF.ArchiLogger.LogNullError(nameof(function));
|
||||
return;
|
||||
}
|
||||
|
||||
Task.Factory.StartNew(function, TaskCreationOptions.DenyChildAttach | TaskCreationOptions.LongRunning).Forget();
|
||||
TaskCreationOptions options = TaskCreationOptions.DenyChildAttach;
|
||||
|
||||
if (longRunning) {
|
||||
options |= TaskCreationOptions.LongRunning;
|
||||
}
|
||||
|
||||
Task.Factory.StartNew(function, options).Forget();
|
||||
}
|
||||
|
||||
internal static IEnumerable<T> ToEnumerable<T>(this T item) where T : struct {
|
||||
|
||||
@@ -35,26 +35,28 @@ using Newtonsoft.Json.Linq;
|
||||
|
||||
namespace ArchiSteamFarm {
|
||||
internal sealed class WebBrowser {
|
||||
internal const byte MaxRetries = 5; // Defines maximum number of retries, UrlRequest() does not handle retry by itself (it's app responsibility)
|
||||
internal const byte MaxTries = 5; // Defines maximum number of recommended tries for a single request
|
||||
|
||||
private const byte MaxConnections = ServicePointManager.DefaultNonPersistentConnectionLimit; // Defines maximum number of connections per ServicePoint. Be careful, as it also defines maximum number of sockets in CLOSE_WAIT state
|
||||
private const byte MaxIdleTime = 15; // In seconds, how long socket is allowed to stay in CLOSE_WAIT state after there are no connections to it
|
||||
private const byte ExtendedTimeoutMultiplier = 10; // Defines multiplier of timeout for WebBrowsers dealing with huge data (ASF update)
|
||||
private const byte MaxConnections = 10; // Defines maximum number of connections per ServicePoint. Be careful, as it also defines maximum number of sockets in CLOSE_WAIT state
|
||||
private const byte MaxIdleTime = 15; // Defines in seconds, how long socket is allowed to stay in CLOSE_WAIT state after there are no connections to it
|
||||
|
||||
internal readonly CookieContainer CookieContainer = new CookieContainer();
|
||||
|
||||
private readonly ArchiLogger ArchiLogger;
|
||||
private readonly HttpClient HttpClient;
|
||||
|
||||
internal WebBrowser(ArchiLogger archiLogger) {
|
||||
internal WebBrowser(ArchiLogger archiLogger, bool extendedTimeout = false) {
|
||||
ArchiLogger = archiLogger ?? throw new ArgumentNullException(nameof(archiLogger));
|
||||
|
||||
HttpClientHandler httpClientHandler = new HttpClientHandler {
|
||||
AutomaticDecompression = DecompressionMethods.Deflate | DecompressionMethods.GZip,
|
||||
CookieContainer = CookieContainer
|
||||
CookieContainer = CookieContainer,
|
||||
MaxConnectionsPerServer = MaxConnections
|
||||
};
|
||||
|
||||
HttpClient = new HttpClient(httpClientHandler) {
|
||||
Timeout = TimeSpan.FromSeconds(Program.GlobalConfig.ConnectionTimeout)
|
||||
Timeout = TimeSpan.FromSeconds(extendedTimeout ? ExtendedTimeoutMultiplier * Program.GlobalConfig.ConnectionTimeout : Program.GlobalConfig.ConnectionTimeout)
|
||||
};
|
||||
|
||||
// Most web services expect that UserAgent is set, so we declare it globally
|
||||
@@ -94,7 +96,7 @@ namespace ArchiSteamFarm {
|
||||
}
|
||||
|
||||
byte[] result = null;
|
||||
for (byte i = 0; (i < MaxRetries) && (result == null); i++) {
|
||||
for (byte i = 0; (i < MaxTries) && (result == null); i++) {
|
||||
result = await UrlGetToBytes(request, referer).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
@@ -102,7 +104,7 @@ namespace ArchiSteamFarm {
|
||||
return result;
|
||||
}
|
||||
|
||||
ArchiLogger.LogGenericWarning(string.Format(Strings.ErrorRequestFailedTooManyTimes, MaxRetries));
|
||||
ArchiLogger.LogGenericWarning(string.Format(Strings.ErrorRequestFailedTooManyTimes, MaxTries));
|
||||
ArchiLogger.LogGenericDebug(string.Format(Strings.ErrorFailingRequest, request));
|
||||
return null;
|
||||
}
|
||||
@@ -114,7 +116,7 @@ namespace ArchiSteamFarm {
|
||||
}
|
||||
|
||||
HtmlDocument result = null;
|
||||
for (byte i = 0; (i < MaxRetries) && (result == null); i++) {
|
||||
for (byte i = 0; (i < MaxTries) && (result == null); i++) {
|
||||
result = await UrlGetToHtmlDocument(request, referer).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
@@ -122,7 +124,7 @@ namespace ArchiSteamFarm {
|
||||
return result;
|
||||
}
|
||||
|
||||
ArchiLogger.LogGenericWarning(string.Format(Strings.ErrorRequestFailedTooManyTimes, MaxRetries));
|
||||
ArchiLogger.LogGenericWarning(string.Format(Strings.ErrorRequestFailedTooManyTimes, MaxTries));
|
||||
ArchiLogger.LogGenericDebug(string.Format(Strings.ErrorFailingRequest, request));
|
||||
return null;
|
||||
}
|
||||
@@ -134,7 +136,7 @@ namespace ArchiSteamFarm {
|
||||
}
|
||||
|
||||
JObject result = null;
|
||||
for (byte i = 0; (i < MaxRetries) && (result == null); i++) {
|
||||
for (byte i = 0; (i < MaxTries) && (result == null); i++) {
|
||||
result = await UrlGetToJObject(request, referer).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
@@ -142,7 +144,7 @@ namespace ArchiSteamFarm {
|
||||
return result;
|
||||
}
|
||||
|
||||
ArchiLogger.LogGenericWarning(string.Format(Strings.ErrorRequestFailedTooManyTimes, MaxRetries));
|
||||
ArchiLogger.LogGenericWarning(string.Format(Strings.ErrorRequestFailedTooManyTimes, MaxTries));
|
||||
ArchiLogger.LogGenericDebug(string.Format(Strings.ErrorFailingRequest, request));
|
||||
return null;
|
||||
}
|
||||
@@ -178,7 +180,7 @@ namespace ArchiSteamFarm {
|
||||
}
|
||||
|
||||
XmlDocument result = null;
|
||||
for (byte i = 0; (i < MaxRetries) && (result == null); i++) {
|
||||
for (byte i = 0; (i < MaxTries) && (result == null); i++) {
|
||||
result = await UrlGetToXML(request, referer).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
@@ -186,7 +188,7 @@ namespace ArchiSteamFarm {
|
||||
return result;
|
||||
}
|
||||
|
||||
ArchiLogger.LogGenericWarning(string.Format(Strings.ErrorRequestFailedTooManyTimes, MaxRetries));
|
||||
ArchiLogger.LogGenericWarning(string.Format(Strings.ErrorRequestFailedTooManyTimes, MaxTries));
|
||||
ArchiLogger.LogGenericDebug(string.Format(Strings.ErrorFailingRequest, request));
|
||||
return null;
|
||||
}
|
||||
@@ -198,7 +200,7 @@ namespace ArchiSteamFarm {
|
||||
}
|
||||
|
||||
bool result = false;
|
||||
for (byte i = 0; (i < MaxRetries) && !result; i++) {
|
||||
for (byte i = 0; (i < MaxTries) && !result; i++) {
|
||||
result = await UrlHead(request, referer).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
@@ -206,7 +208,7 @@ namespace ArchiSteamFarm {
|
||||
return true;
|
||||
}
|
||||
|
||||
ArchiLogger.LogGenericWarning(string.Format(Strings.ErrorRequestFailedTooManyTimes, MaxRetries));
|
||||
ArchiLogger.LogGenericWarning(string.Format(Strings.ErrorRequestFailedTooManyTimes, MaxTries));
|
||||
ArchiLogger.LogGenericDebug(string.Format(Strings.ErrorFailingRequest, request));
|
||||
return false;
|
||||
}
|
||||
@@ -218,7 +220,7 @@ namespace ArchiSteamFarm {
|
||||
}
|
||||
|
||||
Uri result = null;
|
||||
for (byte i = 0; (i < MaxRetries) && (result == null); i++) {
|
||||
for (byte i = 0; (i < MaxTries) && (result == null); i++) {
|
||||
result = await UrlHeadToUri(request, referer).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
@@ -226,7 +228,7 @@ namespace ArchiSteamFarm {
|
||||
return result;
|
||||
}
|
||||
|
||||
ArchiLogger.LogGenericWarning(string.Format(Strings.ErrorRequestFailedTooManyTimes, MaxRetries));
|
||||
ArchiLogger.LogGenericWarning(string.Format(Strings.ErrorRequestFailedTooManyTimes, MaxTries));
|
||||
ArchiLogger.LogGenericDebug(string.Format(Strings.ErrorFailingRequest, request));
|
||||
return null;
|
||||
}
|
||||
@@ -249,7 +251,7 @@ namespace ArchiSteamFarm {
|
||||
}
|
||||
|
||||
bool result = false;
|
||||
for (byte i = 0; (i < MaxRetries) && !result; i++) {
|
||||
for (byte i = 0; (i < MaxTries) && !result; i++) {
|
||||
result = await UrlPost(request, data, referer).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
@@ -257,7 +259,7 @@ namespace ArchiSteamFarm {
|
||||
return true;
|
||||
}
|
||||
|
||||
ArchiLogger.LogGenericWarning(string.Format(Strings.ErrorRequestFailedTooManyTimes, MaxRetries));
|
||||
ArchiLogger.LogGenericWarning(string.Format(Strings.ErrorRequestFailedTooManyTimes, MaxTries));
|
||||
ArchiLogger.LogGenericDebug(string.Format(Strings.ErrorFailingRequest, request));
|
||||
return false;
|
||||
}
|
||||
@@ -333,7 +335,7 @@ namespace ArchiSteamFarm {
|
||||
}
|
||||
|
||||
string result = null;
|
||||
for (byte i = 0; (i < MaxRetries) && string.IsNullOrEmpty(result); i++) {
|
||||
for (byte i = 0; (i < MaxTries) && string.IsNullOrEmpty(result); i++) {
|
||||
result = await UrlGetToContent(request, referer).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
@@ -341,7 +343,7 @@ namespace ArchiSteamFarm {
|
||||
return result;
|
||||
}
|
||||
|
||||
ArchiLogger.LogGenericWarning(string.Format(Strings.ErrorRequestFailedTooManyTimes, MaxRetries));
|
||||
ArchiLogger.LogGenericWarning(string.Format(Strings.ErrorRequestFailedTooManyTimes, MaxTries));
|
||||
ArchiLogger.LogGenericDebug(string.Format(Strings.ErrorFailingRequest, request));
|
||||
return null;
|
||||
}
|
||||
@@ -380,12 +382,13 @@ namespace ArchiSteamFarm {
|
||||
}
|
||||
|
||||
private async Task<HttpResponseMessage> UrlGetToResponse(string request, string referer = null) {
|
||||
if (!string.IsNullOrEmpty(request)) {
|
||||
return await UrlRequest(new Uri(request), HttpMethod.Get, null, referer).ConfigureAwait(false);
|
||||
if (string.IsNullOrEmpty(request)) {
|
||||
ArchiLogger.LogNullError(nameof(request));
|
||||
return null;
|
||||
}
|
||||
|
||||
ArchiLogger.LogNullError(nameof(request));
|
||||
return null;
|
||||
HttpResponseMessage result = await UrlRequest(new Uri(request), HttpMethod.Get, null, referer).ConfigureAwait(false);
|
||||
return result;
|
||||
}
|
||||
|
||||
private async Task<XmlDocument> UrlGetToXML(string request, string referer = null) {
|
||||
@@ -464,7 +467,7 @@ namespace ArchiSteamFarm {
|
||||
}
|
||||
|
||||
string result = null;
|
||||
for (byte i = 0; (i < MaxRetries) && string.IsNullOrEmpty(result); i++) {
|
||||
for (byte i = 0; (i < MaxTries) && string.IsNullOrEmpty(result); i++) {
|
||||
result = await UrlPostToContent(request, data, referer).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
@@ -472,7 +475,7 @@ namespace ArchiSteamFarm {
|
||||
return result;
|
||||
}
|
||||
|
||||
ArchiLogger.LogGenericWarning(string.Format(Strings.ErrorRequestFailedTooManyTimes, MaxRetries));
|
||||
ArchiLogger.LogGenericWarning(string.Format(Strings.ErrorRequestFailedTooManyTimes, MaxTries));
|
||||
ArchiLogger.LogGenericDebug(string.Format(Strings.ErrorFailingRequest, request));
|
||||
return null;
|
||||
}
|
||||
@@ -486,7 +489,7 @@ namespace ArchiSteamFarm {
|
||||
return null;
|
||||
}
|
||||
|
||||
private async Task<HttpResponseMessage> UrlRequest(Uri requestUri, HttpMethod httpMethod, ICollection<KeyValuePair<string, string>> data = null, string referer = null, byte maxRedirections = MaxRetries) {
|
||||
private async Task<HttpResponseMessage> UrlRequest(Uri requestUri, HttpMethod httpMethod, ICollection<KeyValuePair<string, string>> data = null, string referer = null, byte maxRedirections = MaxTries) {
|
||||
if ((requestUri == null) || (httpMethod == null)) {
|
||||
ArchiLogger.LogNullError(nameof(requestUri) + " || " + nameof(httpMethod));
|
||||
return null;
|
||||
|
||||
@@ -15,6 +15,10 @@
|
||||
3,
|
||||
5
|
||||
],
|
||||
"MatchableTypes": [
|
||||
3,
|
||||
5
|
||||
],
|
||||
"PasswordFormat": 0,
|
||||
"Paused": false,
|
||||
"RedeemingPreferences": 0,
|
||||
|
||||
@@ -18,7 +18,7 @@ build:
|
||||
project: ArchiSteamFarm.sln
|
||||
parallel: true
|
||||
verbosity: minimal
|
||||
after_build:
|
||||
after_test:
|
||||
- ps: >-
|
||||
$ErrorActionPreference = 'Stop'
|
||||
|
||||
@@ -35,13 +35,13 @@ after_build:
|
||||
|
||||
Add-Content "ArchiSteamFarm\out\$RUNTIME\ArchiSteamFarm.version" "$RUNTIME"
|
||||
|
||||
7z a -bd -tzip -mm=Deflate64 -mx=1 "ArchiSteamFarm\out\ASF-$RUNTIME.zip" "$env:APPVEYOR_BUILD_FOLDER\ArchiSteamFarm\out\$RUNTIME\*"
|
||||
7z a -bd -tzip -mm=Deflate64 -mx=5 "ArchiSteamFarm\out\ASF-$RUNTIME.zip" "$env:APPVEYOR_BUILD_FOLDER\ArchiSteamFarm\out\$RUNTIME\*"
|
||||
Push-AppveyorArtifact "ArchiSteamFarm\out\ASF-$RUNTIME.zip" -FileName "ASF-$RUNTIME.zip" -DeploymentName "ASF-$RUNTIME.zip"
|
||||
}
|
||||
deploy:
|
||||
- provider: GitHub
|
||||
tag: $(appveyor_repo_tag_name)
|
||||
release: ASF V$(appveyor_repo_tag_name)
|
||||
release: ArchiSteamFarm V$(appveyor_repo_tag_name)
|
||||
description: '**NOTICE:** Pre-releases are experimental versions that often contain unpatched bugs, work-in-progress features or rewritten implementations. If you don''t consider yourself advanced user, please download **[latest stable release](https://github.com/JustArchi/ArchiSteamFarm/releases/latest)** instead. Pre-release versions are dedicated to users who know how to report bugs, deal with issues and give feedback - no technical support will be given. Check out ASF **[release cycle](https://github.com/JustArchi/ArchiSteamFarm/wiki/Release-cycle)** if you''d like to learn more.\n\n---\n\nThis is automated AppVeyor GitHub deployment, human-readable changelog should be available soon. In the meantime please refer to **[GitHub commits](https://github.com/JustArchi/ArchiSteamFarm/commits/$(appveyor_repo_tag_name))**.\n\n---\n\nASF is available for free. If you''re grateful for what we''re doing, please consider donating. Developing ASF requires massive amount of time and knowledge, especially when it comes to Steam (and its problems). Even 1$ is highly appreciated and shows that you care!\n\n [](https://www.patreon.com/JustArchi) [](https://www.paypal.me/JustArchi/1usd) [](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=HD2P2P3WGS5Y4) [](https://blockchain.info/payment_request?address=1Archi6M1r5b41Rvn1SY2FfJAzsrEUT7aT) [](https://steamcommunity.com/tradeoffer/new/?partner=46697991&token=0ix2Ruv_)'
|
||||
auth_token:
|
||||
secure: QC5gIDMvSpd43EG6qW8d1E3ZHiVU4aR7pbKQonXstjj/JtAABf5S1IbtoY4OsnOR
|
||||
|
||||
@@ -15,9 +15,9 @@ This tool is being used by ASF developers for synchronization of strings/transla
|
||||
|
||||
## Before you begin
|
||||
|
||||
- Make sure that your ```crowdin_identity.yaml``` file exists - this is the file with login credentials that is not being committed to GitHub. If it doesn't exist yet (e.g. because you've just cloned the repo), create it from ```crowdin_identity_example.yaml``` and fill ```api_key``` that can be found **[here](http://l10n.asf.justarchi.net/project/archisteamfarm/settings#api)**.
|
||||
- Make sure that your `crowdin_identity.yaml` file exists - this is the file with login credentials that is not being committed to GitHub. If it doesn't exist yet (e.g. because you've just cloned the repo), create it from `crowdin_identity_example.yaml` and fill `api_key` that can be found **[here](http://l10n.asf.justarchi.net/project/archisteamfarm/settings#api)**.
|
||||
|
||||
- Ensure that ```crowdin``` command is recognized by your OS.
|
||||
- Ensure that `crowdin` command is recognized by your OS.
|
||||
|
||||
---
|
||||
|
||||
@@ -25,14 +25,16 @@ This tool is being used by ASF developers for synchronization of strings/transla
|
||||
|
||||
- Install **[Java JDK](http://www.oracle.com/technetwork/java/javase/downloads/index.html)**.
|
||||
- **[Set JAVA_HOME properly](https://confluence.atlassian.com/doc/setting-the-java_home-variable-in-windows-8895.html)**.
|
||||
- Launch ```setup_crowdin.bat``` as administrator.
|
||||
- Open new ```cmd``` prompt and verify that ```crowdin help``` indeed works.
|
||||
- Launch `setup_crowdin.bat` as administrator.
|
||||
- Open new `cmd` prompt and verify that `crowdin help` indeed works.
|
||||
|
||||
---
|
||||
|
||||
## Usage
|
||||
|
||||
- ```archi_download.bat``` for downloading translations from Crowdin (typically last commit before release).
|
||||
- `archi_upload.bat` for pushing strings to Crowdin (when any `*Strings.resx` file gets modified).
|
||||
|
||||
- ```archi_upload.bat``` for pushing strings to Crowdin (when any ```*Strings.resx``` file gets modified).
|
||||
- `archi_download.bat` for downloading translations from Crowdin (typically last commit before release).
|
||||
|
||||
- `archi_sync.bat` for upload + download (tree sync).
|
||||
|
||||
|
||||
5
tools/crowdin-cli/archi_sync.bat
Normal file
5
tools/crowdin-cli/archi_sync.bat
Normal file
@@ -0,0 +1,5 @@
|
||||
@echo off
|
||||
cd ..\\..
|
||||
call crowdin -b master --identity tools\\crowdin-cli\\crowdin_identity.yaml upload sources
|
||||
call crowdin -b master --identity tools\\crowdin-cli\\crowdin_identity.yaml download
|
||||
pause
|
||||
Reference in New Issue
Block a user