mirror of
https://github.com/JustArchiNET/ArchiSteamFarm.git
synced 2025-12-24 18:26:49 +00:00
Compare commits
48 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5b66b70566 | ||
|
|
41c06851a5 | ||
|
|
4dbb964ba9 | ||
|
|
11471c759d | ||
|
|
2aa4ab7fe8 | ||
|
|
dfc055c066 | ||
|
|
1a0ac11f46 | ||
|
|
7266864b3b | ||
|
|
b52f746138 | ||
|
|
a2585ec8c9 | ||
|
|
37781698e0 | ||
|
|
2a8fe7611b | ||
|
|
8fdf14bb10 | ||
|
|
31db72b2d6 | ||
|
|
f28ae15cc9 | ||
|
|
6fcc64dad1 | ||
|
|
e18046084e | ||
|
|
c3c5f33289 | ||
|
|
e03734ef8f | ||
|
|
a7c2ca6bc5 | ||
|
|
171fca42f2 | ||
|
|
e90ac74b16 | ||
|
|
a5ce8bf3d7 | ||
|
|
aad77569a7 | ||
|
|
e74b3e4f78 | ||
|
|
7db44c5835 | ||
|
|
25a88f941d | ||
|
|
2eab00facc | ||
|
|
98e51a4543 | ||
|
|
2ee49db81d | ||
|
|
aab397dd2d | ||
|
|
7426fafcb0 | ||
|
|
270bd7ae26 | ||
|
|
4c3713c19f | ||
|
|
5791b1e552 | ||
|
|
5c59236a09 | ||
|
|
a7119bba89 | ||
|
|
3b64e14489 | ||
|
|
5f36ca91d7 | ||
|
|
5a2cd25fa1 | ||
|
|
20a5d509a7 | ||
|
|
0c457e7f3e | ||
|
|
4e6014d652 | ||
|
|
1436fb6d6a | ||
|
|
e2578c7960 | ||
|
|
8fb1a2e1ea | ||
|
|
3e2951d1d0 | ||
|
|
1dcb103bf7 |
2
.github/workflows/docker-ci.yml
vendored
2
.github/workflows/docker-ci.yml
vendored
@@ -25,7 +25,7 @@ jobs:
|
||||
uses: docker/setup-buildx-action@v1.6.0
|
||||
|
||||
- name: Build ${{ matrix.configuration }} Docker image from ${{ matrix.file }}
|
||||
uses: docker/build-push-action@v2.8.0
|
||||
uses: docker/build-push-action@v2.9.0
|
||||
with:
|
||||
context: .
|
||||
file: ${{ matrix.file }}
|
||||
|
||||
2
.github/workflows/docker-publish-latest.yml
vendored
2
.github/workflows/docker-publish-latest.yml
vendored
@@ -55,7 +55,7 @@ jobs:
|
||||
echo "DH_REPOSITORY=$(echo ${{ secrets.DOCKERHUB_USERNAME }}/${{ github.event.repository.name }} | tr '[:upper:]' '[:lower:]')" >> "$GITHUB_ENV"
|
||||
|
||||
- name: Build and publish Docker image from Dockerfile.Service
|
||||
uses: docker/build-push-action@v2.8.0
|
||||
uses: docker/build-push-action@v2.9.0
|
||||
with:
|
||||
context: .
|
||||
file: Dockerfile.Service
|
||||
|
||||
2
.github/workflows/docker-publish-main.yml
vendored
2
.github/workflows/docker-publish-main.yml
vendored
@@ -55,7 +55,7 @@ jobs:
|
||||
echo "DH_REPOSITORY=$(echo ${{ secrets.DOCKERHUB_USERNAME }}/${{ github.event.repository.name }} | tr '[:upper:]' '[:lower:]')" >> "$GITHUB_ENV"
|
||||
|
||||
- name: Build and publish Docker image from Dockerfile
|
||||
uses: docker/build-push-action@v2.8.0
|
||||
uses: docker/build-push-action@v2.9.0
|
||||
with:
|
||||
context: .
|
||||
platforms: ${{ env.PLATFORMS }}
|
||||
|
||||
@@ -56,7 +56,7 @@ jobs:
|
||||
echo "DH_REPOSITORY=$(echo ${{ secrets.DOCKERHUB_USERNAME }}/${{ github.event.repository.name }} | tr '[:upper:]' '[:lower:]')" >> "$GITHUB_ENV"
|
||||
|
||||
- name: Build and publish Docker image from Dockerfile
|
||||
uses: docker/build-push-action@v2.8.0
|
||||
uses: docker/build-push-action@v2.9.0
|
||||
with:
|
||||
context: .
|
||||
platforms: ${{ env.PLATFORMS }}
|
||||
|
||||
2
ASF-ui
2
ASF-ui
Submodule ASF-ui updated: 156992e88d...533e6082fb
@@ -171,6 +171,10 @@
|
||||
<data name="LoadingGlobalCache" xml:space="preserve">
|
||||
<value>Globaler STD-Cache wird geladen...</value>
|
||||
</data>
|
||||
|
||||
|
||||
<data name="ValidatingGlobalCacheIntegrity" xml:space="preserve">
|
||||
<value>Überprüfe STD globale Cache-Integrität...</value>
|
||||
</data>
|
||||
<data name="GlobalCacheIntegrityValidationFailed" xml:space="preserve">
|
||||
<value>Fehler beim Überprüfen der globalen STD-Cache-Integrität. Dies deutet auf eine mögliche Datei-/Speicher-Beschädigung hin; stattdessen wird eine neue Instanz initialisiert.</value>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -62,23 +62,72 @@
|
||||
PublicKeyToken=b77a5c561934e089
|
||||
</value>
|
||||
</resheader>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<data name="PluginDisabledMissingBuildToken" xml:space="preserve">
|
||||
<value>由於 {0} 缺少組建令牌而被停用</value>
|
||||
<comment>{0} will be replaced by the name of the plugin (e.g. "SteamTokenDumperPlugin")</comment>
|
||||
</data>
|
||||
<data name="PluginDisabledInConfig" xml:space="preserve">
|
||||
<value>目前 {0} 已根據您的設定被停用。如果您想幫助 SteamDB 提交資料,請查看我們的 Wiki。</value>
|
||||
<comment>{0} will be replaced by the name of the plugin (e.g. "SteamTokenDumperPlugin")</comment>
|
||||
</data>
|
||||
<data name="PluginInitializedAndEnabled" xml:space="preserve">
|
||||
<value>已成功初始化 {0},預先感謝您的幫助。第一次提交將大約在 {1} 後進行。</value>
|
||||
<comment>{0} will be replaced by the name of the plugin (e.g. "SteamTokenDumperPlugin"), {1} will be replaced by translated TimeSpan string (such as "53 minutes")</comment>
|
||||
</data>
|
||||
<data name="FileCouldNotBeLoadedFreshInit" xml:space="preserve">
|
||||
<value>無法載入 {0},將初始化一個新實例…</value>
|
||||
<comment>{0} will be replaced by the name of the file (e.g. "GlobalCache")</comment>
|
||||
</data>
|
||||
<data name="BotNoAppsToRefresh" xml:space="preserve">
|
||||
<value>此 Bot 實例中沒有需要再新的應用程式。</value>
|
||||
</data>
|
||||
<data name="BotRetrievingTotalAppAccessTokens" xml:space="preserve">
|
||||
<value>正在檢索共 {0} 個應用程式存取令牌…</value>
|
||||
<comment>{0} will be replaced by the number (total count) of app access tokens being retrieved</comment>
|
||||
</data>
|
||||
<data name="BotRetrievingAppAccessTokens" xml:space="preserve">
|
||||
<value>正在檢索 {0} 個應用程式存取令牌…</value>
|
||||
<comment>{0} will be replaced by the number (count this batch) of app access tokens being retrieved</comment>
|
||||
</data>
|
||||
<data name="BotFinishedRetrievingAppAccessTokens" xml:space="preserve">
|
||||
<value>已完成檢索 {0} 個應用程式存取令牌。</value>
|
||||
<comment>{0} will be replaced by the number (count this batch) of app access tokens retrieved</comment>
|
||||
</data>
|
||||
<data name="BotFinishedRetrievingTotalAppAccessTokens" xml:space="preserve">
|
||||
<value>已完成檢索共 {0} 個應用程式存取令牌。</value>
|
||||
<comment>{0} will be replaced by the number (total count) of app access tokens retrieved</comment>
|
||||
</data>
|
||||
<data name="BotRetrievingTotalDepots" xml:space="preserve">
|
||||
<value>正在檢索共 {0} 個應用程式的所有資料段儲存目錄…</value>
|
||||
<comment>{0} will be replaced by the number (total count) of apps being retrieved</comment>
|
||||
</data>
|
||||
<data name="BotRetrievingAppInfos" xml:space="preserve">
|
||||
<value>正在檢索 {0} 個應用程式資料…</value>
|
||||
<comment>{0} will be replaced by the number (count this batch) of app infos being retrieved</comment>
|
||||
</data>
|
||||
<data name="BotFinishedRetrievingAppInfos" xml:space="preserve">
|
||||
<value>已完成檢索 {0} 個應用程式資料。</value>
|
||||
<comment>{0} will be replaced by the number (count this batch) of app infos retrieved</comment>
|
||||
</data>
|
||||
<data name="BotRetrievingDepotKeys" xml:space="preserve">
|
||||
<value>正在檢索 {0} 個應用程式的所有資料段儲存目錄…</value>
|
||||
<comment>{0} will be replaced by the number (count this batch) of depot keys being retrieved</comment>
|
||||
</data>
|
||||
<data name="BotFinishedRetrievingDepotKeys" xml:space="preserve">
|
||||
<value>已完成檢索 {0} 個應用程式的所有資料段儲存目錄。</value>
|
||||
<comment>{0} will be replaced by the number (count this batch) of depot keys retrieved</comment>
|
||||
</data>
|
||||
<data name="BotFinishedRetrievingTotalDepots" xml:space="preserve">
|
||||
<value>已完成檢索共 {0} 個應用程式的所有資料段儲存目錄。</value>
|
||||
<comment>{0} will be replaced by the number (total count) of apps retrieved</comment>
|
||||
</data>
|
||||
<data name="SubmissionNoNewData" xml:space="preserve">
|
||||
<value>沒有要提交的新資料,一切都是最新的。</value>
|
||||
</data>
|
||||
<data name="SubmissionNoContributorSet" xml:space="preserve">
|
||||
<value>無法提交資料,因為沒有可以讓我們歸類為貢獻者的有效 SteamID 集。 考慮設定 {0} 屬性。</value>
|
||||
<comment>{0} will be replaced by the name of the config property (e.g. "SteamOwnerID") that the user is expected to set</comment>
|
||||
</data>
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -41,7 +41,7 @@ using ArchiSteamFarm.Web;
|
||||
|
||||
namespace ArchiSteamFarm.Core;
|
||||
|
||||
internal sealed class Statistics : IAsyncDisposable {
|
||||
internal sealed class RemoteCommunication : IAsyncDisposable {
|
||||
private const ushort MaxItemsForFairBots = ArchiWebHandler.MaxItemsInSingleInventoryRequest * WebBrowser.MaxTries; // Determines which fair bots we'll deprioritize when matching due to excessive number of inventory requests they need to make, which are likely to fail in the process or cause excessive delays
|
||||
private const byte MaxMatchedBotsHard = 40; // Determines how many bots we can attempt to match in total, where match attempt is equal to analyzing bot's inventory
|
||||
private const byte MaxMatchingRounds = 10; // Determines maximum amount of matching rounds we're going to consider before leaving the rest of work for the next batch
|
||||
@@ -61,7 +61,7 @@ internal sealed class Statistics : IAsyncDisposable {
|
||||
private readonly SemaphoreSlim MatchActivelySemaphore = new(1, 1);
|
||||
|
||||
#pragma warning disable CA2213 // False positive, .NET Framework can't understand DisposeAsync()
|
||||
private readonly Timer MatchActivelyTimer;
|
||||
private readonly Timer? MatchActivelyTimer;
|
||||
#pragma warning restore CA2213 // False positive, .NET Framework can't understand DisposeAsync()
|
||||
|
||||
private readonly SemaphoreSlim RequestsSemaphore = new(1, 1);
|
||||
@@ -71,25 +71,33 @@ internal sealed class Statistics : IAsyncDisposable {
|
||||
private DateTime LastPersonaStateRequest;
|
||||
private bool ShouldSendHeartBeats;
|
||||
|
||||
internal Statistics(Bot bot) {
|
||||
internal RemoteCommunication(Bot bot) {
|
||||
Bot = bot ?? throw new ArgumentNullException(nameof(bot));
|
||||
|
||||
MatchActivelyTimer = new Timer(
|
||||
MatchActively,
|
||||
null,
|
||||
TimeSpan.FromHours(1) + TimeSpan.FromSeconds(ASF.LoadBalancingDelay * Bot.Bots?.Count ?? 0), // Delay
|
||||
TimeSpan.FromHours(8) // Period
|
||||
);
|
||||
if (Bot.BotConfig.TradingPreferences.HasFlag(BotConfig.ETradingPreferences.MatchActively)) {
|
||||
MatchActivelyTimer = new Timer(
|
||||
MatchActively,
|
||||
null,
|
||||
TimeSpan.FromHours(1) + TimeSpan.FromSeconds(ASF.LoadBalancingDelay * Bot.Bots?.Count ?? 0), // Delay
|
||||
TimeSpan.FromHours(8) // Period
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
public async ValueTask DisposeAsync() {
|
||||
MatchActivelySemaphore.Dispose();
|
||||
RequestsSemaphore.Dispose();
|
||||
|
||||
await MatchActivelyTimer.DisposeAsync().ConfigureAwait(false);
|
||||
if (MatchActivelyTimer != null) {
|
||||
await MatchActivelyTimer.DisposeAsync().ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
||||
internal async Task OnHeartBeat() {
|
||||
if (!Bot.BotConfig.RemoteCommunication.HasFlag(BotConfig.ERemoteCommunication.PublicListing)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Request persona update if needed
|
||||
if ((DateTime.UtcNow > LastPersonaStateRequest.AddHours(MinPersonaStateTTL)) && (DateTime.UtcNow > LastAnnouncementCheck.AddHours(MinAnnouncementCheckTTL))) {
|
||||
LastPersonaStateRequest = DateTime.UtcNow;
|
||||
@@ -125,12 +133,20 @@ internal sealed class Statistics : IAsyncDisposable {
|
||||
}
|
||||
|
||||
internal async Task OnLoggedOn() {
|
||||
if (!Bot.BotConfig.RemoteCommunication.HasFlag(BotConfig.ERemoteCommunication.SteamGroup)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!await Bot.ArchiWebHandler.JoinGroup(SharedInfo.ASFGroupSteamID).ConfigureAwait(false)) {
|
||||
Bot.ArchiLogger.LogGenericWarning(string.Format(CultureInfo.CurrentCulture, Strings.WarningFailedWithError, nameof(ArchiWebHandler.JoinGroup)));
|
||||
}
|
||||
}
|
||||
|
||||
internal async Task OnPersonaState(string? nickname = null, string? avatarHash = null) {
|
||||
if (!Bot.BotConfig.RemoteCommunication.HasFlag(BotConfig.ERemoteCommunication.PublicListing)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ((DateTime.UtcNow < LastAnnouncementCheck.AddHours(MinAnnouncementCheckTTL)) && (ShouldSendHeartBeats || (LastHeartBeat == DateTime.MinValue))) {
|
||||
return;
|
||||
}
|
||||
@@ -229,12 +245,20 @@ internal sealed class Statistics : IAsyncDisposable {
|
||||
}
|
||||
|
||||
private async Task<bool?> IsEligibleForListing() {
|
||||
// Bot must be eligible for matching first
|
||||
bool? isEligibleForMatching = await IsEligibleForMatching().ConfigureAwait(false);
|
||||
|
||||
if (isEligibleForMatching != true) {
|
||||
return isEligibleForMatching;
|
||||
}
|
||||
|
||||
// Bot must have STM enabled in TradingPreferences
|
||||
if (!Bot.BotConfig.TradingPreferences.HasFlag(BotConfig.ETradingPreferences.SteamTradeMatcher)) {
|
||||
Bot.ArchiLogger.LogGenericTrace(string.Format(CultureInfo.CurrentCulture, Strings.WarningFailedWithError, $"{nameof(Bot.BotConfig.TradingPreferences)}: {Bot.BotConfig.TradingPreferences}"));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Bot must have public inventory
|
||||
bool? hasPublicInventory = await Bot.HasPublicInventory().ConfigureAwait(false);
|
||||
|
||||
@@ -255,13 +279,6 @@ internal sealed class Statistics : IAsyncDisposable {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Bot must have STM enable in TradingPreferences
|
||||
if (!Bot.BotConfig.TradingPreferences.HasFlag(BotConfig.ETradingPreferences.SteamTradeMatcher)) {
|
||||
Bot.ArchiLogger.LogGenericTrace(string.Format(CultureInfo.CurrentCulture, Strings.WarningFailedWithError, $"{nameof(Bot.BotConfig.TradingPreferences)}: {Bot.BotConfig.TradingPreferences}"));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Bot must have at least one accepted matchable type set
|
||||
if ((Bot.BotConfig.MatchableTypes.Count == 0) || Bot.BotConfig.MatchableTypes.All(static type => !AcceptedMatchableTypes.Contains(type))) {
|
||||
Bot.ArchiLogger.LogGenericTrace(string.Format(CultureInfo.CurrentCulture, Strings.WarningFailedWithError, $"{nameof(Bot.BotConfig.MatchableTypes)}: {string.Join(", ", Bot.BotConfig.MatchableTypes)}"));
|
||||
@@ -195,7 +195,7 @@ StackTrace:
|
||||
<comment>Please note that this translation should end with space</comment>
|
||||
</data>
|
||||
<data name="UserInputSteamGuard" xml:space="preserve">
|
||||
<value>Bitte gebe den SteamGuard Authentifizierungstoken ein, der an deine E-Mail Adresse geschickt wurde: </value>
|
||||
<value>Bitte gebe den SteamGuard Authentifizierungstoken ein, der an Ihre E-Mail Adresse geschickt wurde: </value>
|
||||
<comment>Please note that this translation should end with space</comment>
|
||||
</data>
|
||||
<data name="UserInputSteamLogin" xml:space="preserve">
|
||||
@@ -445,10 +445,10 @@ StackTrace:
|
||||
<value>Bot stellt eine Verbindung zum Steam-Netzwerk her.</value>
|
||||
</data>
|
||||
<data name="BotStatusNotRunning" xml:space="preserve">
|
||||
<value>Bot läuft nicht.</value>
|
||||
<value>Bot ist nicht in Betrieb.</value>
|
||||
</data>
|
||||
<data name="BotStatusPaused" xml:space="preserve">
|
||||
<value>Bot ist pausiert oder läuft im manuellen Modus.</value>
|
||||
<value>Bot ist pausiert oder wird im manuellen Modus ausgeführt.</value>
|
||||
</data>
|
||||
<data name="BotStatusPlayingNotAvailable" xml:space="preserve">
|
||||
<value>Bot wird zurzeit benutzt.</value>
|
||||
@@ -476,7 +476,7 @@ StackTrace:
|
||||
<value>Benutzerkonto ist nicht mehr in Verwendung: Sammelprozess fortgesetzt!</value>
|
||||
</data>
|
||||
<data name="BotAccountOccupied" xml:space="preserve">
|
||||
<value>Benutzerkonto ist in Verwendung: ASF wird den Sammelprozess fortsetzen, wenn es wieder möglich ist...</value>
|
||||
<value>Benutzerkonto ist in Verwendung: ASF wird den Sammelprozess fortsetzen, sobald diese wieder verfügbar ist...</value>
|
||||
</data>
|
||||
<data name="BotConnecting" xml:space="preserve">
|
||||
<value>Verbinde...</value>
|
||||
@@ -506,7 +506,7 @@ StackTrace:
|
||||
<value>Bitte lesen Sie den Abschnitt zu unseren Datenschutzrichtlinien im Wiki, wenn Sie wissen möchten was ASF im Detail alles macht!</value>
|
||||
</data>
|
||||
<data name="Welcome" xml:space="preserve">
|
||||
<value>Es sieht so aus, als ob Sie das Programm zum ersten Mal gestartet haben, willkommen!</value>
|
||||
<value>Es sieht so aus, als ob Sie das Programm zum ersten Mal gestartet haben. Willkommen!</value>
|
||||
</data>
|
||||
<data name="ErrorInvalidCurrentCulture" xml:space="preserve">
|
||||
<value>Ihre angegebene CurrentCulture ist ungültig, ASF wird weiterhin mit dem Standard laufen!</value>
|
||||
|
||||
@@ -222,20 +222,34 @@ StackTrace: {2}</value>
|
||||
</data>
|
||||
|
||||
|
||||
|
||||
<data name="BotStatusIdlingList" xml:space="preserve">
|
||||
<value>A bot a {0} játékot farmolja. Összesen {1} játék ({2} kártya) maradt hátra (kb. {3} mire végez).</value>
|
||||
<comment>{0} will be replaced by list of the games (IDs, numbers), {1} will be replaced by total number of games to farm, {2} will be replaced by total number of cards to farm, {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>A kitűzők első oldalának ellenőrzése...</value>
|
||||
</data>
|
||||
<data name="CheckingOtherBadgePages" xml:space="preserve">
|
||||
<value>A többi kitűző oldal ellenőrzése...</value>
|
||||
</data>
|
||||
|
||||
<data name="ChosenFarmingAlgorithm" xml:space="preserve">
|
||||
<value>A kiválasztott farmoló algoritmus: {0}</value>
|
||||
<comment>{0} will be replaced by the name of chosen farming algorithm</comment>
|
||||
</data>
|
||||
<data name="Done" xml:space="preserve">
|
||||
<value>Kész!</value>
|
||||
</data>
|
||||
|
||||
|
||||
|
||||
<data name="GamesToIdle" xml:space="preserve">
|
||||
<value>Még összesen {0} játék ({1} kártya) maradt (kb. {2} míg végez)...</value>
|
||||
<comment>{0} will be replaced by number of games, {1} will be replaced by number of cards, {2} will be replaced by translated TimeSpan string (such as "1 day, 5 hours and 30 minutes")</comment>
|
||||
</data>
|
||||
<data name="IdlingFinished" xml:space="preserve">
|
||||
<value>Farmolás befejezve!</value>
|
||||
</data>
|
||||
<data name="IdlingFinishedForGame" xml:space="preserve">
|
||||
<value>Farmolás befejezve: {0} ({1}) készen van {2} játékidő után!</value>
|
||||
<comment>{0} will be replaced by game's ID (number), {1} will be replaced by game's name, {2} will be replaced by translated TimeSpan string (such as "1 day, 5 hours and 30 minutes")</comment>
|
||||
</data>
|
||||
|
||||
<data name="IdlingStatusForGame" xml:space="preserve">
|
||||
<value>Farmolás állapota a következő a játékhoz: {0} ({1}): {2} kártya maradt</value>
|
||||
|
||||
@@ -105,7 +105,7 @@ StackTrace:
|
||||
<comment>{0} will be replaced by object's name</comment>
|
||||
</data>
|
||||
<data name="ErrorNoBotsDefined" xml:space="preserve">
|
||||
<value>Nenhum bot foi definido. Você esqueceu de configurar seu Archi Steam Farm? Siga o guia de "configuração" no wiki se você estiver com dúvidas.</value>
|
||||
<value>Nenhum bot foi definido. Você esqueceu de configurar seu ASF? Confira o guia de "configuração" no wiki se você estiver confuso.</value>
|
||||
</data>
|
||||
<data name="ErrorObjectIsNull" xml:space="preserve">
|
||||
<value>{0} é nulo!</value>
|
||||
@@ -194,7 +194,10 @@ StackTrace:
|
||||
<value>Insira o código gerado pelo autenticador móvel do Steam: </value>
|
||||
<comment>Please note that this translation should end with space</comment>
|
||||
</data>
|
||||
|
||||
<data name="UserInputSteamGuard" xml:space="preserve">
|
||||
<value>Por favor digite o código do Steam Guard que foi enviado para o seu e-mail: </value>
|
||||
<comment>Please note that this translation should end with space</comment>
|
||||
</data>
|
||||
<data name="UserInputSteamLogin" xml:space="preserve">
|
||||
<value>Insira o seu nome de usuário Steam: </value>
|
||||
<comment>Please note that this translation should end with space</comment>
|
||||
@@ -705,7 +708,7 @@ Tempo de execução: {1}</value>
|
||||
<comment>{0} will be replaced by the number of bytes (characters) recommended</comment>
|
||||
</data>
|
||||
<data name="WarningDefaultCryptKeyUsedForHashing" xml:space="preserve">
|
||||
<value>Você está utilizando {0} configuração de {1}, mas você não forneceu uma senha de criptografia personalizada. Você deve fornecer uma senha de criptografia para melhorar sua segurança.</value>
|
||||
<value>Você está usando a configuração {0} de propriedade {1}, mas você não forneceu uma --cryptkey personalizada. Você deve fornecer uma --cryptkey personalizada para maior segurança.</value>
|
||||
<comment>{0} will be replaced by the name of a particular setting (e.g. "SCrypt"), {1} will be replaced by the name of the property (e.g. "IPCPassword")</comment>
|
||||
</data>
|
||||
<data name="WarningDefaultCryptKeyUsedForEncryption" xml:space="preserve">
|
||||
@@ -713,24 +716,24 @@ Tempo de execução: {1}</value>
|
||||
<comment>{0} will be replaced by the name of a particular setting (e.g. "AES"), {1} will be replaced by the name of the property (e.g. "SteamPassword")</comment>
|
||||
</data>
|
||||
<data name="WarningRunningAsRoot" xml:space="preserve">
|
||||
<value>Você está utilizando o Archi Steam Farm como administrador (Root). Isto não é necessário, e poderá trazer riscos a sua máquina. É recomendado rodar em modo usuário se possível.</value>
|
||||
<value>Você está tentando executar o ASF como administrador (root). Isto causa um risco de segurança significativo à sua máquina e já que o ASF não requer acesso root para o seu funcionamento, recomendamos executá-lo como usuário não-administrador, se possível.</value>
|
||||
</data>
|
||||
<data name="WarningRunningInUnsupportedEnvironment" xml:space="preserve">
|
||||
<value>Você está executando o Archi Steam Farm em um ambiente não suportado, utilizando o argumento --ignore-unported-environment. Por favor, note que não oferecemos qualquer tipo de apoio a este cenário, e você está fazendo isso inteiramente por sua conta e risco! Você foi avisado.</value>
|
||||
<value>Você está executando o ASF em um ambiente não suportado, utilizando o argumento --ignore-unported-environment. Por favor, note que não oferecemos qualquer tipo de apoio a este cenário, e você está fazendo isso inteiramente por sua conta e risco! Você foi avisado.</value>
|
||||
</data>
|
||||
<data name="FetchingChecksumFromRemoteServer" xml:space="preserve">
|
||||
<value>Obtendo checksum do servidor remoto...</value>
|
||||
</data>
|
||||
<data name="VerifyingChecksumWithRemoteServer" xml:space="preserve">
|
||||
<value>Comparando a checksum do binário baixado junto ao servidor remoto...</value>
|
||||
<value>Comparando a checksum do binário baixado com a do servidor remoto...</value>
|
||||
</data>
|
||||
<data name="ChecksumMissing" xml:space="preserve">
|
||||
<value>O servidor remoto não reconhece a versão para a qual estamos atualizando. Esta situação pode ser possível se a versão foi publicada recentemente, recusando-se a prosseguir imediatamente com o processo de atualização, como uma medida de segurança adicional.</value>
|
||||
<value>O servidor remoto não sabe nada sobre a versão para a qual estamos atualizando. Esta situação é possível se a atualização foi publicada recentemente - recusando-se a prosseguir com o processo de atualização imediatamente como uma medida de segurança adicional.</value>
|
||||
</data>
|
||||
<data name="ChecksumWrong" xml:space="preserve">
|
||||
<value>O servidor remoto retornou com uma chave de verificação diferente. Isto pode indicar que o download corrompeu, ou um ataque MITM, não será possível prosseguir com a atualização!</value>
|
||||
<value>O servidor remoto respondeu com um checksum diferente, isto pode indicar download corrompido ou um ataque MITM, recusando-se a prosseguir com o procedimento de atualização!</value>
|
||||
</data>
|
||||
<data name="PatchingFiles" xml:space="preserve">
|
||||
<value>Extraindo arquivos do Archi Steam Farm...</value>
|
||||
<value>Atualizando arquivos do ASF...</value>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -104,7 +104,7 @@
|
||||
<comment>{0} will be replaced by object's name</comment>
|
||||
</data>
|
||||
<data name="ErrorNoBotsDefined" xml:space="preserve">
|
||||
<value>沒有設定任何機器人,您是否忘記設定 ASF 了?如果您不明白發生了什麼,請閱讀 Wiki 上的「安裝指南」。</value>
|
||||
<value>沒有設定任何 Bot。你是否忘記設定 ASF 了?如果你不明白發生了什麼,請閱讀 Wiki 上的「設定指南」。</value>
|
||||
</data>
|
||||
<data name="ErrorObjectIsNull" xml:space="preserve">
|
||||
<value>{0} 為空值!</value>
|
||||
@@ -128,7 +128,7 @@
|
||||
<value>無法進行更新,因為此版本沒有提供任何資產!</value>
|
||||
</data>
|
||||
<data name="ErrorUserInputRunningInHeadlessMode" xml:space="preserve">
|
||||
<value>收到一個使用者輸入請求,但行程目前正以無介面模式執行!</value>
|
||||
<value>收到一個使用者輸入請求,但進程目前正以無介面模式執行!</value>
|
||||
</data>
|
||||
<data name="Exiting" xml:space="preserve">
|
||||
<value>正在退出...</value>
|
||||
@@ -147,11 +147,11 @@
|
||||
<comment>{0} will be replaced by trade number</comment>
|
||||
</data>
|
||||
<data name="LoggingIn" xml:space="preserve">
|
||||
<value>正在登錄到 {0}...</value>
|
||||
<value>正在登入到 {0}…</value>
|
||||
<comment>{0} will be replaced by service's name</comment>
|
||||
</data>
|
||||
<data name="NoBotsAreRunning" xml:space="preserve">
|
||||
<value>沒有執行中的 Bot,正在退出……</value>
|
||||
<value>沒有執行中的 Bot,正在退出…</value>
|
||||
</data>
|
||||
<data name="RefreshingOurSession" xml:space="preserve">
|
||||
<value>更新工作階段 !</value>
|
||||
@@ -161,22 +161,22 @@
|
||||
<comment>{0} will be replaced by trade number</comment>
|
||||
</data>
|
||||
<data name="Restarting" xml:space="preserve">
|
||||
<value>正在重新啟動...</value>
|
||||
<value>正在重新啟動…</value>
|
||||
</data>
|
||||
<data name="Starting" xml:space="preserve">
|
||||
<value>正在啟動...</value>
|
||||
<value>正在啟動…</value>
|
||||
</data>
|
||||
<data name="Success" xml:space="preserve">
|
||||
<value>成功!</value>
|
||||
</data>
|
||||
<data name="UnlockingParentalAccount" xml:space="preserve">
|
||||
<value>正在解鎖家庭監護帳戶...</value>
|
||||
<value>正在解鎖家庭監護帳號…</value>
|
||||
</data>
|
||||
<data name="UpdateCheckingNewVersion" xml:space="preserve">
|
||||
<value>正在檢查新版本...</value>
|
||||
<value>正在檢查新版本…</value>
|
||||
</data>
|
||||
<data name="UpdateDownloadingNewVersion" xml:space="preserve">
|
||||
<value>正在下載新版本:{0}({1} MB)……等待期間,如果喜歡這個軟體,請考慮捐助 ASF!:)</value>
|
||||
<value>正在下載新版本:{0} ({1} MB)…等待期間,如果喜歡這個軟體,請考慮捐助 ASF!:)</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">
|
||||
@@ -193,9 +193,12 @@
|
||||
<value>請輸入你的 Steam Guard 行動驗證器上的兩步驟驗證代碼: </value>
|
||||
<comment>Please note that this translation should end with space</comment>
|
||||
</data>
|
||||
|
||||
<data name="UserInputSteamGuard" xml:space="preserve">
|
||||
<value>請輸入寄送至你的電子信箱的 Steam Guard 驗證代碼: </value>
|
||||
<comment>Please note that this translation should end with space</comment>
|
||||
</data>
|
||||
<data name="UserInputSteamLogin" xml:space="preserve">
|
||||
<value>請輸入你的 Steam 帳戶:</value>
|
||||
<value>請輸入你的 Steam 帳號: </value>
|
||||
<comment>Please note that this translation should end with space</comment>
|
||||
</data>
|
||||
<data name="UserInputSteamParentalCode" xml:space="preserve">
|
||||
@@ -214,7 +217,7 @@
|
||||
<value>IPC 伺服器已就緒!</value>
|
||||
</data>
|
||||
<data name="IPCStarting" xml:space="preserve">
|
||||
<value>IPC 伺服器啟動中……</value>
|
||||
<value>正在啟動 IPC 伺服器…</value>
|
||||
</data>
|
||||
<data name="BotAlreadyStopped" xml:space="preserve">
|
||||
<value>這個 Bot 已經停止了!</value>
|
||||
@@ -224,7 +227,7 @@
|
||||
<comment>{0} will be replaced by bot's name query (string)</comment>
|
||||
</data>
|
||||
<data name="BotStatusOverview" xml:space="preserve">
|
||||
<value>有 {0}/{1} 個 Bot 正在運行,總共有 {2} 個遊戲 ({3} 張卡片) 等待掛卡。</value>
|
||||
<value>有 {0}/{1} 個 Bot 正在執行,總共有 {2} 個遊戲 ({3} 張卡片) 等待掛卡。</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 farm, {3} will be replaced by total number of cards left to farm</comment>
|
||||
</data>
|
||||
<data name="BotStatusIdling" xml:space="preserve">
|
||||
@@ -236,10 +239,10 @@
|
||||
<comment>{0} will be replaced by list of the games (IDs, numbers), {1} will be replaced by total number of games to farm, {2} will be replaced by total number of cards to farm, {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>正在檢查徽章頁面第一頁...</value>
|
||||
<value>正在檢查徽章頁面第一頁…</value>
|
||||
</data>
|
||||
<data name="CheckingOtherBadgePages" xml:space="preserve">
|
||||
<value>正在檢查其他徽章頁面...</value>
|
||||
<value>正在檢查其他徽章頁面…</value>
|
||||
</data>
|
||||
<data name="ChosenFarmingAlgorithm" xml:space="preserve">
|
||||
<value>選擇的掛卡演算法為:{0}</value>
|
||||
@@ -249,7 +252,7 @@
|
||||
<value>完成!</value>
|
||||
</data>
|
||||
<data name="GamesToIdle" xml:space="preserve">
|
||||
<value>總共有 {0} 個遊戲 (總數 {1} 張卡片) 需要掛卡 (仍需約 {2})...</value>
|
||||
<value>總共有 {0} 個遊戲 ({1} 張卡片) 需要掛卡 (仍需約 {2})…</value>
|
||||
<comment>{0} will be replaced by number of games, {1} will be replaced by number of cards, {2} will be replaced by translated TimeSpan string (such as "1 day, 5 hours and 30 minutes")</comment>
|
||||
</data>
|
||||
<data name="IdlingFinished" xml:space="preserve">
|
||||
@@ -274,33 +277,33 @@
|
||||
<value>正在忽略此請求,因為強制暫停已啟用!</value>
|
||||
</data>
|
||||
<data name="NothingToIdle" xml:space="preserve">
|
||||
<value>本帳戶目前沒有需要掛卡的遊戲!</value>
|
||||
<value>本帳號目前沒有需要掛卡的遊戲!</value>
|
||||
</data>
|
||||
<data name="NowIdling" xml:space="preserve">
|
||||
<value>正在掛卡: {0} ({1})</value>
|
||||
<value>正在掛卡:{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="NowIdlingList" xml:space="preserve">
|
||||
<value>正在掛卡: {0}</value>
|
||||
<value>正在掛卡:{0}</value>
|
||||
<comment>{0} will be replaced by list of the games (IDs, numbers), separated by a comma</comment>
|
||||
</data>
|
||||
<data name="PlayingNotAvailable" xml:space="preserve">
|
||||
<value>目前無法執行,我們將稍後再試!</value>
|
||||
</data>
|
||||
<data name="StillIdling" xml:space="preserve">
|
||||
<value>仍在掛卡: {0} ({1})</value>
|
||||
<value>仍在掛卡:{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="StillIdlingList" xml:space="preserve">
|
||||
<value>仍在掛卡: {0}</value>
|
||||
<value>仍在掛卡:{0}</value>
|
||||
<comment>{0} will be replaced by list of the games (IDs, numbers), separated by a comma</comment>
|
||||
</data>
|
||||
<data name="StoppedIdling" xml:space="preserve">
|
||||
<value>停止掛卡: {0} ({1})</value>
|
||||
<value>停止掛卡:{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="StoppedIdlingList" xml:space="preserve">
|
||||
<value>停止掛卡: {0}</value>
|
||||
<value>停止掛卡:{0}</value>
|
||||
<comment>{0} will be replaced by list of the games (IDs, numbers), separated by a comma</comment>
|
||||
</data>
|
||||
<data name="UnknownCommand" xml:space="preserve">
|
||||
@@ -314,11 +317,11 @@
|
||||
<comment>{0} will be replaced by game's ID (number), {1} will be replaced by game's name</comment>
|
||||
</data>
|
||||
<data name="BotAcceptingGift" xml:space="preserve">
|
||||
<value>接受禮物:{0}……</value>
|
||||
<value>接受禮物:{0}…</value>
|
||||
<comment>{0} will be replaced by giftID (number)</comment>
|
||||
</data>
|
||||
<data name="BotAccountLimited" xml:space="preserve">
|
||||
<value>本帳戶為受限帳戶,在限制解除前將無法掛卡!</value>
|
||||
<value>本帳號為受限帳號,在限制解除前將無法掛卡!</value>
|
||||
</data>
|
||||
<data name="BotAddLicense" xml:space="preserve">
|
||||
<value>ID:{0} | 狀態:{1}</value>
|
||||
@@ -332,7 +335,7 @@
|
||||
<value>Bot 已在執行中!</value>
|
||||
</data>
|
||||
<data name="BotAuthenticatorConverting" xml:space="preserve">
|
||||
<value>正在將 .maFile 轉換成 ASF 的檔案格式……</value>
|
||||
<value>正在將 .maFile 轉換成 ASF 的檔案格式…</value>
|
||||
</data>
|
||||
<data name="BotAuthenticatorImportFinished" xml:space="preserve">
|
||||
<value>已成功匯入行動驗證器!</value>
|
||||
@@ -360,7 +363,7 @@
|
||||
<value>已與 Steam 中斷連線!</value>
|
||||
</data>
|
||||
<data name="BotDisconnecting" xml:space="preserve">
|
||||
<value>正在中斷連線...</value>
|
||||
<value>正在中斷連線…</value>
|
||||
</data>
|
||||
<data name="BotInstanceNotStartingBecauseDisabled" xml:space="preserve">
|
||||
<value>這個 Bot 將不會啟動,因為它在設定檔中被停用!</value>
|
||||
@@ -378,16 +381,16 @@
|
||||
<comment>{0} will be replaced by steam ID (number)</comment>
|
||||
</data>
|
||||
<data name="BotLoggingIn" xml:space="preserve">
|
||||
<value>登入中...</value>
|
||||
<value>正在登入…</value>
|
||||
</data>
|
||||
<data name="BotLogonSessionReplaced" xml:space="preserve">
|
||||
<value>這個帳戶似乎正被另一個 ASF 使用中,這是未定義的行為,拒絕讓它繼續執行!</value>
|
||||
<value>這個帳號似乎正被另一個 ASF 使用中,這是未定義的行為,拒絕讓它繼續執行!</value>
|
||||
</data>
|
||||
<data name="BotLootingFailed" xml:space="preserve">
|
||||
<value>交易提案已失敗!</value>
|
||||
</data>
|
||||
<data name="BotLootingMasterNotDefined" xml:space="preserve">
|
||||
<value>無法發送交易提案,因為沒有帳戶設有 master 權限!</value>
|
||||
<value>無法發送交易提案,因為沒有帳號設有 master 權限!</value>
|
||||
</data>
|
||||
<data name="BotLootingSuccess" xml:space="preserve">
|
||||
<value>交易提案發送成功!</value>
|
||||
@@ -414,11 +417,11 @@
|
||||
<comment>{0} will be replaced by the points balance value (integer)</comment>
|
||||
</data>
|
||||
<data name="BotRateLimitExceeded" xml:space="preserve">
|
||||
<value>超過頻率限制,我們將在 {0} 後重試……</value>
|
||||
<value>超過頻率限制,我們將在 {0} 後重試…</value>
|
||||
<comment>{0} will be replaced by translated TimeSpan string (such as "25 minutes")</comment>
|
||||
</data>
|
||||
<data name="BotReconnecting" xml:space="preserve">
|
||||
<value>正在重新連線...</value>
|
||||
<value>正在重新連線…</value>
|
||||
</data>
|
||||
<data name="BotRedeem" xml:space="preserve">
|
||||
<value>序號:{0} | 狀態:{1}</value>
|
||||
@@ -469,13 +472,13 @@
|
||||
<value>與 Steam 網路的連線中斷,正在重新連線……</value>
|
||||
</data>
|
||||
<data name="BotAccountFree" xml:space="preserve">
|
||||
<value>帳戶不再被佔用,已恢復掛卡!</value>
|
||||
<value>帳號不再被佔用,已恢復掛卡!</value>
|
||||
</data>
|
||||
<data name="BotAccountOccupied" xml:space="preserve">
|
||||
<value>帳號目前使用中,ASF 將在該帳號空閒時繼續掛卡……</value>
|
||||
<value>帳號目前使用中,ASF 將在該帳號空閒時繼續掛卡…</value>
|
||||
</data>
|
||||
<data name="BotConnecting" xml:space="preserve">
|
||||
<value>正在連線...</value>
|
||||
<value>正在連線…</value>
|
||||
</data>
|
||||
<data name="BotHeartBeatFailed" xml:space="preserve">
|
||||
<value>無法與用戶端中斷連線,正在中止此 Bot!</value>
|
||||
@@ -484,7 +487,7 @@
|
||||
<value>無法初始化 SteamDirectory,與 Steam 網路的連線可能需要更長的時間!</value>
|
||||
</data>
|
||||
<data name="BotStopping" xml:space="preserve">
|
||||
<value>正在停止...</value>
|
||||
<value>正在停止…</value>
|
||||
</data>
|
||||
<data name="ErrorBotConfigInvalid" xml:space="preserve">
|
||||
<value>你的 Bot 設定無效,請確認 {0} 的內容然後再試一次!</value>
|
||||
@@ -495,7 +498,7 @@
|
||||
<comment>{0} will be replaced by file's path</comment>
|
||||
</data>
|
||||
<data name="Initializing" xml:space="preserve">
|
||||
<value>正在初始化 {0}...</value>
|
||||
<value>正在初始化 {0}…</value>
|
||||
<comment>{0} will be replaced by service name that is being initialized</comment>
|
||||
</data>
|
||||
<data name="WarningPrivacyPolicy" xml:space="preserve">
|
||||
@@ -524,7 +527,7 @@
|
||||
<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>此帳戶已被封鎖,永久無法掛卡!</value>
|
||||
<value>此帳號已被封鎖,永久無法掛卡!</value>
|
||||
</data>
|
||||
<data name="BotStatusLocked" xml:space="preserve">
|
||||
<value>Bot 已被封鎖,無法透過掛卡得到卡片。</value>
|
||||
@@ -548,7 +551,7 @@
|
||||
<comment>{0} will be replaced by number (in megabytes) of memory being used, {1} will be replaced by translated TimeSpan string (such as "25 minutes"). Please note that this string should include newlines for formatting.</comment>
|
||||
</data>
|
||||
<data name="ClearingDiscoveryQueue" xml:space="preserve">
|
||||
<value>正在瀏覽 Steam 探索佇列 #{0}……</value>
|
||||
<value>正在瀏覽 Steam 探索佇列 #{0}…</value>
|
||||
<comment>{0} will be replaced by queue number</comment>
|
||||
</data>
|
||||
<data name="DoneClearingDiscoveryQueue" xml:space="preserve">
|
||||
@@ -556,11 +559,11 @@
|
||||
<comment>{0} will be replaced by queue number</comment>
|
||||
</data>
|
||||
<data name="BotOwnsOverviewPerGame" xml:space="preserve">
|
||||
<value>{0}/{1} 個 Bot 已經擁有遊戲 {2}。</value>
|
||||
<value>{0}/{1} 個 Bot 已擁有遊戲 {2}。</value>
|
||||
<comment>{0} will be replaced by number of bots that already own particular game being checked, {1} will be replaced by total number of bots that were checked during the process, {2} will be replaced by game's ID (number)</comment>
|
||||
</data>
|
||||
<data name="BotRefreshingPackagesData" xml:space="preserve">
|
||||
<value>更新套件資料中……</value>
|
||||
<value>更新套件資料中…</value>
|
||||
</data>
|
||||
<data name="WarningDeprecated" xml:space="preserve">
|
||||
<value>{0} 的用法已棄用,並且將在未來的版本中移除,請改用 {1}。</value>
|
||||
@@ -589,7 +592,7 @@
|
||||
<comment>{0} will be replaced by bot's level</comment>
|
||||
</data>
|
||||
<data name="ActivelyMatchingItems" xml:space="preserve">
|
||||
<value>正在比對 Steam 物品,第 #{0} 輪……</value>
|
||||
<value>正在比對 Steam 物品,第 #{0} 輪…</value>
|
||||
<comment>{0} will be replaced by round number</comment>
|
||||
</data>
|
||||
<data name="DoneActivelyMatchingItems" xml:space="preserve">
|
||||
@@ -604,7 +607,7 @@
|
||||
<comment>{0} will be replaced by number of sets traded</comment>
|
||||
</data>
|
||||
<data name="WarningExcessiveBotsCount" xml:space="preserve">
|
||||
<value>你執行的個人 Bot 帳戶數量超過我們的建議上限 ({0})。請留意,此設定不受支援,且可能會導致各種 Steam 相關問題,包括帳戶停權。請參閱常見問答了解詳情。</value>
|
||||
<value>你執行的個人 Bot 帳號數量超過我們的建議上限 ({0})。請留意,此設定不受支援,且可能會導致各種 Steam 相關問題,包括帳號停權。請參閱常見問答了解詳情。</value>
|
||||
<comment>{0} will be replaced by our maximum recommended bots count (number)</comment>
|
||||
</data>
|
||||
<data name="PluginLoaded" xml:space="preserve">
|
||||
@@ -612,7 +615,7 @@
|
||||
<comment>{0} will be replaced by the name of the custom ASF plugin</comment>
|
||||
</data>
|
||||
<data name="PluginLoading" xml:space="preserve">
|
||||
<value>正在載入 {0} V{1}……</value>
|
||||
<value>正在載入 {0} V{1}…</value>
|
||||
<comment>{0} will be replaced by the name of the custom ASF plugin, {1} will be replaced by its version</comment>
|
||||
</data>
|
||||
<data name="NothingFound" xml:space="preserve">
|
||||
@@ -622,13 +625,13 @@
|
||||
<value>你已載入一個以上的自訂外掛程式。由於我們無法支援修改過的配置,如遭遇任何問題,請向相關外掛程式的開發人員尋求協助。</value>
|
||||
</data>
|
||||
<data name="PleaseWait" xml:space="preserve">
|
||||
<value>請稍候⋯⋯</value>
|
||||
<value>請稍候…</value>
|
||||
</data>
|
||||
<data name="EnterCommand" xml:space="preserve">
|
||||
<value>輸入指令:</value>
|
||||
</data>
|
||||
<data name="Executing" xml:space="preserve">
|
||||
<value>執行中……</value>
|
||||
<value>正在執行…</value>
|
||||
</data>
|
||||
<data name="InteractiveConsoleEnabled" xml:space="preserve">
|
||||
<value>已開啟互動式主控台,按「C」進入指令模式</value>
|
||||
@@ -645,14 +648,14 @@
|
||||
<comment>{0} will be replaced by number of confirmations</comment>
|
||||
</data>
|
||||
<data name="BotExtraIdlingCooldown" xml:space="preserve">
|
||||
<value>最多等待 {0} 以確保我們可以開始掛卡……</value>
|
||||
<value>最多等待 {0} 以確保我們可以開始掛卡…</value>
|
||||
<comment>{0} will be replaced by translated TimeSpan string (such as "1 minute")</comment>
|
||||
</data>
|
||||
<data name="UpdateCleanup" xml:space="preserve">
|
||||
<value>正在清理更新後的過時檔案……</value>
|
||||
<value>正在清理更新後的過時檔案…</value>
|
||||
</data>
|
||||
<data name="BotGeneratingSteamParentalCode" xml:space="preserve">
|
||||
<value>正在產生 Steam 家庭監護代碼,這會需要一段時間,請考慮將它寫入設定檔中……</value>
|
||||
<value>正在產生 Steam 家庭監護代碼,這會需要一段時間,請考慮將它寫入設定檔中…</value>
|
||||
</data>
|
||||
<data name="IPCConfigChanged" xml:space="preserve">
|
||||
<value>IPC 設定檔已變更!</value>
|
||||
@@ -662,7 +665,7 @@
|
||||
<comment>{0} will be replaced by trade offer ID (number), {1} will be replaced by internal ASF enum name, {2} will be replaced by technical reason why the trade was determined to be in this state</comment>
|
||||
</data>
|
||||
<data name="BotInvalidPasswordDuringLogin" xml:space="preserve">
|
||||
<value>連續收到 InvalidPassword 錯誤代碼 {0} 次。您的帳戶密碼大概是錯的,中止!</value>
|
||||
<value>連續收到 InvalidPassword 錯誤代碼 {0} 次。您的帳號密碼大概是錯的,中止!</value>
|
||||
<comment>{0} will be replaced by maximum allowed number of failed login attempts</comment>
|
||||
</data>
|
||||
<data name="Result" xml:space="preserve">
|
||||
@@ -684,40 +687,52 @@
|
||||
<comment>{0} will be replaced by internal name of the config property (e.g. "GamesPlayedWhileIdle"), {1} will be replaced by comma-separated list of appIDs that user has chosen</comment>
|
||||
</data>
|
||||
<data name="AutomaticFileMigration" xml:space="preserve">
|
||||
<value>{0} 設定檔將會改版成最新的語法……</value>
|
||||
<value>{0} 設定檔將會改版成最新的語法…</value>
|
||||
<comment>{0} will be replaced with the relative path to the affected config file</comment>
|
||||
</data>
|
||||
<data name="WarningWeakIPCPassword" xml:space="preserve">
|
||||
<value>你的IPC密碼看起來很弱 你可以考慮更換一個安全性更高的密碼 細節:{0}</value>
|
||||
<value>你的 IPC 密碼看起來很弱。請考慮換一個強度更高的密碼來增加安全性。詳細資訊: {0}</value>
|
||||
<comment>{0} will be replaced by additional details about the password being considered weak</comment>
|
||||
</data>
|
||||
<data name="WarningWeakSteamPassword" xml:space="preserve">
|
||||
<value>你的steam 密碼 {0} 看起來很弱 你可以考慮換一個 細節: {1}</value>
|
||||
<value>你的 Steam 密碼「{0}」看起來很弱。請考慮換一個強度更高的密碼來增加安全性。詳細資訊: {1}</value>
|
||||
<comment>{0} will be replaced by either the affected bot name or the path to the bots configuration file, {1} will be replaced by additional details about the password being considered weak</comment>
|
||||
</data>
|
||||
<data name="WarningWeakCryptKey" xml:space="preserve">
|
||||
<value>你的加密密鑰看起來很弱 可以考慮換一個 細節:{0}</value>
|
||||
<value>你的加密金鑰看起來很弱。請考慮換一個強度更高的金鑰來增加安全性。詳細資訊: {0}</value>
|
||||
<comment>{0} will be replaced by additional details about the encryption key being considered weak</comment>
|
||||
</data>
|
||||
<data name="WarningTooShortCryptKey" xml:space="preserve">
|
||||
<value>你的加密密鑰太短 我們推薦使用{0} 以上長度的密鑰</value>
|
||||
<value>你的加密金鑰太短。我們推薦使用 {0} 位元組 (字元) 以上長度的金鑰。</value>
|
||||
<comment>{0} will be replaced by the number of bytes (characters) recommended</comment>
|
||||
</data>
|
||||
<data name="WarningDefaultCryptKeyUsedForHashing" xml:space="preserve">
|
||||
<value>你正在使用 {0} 設置 {1} 屬性 但你沒有提供一個自定義的加密密鑰 你應該提供一個自定義的加密密鑰以提高安全性</value>
|
||||
<value>你正在使用 {0} 設定 {1} 屬性。但你沒有提供一個自定義的 --cryptkey。你應該提供自定義 --cryptkey 以提高安全性。</value>
|
||||
<comment>{0} will be replaced by the name of a particular setting (e.g. "SCrypt"), {1} will be replaced by the name of the property (e.g. "IPCPassword")</comment>
|
||||
</data>
|
||||
<data name="WarningDefaultCryptKeyUsedForEncryption" xml:space="preserve">
|
||||
<value>你正在使用 {0} 設置 {1} 屬性 但你沒有提供一個自定義的加密密鑰 這很不安全 你應該提供一個自定義的加密密鑰</value>
|
||||
<value>你正在使用 {0} 設定 {1} 屬性。但你沒有提供一個自定義的 --cryptkey。這完全破壞了保護,因為 ASF 被迫使用自己的 (已知) 金鑰。你應該提供自定義 --cryptkey 用於使用此設定提供的安全優勢。</value>
|
||||
<comment>{0} will be replaced by the name of a particular setting (e.g. "AES"), {1} will be replaced by the name of the property (e.g. "SteamPassword")</comment>
|
||||
</data>
|
||||
|
||||
<data name="WarningRunningInUnsupportedEnvironment" xml:space="preserve">
|
||||
<value>你在不支援的環境下提供了 --ignore-unsupported-environment 參數 請注意 我們不為這種情況提供任何支持 風險請完全由你自行承擔 我們已經警告過你了</value>
|
||||
<data name="WarningRunningAsRoot" xml:space="preserve">
|
||||
<value>你正在以管理員權限 (Root) 執行 ASF。這會給你的機器帶來重大的安全風險,且由於 ASF 的操作不需要 Root 權限,我們建議盡可能以非管理員使用者身份執行它。</value>
|
||||
</data>
|
||||
<data name="WarningRunningInUnsupportedEnvironment" xml:space="preserve">
|
||||
<value>您在不受支援的環境中執行 ASF,並提供 --ignore-unsupported-environment 引數。請注意,我們不對這種情況提供任何形式的支援,您完全需要自行承擔風險。你已經被警告過了。</value>
|
||||
</data>
|
||||
<data name="FetchingChecksumFromRemoteServer" xml:space="preserve">
|
||||
<value>正在從遠端伺服器擷取核對和…</value>
|
||||
</data>
|
||||
<data name="VerifyingChecksumWithRemoteServer" xml:space="preserve">
|
||||
<value>正在驗證已下載的二進制檔案與來自遠端伺服器的核對和…</value>
|
||||
</data>
|
||||
<data name="ChecksumMissing" xml:space="preserve">
|
||||
<value>遠端伺服器對我們要更新到的版本一無所知。如果該版本是最近發布的,則可能出現這種情況——立刻拒絕進行更新程序作為額外的安全措施。</value>
|
||||
</data>
|
||||
<data name="ChecksumWrong" xml:space="preserve">
|
||||
<value>遠端伺服器回覆了不同的核對和,這可能意味著下載檔案損毀或遭受中間人攻擊,拒絕繼續更新程序!</value>
|
||||
</data>
|
||||
<data name="PatchingFiles" xml:space="preserve">
|
||||
<value>正在修補 ASF 檔案…</value>
|
||||
</data>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</root>
|
||||
|
||||
@@ -1,42 +0,0 @@
|
||||
// _ _ _ ____ _ _____
|
||||
// / \ _ __ ___ | |__ (_)/ ___| | |_ ___ __ _ _ __ ___ | ___|__ _ _ __ _ __ ___
|
||||
// / _ \ | '__|/ __|| '_ \ | |\___ \ | __|/ _ \ / _` || '_ ` _ \ | |_ / _` || '__|| '_ ` _ \
|
||||
// / ___ \ | | | (__ | | | || | ___) || |_| __/| (_| || | | | | || _|| (_| || | | | | | | |
|
||||
// /_/ \_\|_| \___||_| |_||_||____/ \__|\___| \__,_||_| |_| |_||_| \__,_||_| |_| |_| |_|
|
||||
// |
|
||||
// Copyright 2015-2022 Ł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.Threading.Tasks;
|
||||
using ArchiSteamFarm.Steam;
|
||||
using ArchiSteamFarm.Storage;
|
||||
using JetBrains.Annotations;
|
||||
|
||||
namespace ArchiSteamFarm.Plugins.Interfaces;
|
||||
|
||||
[PublicAPI]
|
||||
[Obsolete($"Use {nameof(IBotCommand2)} instead, this one will be removed soon.", true)]
|
||||
public interface IBotCommand : IPlugin {
|
||||
/// <summary>
|
||||
/// ASF will call this method for unrecognized commands.
|
||||
/// </summary>
|
||||
/// <param name="bot">Bot object related to this callback.</param>
|
||||
/// <param name="steamID">64-bit long unsigned integer of steamID executing the command.</param>
|
||||
/// <param name="message">Command message in its raw format, stripped of <see cref="GlobalConfig.CommandPrefix" />.</param>
|
||||
/// <param name="args">Pre-parsed message using standard ASF delimiters.</param>
|
||||
/// <returns>Response to the command, or null/empty (as the task value) if the command isn't handled by this plugin.</returns>
|
||||
Task<string?> OnBotCommand(Bot bot, ulong steamID, string message, string[] args);
|
||||
}
|
||||
@@ -40,7 +40,6 @@ using ArchiSteamFarm.Steam;
|
||||
using ArchiSteamFarm.Steam.Data;
|
||||
using ArchiSteamFarm.Steam.Exchange;
|
||||
using ArchiSteamFarm.Steam.Integration.Callbacks;
|
||||
using ArchiSteamFarm.Storage;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using SteamKit2;
|
||||
|
||||
@@ -297,30 +296,6 @@ internal static class PluginsCore {
|
||||
return null;
|
||||
}
|
||||
|
||||
ulong oldSteamID = steamID;
|
||||
|
||||
if (oldSteamID == 0) {
|
||||
oldSteamID = ASF.GlobalConfig?.SteamOwnerID ?? GlobalConfig.DefaultSteamOwnerID;
|
||||
}
|
||||
|
||||
if ((oldSteamID != 0) && new SteamID(oldSteamID).IsIndividualAccount) {
|
||||
IList<string?> oldResponses;
|
||||
|
||||
try {
|
||||
#pragma warning disable CS0618 // We intentionally support deprecated interface for a while longer
|
||||
oldResponses = await Utilities.InParallel(ActivePlugins.OfType<IBotCommand>().Select(plugin => plugin.OnBotCommand(bot, oldSteamID, message, args))).ConfigureAwait(false);
|
||||
#pragma warning restore CS0618 // We intentionally support deprecated interface for a while longer
|
||||
} catch (Exception e) {
|
||||
ASF.ArchiLogger.LogGenericException(e);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
foreach (string? oldResponse in oldResponses) {
|
||||
responses.Add(oldResponse);
|
||||
}
|
||||
}
|
||||
|
||||
return string.Join(Environment.NewLine, responses.Where(static response => !string.IsNullOrEmpty(response)));
|
||||
}
|
||||
|
||||
|
||||
@@ -154,7 +154,6 @@ public sealed class Bot : IAsyncDisposable {
|
||||
private readonly SemaphoreSlim MessagingSemaphore = new(1, 1);
|
||||
private readonly ConcurrentDictionary<UserNotificationsCallback.EUserNotification, uint> PastNotifications = new();
|
||||
private readonly SemaphoreSlim SendCompleteTypesSemaphore = new(1, 1);
|
||||
private readonly Statistics? Statistics;
|
||||
private readonly SteamClient SteamClient;
|
||||
private readonly ConcurrentHashSet<ulong> SteamFamilySharingIDs = new();
|
||||
private readonly SteamUser SteamUser;
|
||||
@@ -250,6 +249,7 @@ public sealed class Bot : IAsyncDisposable {
|
||||
#pragma warning restore CA2213 // False positive, .NET Framework can't understand DisposeAsync()
|
||||
|
||||
private bool ReconnectOnUserInitiated;
|
||||
private RemoteCommunication? RemoteCommunication;
|
||||
private bool SendCompleteTypesScheduled;
|
||||
|
||||
#pragma warning disable CA2213 // False positive, .NET Framework can't understand DisposeAsync()
|
||||
@@ -339,10 +339,6 @@ public sealed class Bot : IAsyncDisposable {
|
||||
Commands = new Commands(this);
|
||||
Trading = new Trading(this);
|
||||
|
||||
if (!Debugging.IsDebugBuild && (ASF.GlobalConfig?.Statistics ?? GlobalConfig.DefaultStatistics)) {
|
||||
Statistics = new Statistics(this);
|
||||
}
|
||||
|
||||
HeartBeatTimer = new Timer(
|
||||
HeartBeat,
|
||||
null,
|
||||
@@ -383,8 +379,8 @@ public sealed class Bot : IAsyncDisposable {
|
||||
await SendItemsTimer.DisposeAsync().ConfigureAwait(false);
|
||||
}
|
||||
|
||||
if (Statistics != null) {
|
||||
await Statistics.DisposeAsync().ConfigureAwait(false);
|
||||
if (RemoteCommunication != null) {
|
||||
await RemoteCommunication.DisposeAsync().ConfigureAwait(false);
|
||||
}
|
||||
|
||||
if (SteamSaleEvent != null) {
|
||||
@@ -757,27 +753,6 @@ public sealed class Bot : IAsyncDisposable {
|
||||
return await ArchiWebHandler.GetTradeHoldDurationForTrade(tradeID).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
[PublicAPI]
|
||||
[Obsolete($"Use {nameof(GetAccess)} instead (if you still need it), this one will be removed soon.", true)]
|
||||
public bool HasAccess(ulong steamID, BotConfig.EAccess access) {
|
||||
if ((steamID == 0) || !new SteamID(steamID).IsIndividualAccount) {
|
||||
throw new ArgumentOutOfRangeException(nameof(steamID));
|
||||
}
|
||||
|
||||
if ((access == BotConfig.EAccess.None) || !Enum.IsDefined(access)) {
|
||||
throw new InvalidEnumArgumentException(nameof(access), (int) access, typeof(BotConfig.EAccess));
|
||||
}
|
||||
|
||||
if (ASF.IsOwner(steamID)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return access switch {
|
||||
BotConfig.EAccess.FamilySharing when SteamFamilySharingIDs.Contains(steamID) => true,
|
||||
_ => BotConfig.SteamUserPermissions.TryGetValue(steamID, out BotConfig.EAccess realPermission) && (realPermission >= access)
|
||||
};
|
||||
}
|
||||
|
||||
[PublicAPI]
|
||||
public async Task<Dictionary<uint, byte>?> LoadCardsPerSet(IReadOnlyCollection<uint> appIDs) {
|
||||
if ((appIDs == null) || (appIDs.Count == 0)) {
|
||||
@@ -1962,8 +1937,8 @@ public sealed class Bot : IAsyncDisposable {
|
||||
|
||||
HeartBeatFailures = 0;
|
||||
|
||||
if (Statistics != null) {
|
||||
Utilities.InBackground(Statistics.OnHeartBeat);
|
||||
if (RemoteCommunication != null) {
|
||||
Utilities.InBackground(RemoteCommunication.OnHeartBeat);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
ArchiLogger.LogGenericDebuggingException(e);
|
||||
@@ -2112,6 +2087,16 @@ public sealed class Bot : IAsyncDisposable {
|
||||
SteamSaleEvent = new SteamSaleEvent(this);
|
||||
}
|
||||
|
||||
if (RemoteCommunication != null) {
|
||||
await RemoteCommunication.DisposeAsync().ConfigureAwait(false);
|
||||
|
||||
RemoteCommunication = null;
|
||||
}
|
||||
|
||||
if (!Debugging.IsDebugBuild && (BotConfig.RemoteCommunication > BotConfig.ERemoteCommunication.None)) {
|
||||
RemoteCommunication = new RemoteCommunication(this);
|
||||
}
|
||||
|
||||
await PluginsCore.OnBotInitModules(this, BotConfig.AdditionalProperties).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
@@ -2866,8 +2851,8 @@ public sealed class Bot : IAsyncDisposable {
|
||||
|
||||
Utilities.InBackground(InitializeFamilySharing);
|
||||
|
||||
if (Statistics != null) {
|
||||
Utilities.InBackground(Statistics.OnLoggedOn);
|
||||
if (RemoteCommunication != null) {
|
||||
Utilities.InBackground(RemoteCommunication.OnLoggedOn);
|
||||
}
|
||||
|
||||
if (BotConfig.OnlineStatus != EPersonaState.Offline) {
|
||||
@@ -3042,8 +3027,8 @@ public sealed class Bot : IAsyncDisposable {
|
||||
AvatarHash = avatarHash;
|
||||
Nickname = callback.Name;
|
||||
|
||||
if (Statistics != null) {
|
||||
Utilities.InBackground(() => Statistics.OnPersonaState(callback.Name, avatarHash));
|
||||
if (RemoteCommunication != null) {
|
||||
Utilities.InBackground(() => RemoteCommunication.OnPersonaState(callback.Name, avatarHash));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3288,7 +3273,7 @@ public sealed class Bot : IAsyncDisposable {
|
||||
}
|
||||
|
||||
private async Task ResetGamesPlayed() {
|
||||
if (CardsFarmer.NowFarming) {
|
||||
if (!IsConnectedAndLoggedOn || CardsFarmer.NowFarming) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -3300,10 +3285,24 @@ public sealed class Bot : IAsyncDisposable {
|
||||
// This function might be executed before PlayingSessionStateCallback/SharedLibraryLockStatusCallback, ensure proper delay in this case
|
||||
await Task.Delay(2000).ConfigureAwait(false);
|
||||
|
||||
if (CardsFarmer.NowFarming || !IsPlayingPossible) {
|
||||
if (!IsConnectedAndLoggedOn || CardsFarmer.NowFarming || !IsPlayingPossible) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (PlayingWasBlocked) {
|
||||
byte minFarmingDelayAfterBlock = ASF.GlobalConfig?.MinFarmingDelayAfterBlock ?? GlobalConfig.DefaultMinFarmingDelayAfterBlock;
|
||||
|
||||
if (minFarmingDelayAfterBlock > 0) {
|
||||
for (byte i = 0; (i < minFarmingDelayAfterBlock) && IsConnectedAndLoggedOn && !CardsFarmer.NowFarming && IsPlayingPossible && PlayingWasBlocked; i++) {
|
||||
await Task.Delay(1000).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
if (!IsConnectedAndLoggedOn || CardsFarmer.NowFarming || !IsPlayingPossible) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ArchiLogger.LogGenericInfo(string.Format(CultureInfo.CurrentCulture, Strings.BotIdlingSelectedGames, nameof(BotConfig.GamesPlayedWhileIdle), string.Join(", ", BotConfig.GamesPlayedWhileIdle)));
|
||||
}
|
||||
|
||||
|
||||
@@ -81,18 +81,6 @@ public sealed class Commands {
|
||||
return $"<{SharedInfo.ASF}> {response}";
|
||||
}
|
||||
|
||||
[PublicAPI]
|
||||
[Obsolete($"Use overload which accepts {nameof(EAccess)} instead, this one will be removed soon.", true)]
|
||||
public async Task<string?> Response(ulong steamID, string message) {
|
||||
if ((steamID == 0) || !new SteamID(steamID).IsIndividualAccount) {
|
||||
throw new ArgumentOutOfRangeException(nameof(steamID));
|
||||
}
|
||||
|
||||
EAccess access = Bot.GetAccess(steamID);
|
||||
|
||||
return await Response(access, message, steamID).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
[PublicAPI]
|
||||
public async Task<string?> Response(EAccess access, string message, ulong steamID = 0) {
|
||||
if (!Enum.IsDefined(access)) {
|
||||
|
||||
@@ -35,6 +35,7 @@ using ArchiSteamFarm.IPC.Integration;
|
||||
using ArchiSteamFarm.Localization;
|
||||
using ArchiSteamFarm.Steam.Data;
|
||||
using ArchiSteamFarm.Steam.Integration;
|
||||
using ArchiSteamFarm.Storage;
|
||||
using JetBrains.Annotations;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
@@ -80,6 +81,9 @@ public sealed class BotConfig {
|
||||
[PublicAPI]
|
||||
public const ERedeemingPreferences DefaultRedeemingPreferences = ERedeemingPreferences.None;
|
||||
|
||||
[PublicAPI]
|
||||
public const ERemoteCommunication DefaultRemoteCommunication = ERemoteCommunication.All;
|
||||
|
||||
[PublicAPI]
|
||||
public const bool DefaultSendOnFarmingFinished = false;
|
||||
|
||||
@@ -195,6 +199,9 @@ public sealed class BotConfig {
|
||||
[JsonProperty(Required = Required.DisallowNull)]
|
||||
public ERedeemingPreferences RedeemingPreferences { get; private set; } = DefaultRedeemingPreferences;
|
||||
|
||||
[JsonProperty(Required = Required.DisallowNull)]
|
||||
public ERemoteCommunication RemoteCommunication { get; private set; } = DefaultRemoteCommunication;
|
||||
|
||||
[JsonProperty(Required = Required.DisallowNull)]
|
||||
public bool SendOnFarmingFinished { get; private set; } = DefaultSendOnFarmingFinished;
|
||||
|
||||
@@ -351,6 +358,9 @@ public sealed class BotConfig {
|
||||
[UsedImplicitly]
|
||||
public bool ShouldSerializeRedeemingPreferences() => !Saving || (RedeemingPreferences != DefaultRedeemingPreferences);
|
||||
|
||||
[UsedImplicitly]
|
||||
public bool ShouldSerializeRemoteCommunication() => !Saving || (RemoteCommunication != DefaultRemoteCommunication);
|
||||
|
||||
[UsedImplicitly]
|
||||
public bool ShouldSerializeSendOnFarmingFinished() => !Saving || (SendOnFarmingFinished != DefaultSendOnFarmingFinished);
|
||||
|
||||
@@ -594,7 +604,18 @@ public sealed class BotConfig {
|
||||
break;
|
||||
}
|
||||
|
||||
// TODO: Pending removal, Statistics -> RemoteCommunication migration
|
||||
if ((ASF.GlobalConfig?.Statistics == false) && (botConfig.RemoteCommunication == DefaultRemoteCommunication)) {
|
||||
botConfig.RemoteCommunication = ERemoteCommunication.None;
|
||||
}
|
||||
|
||||
if (!Program.ConfigMigrate) {
|
||||
// TODO: Pending removal, warning for people that disabled config migrate, they need to migrate themselves
|
||||
if (ASF.GlobalConfig?.Statistics == false) {
|
||||
ASF.ArchiLogger.LogGenericWarning(string.Format(CultureInfo.CurrentCulture, Strings.WarningFailedWithError, nameof(Program.ConfigMigrate)));
|
||||
ASF.ArchiLogger.LogGenericWarning(string.Format(CultureInfo.CurrentCulture, Strings.WarningDeprecated, nameof(GlobalConfig.Statistics), nameof(RemoteCommunication)));
|
||||
}
|
||||
|
||||
return (botConfig, null);
|
||||
}
|
||||
|
||||
@@ -662,6 +683,14 @@ public sealed class BotConfig {
|
||||
All = Forwarding | Distributing | KeepMissingGames | AssumeWalletKeyOnBadActivationCode
|
||||
}
|
||||
|
||||
[Flags]
|
||||
public enum ERemoteCommunication : byte {
|
||||
None = 0,
|
||||
SteamGroup = 1,
|
||||
PublicListing = 2,
|
||||
All = SteamGroup | PublicListing
|
||||
}
|
||||
|
||||
[Flags]
|
||||
public enum ETradingPreferences : byte {
|
||||
None = 0,
|
||||
|
||||
@@ -94,48 +94,6 @@ internal sealed class BotDatabase : SerializableFile {
|
||||
[JsonProperty(PropertyName = $"_{nameof(MobileAuthenticator)}")]
|
||||
private MobileAuthenticator? BackingMobileAuthenticator;
|
||||
|
||||
private bool SaveNeededDueToMigration;
|
||||
|
||||
[JsonProperty(Required = Required.DisallowNull)]
|
||||
[Obsolete("Available for limited time and only to migrate existing databases")]
|
||||
private ConcurrentHashSet<ulong> BlacklistedFromTradesSteamIDs {
|
||||
set {
|
||||
if (TradingBlacklistSteamIDs.AddRange(value) && string.IsNullOrEmpty(FilePath)) {
|
||||
SaveNeededDueToMigration = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[JsonProperty(Required = Required.DisallowNull)]
|
||||
[Obsolete("Available for limited time and only to migrate existing databases")]
|
||||
private ConcurrentHashSet<uint> IdlingBlacklistedAppIDs {
|
||||
set {
|
||||
if (FarmingBlacklistAppIDs.AddRange(value) && string.IsNullOrEmpty(FilePath)) {
|
||||
SaveNeededDueToMigration = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[JsonProperty(Required = Required.DisallowNull)]
|
||||
[Obsolete("Available for limited time and only to migrate existing databases")]
|
||||
private ConcurrentHashSet<uint> IdlingPriorityAppIDs {
|
||||
set {
|
||||
if (FarmingPriorityQueueAppIDs.AddRange(value) && string.IsNullOrEmpty(FilePath)) {
|
||||
SaveNeededDueToMigration = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[JsonProperty(Required = Required.DisallowNull)]
|
||||
[Obsolete("Available for limited time and only to migrate existing databases")]
|
||||
private ConcurrentHashSet<uint> MatchActivelyBlacklistedAppIDs {
|
||||
set {
|
||||
if (MatchActivelyBlacklistAppIDs.AddRange(value) && string.IsNullOrEmpty(FilePath)) {
|
||||
SaveNeededDueToMigration = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private BotDatabase(string filePath) {
|
||||
if (string.IsNullOrEmpty(filePath)) {
|
||||
throw new ArgumentNullException(nameof(filePath));
|
||||
@@ -243,12 +201,6 @@ internal sealed class BotDatabase : SerializableFile {
|
||||
|
||||
botDatabase.FilePath = filePath;
|
||||
|
||||
if (botDatabase.SaveNeededDueToMigration) {
|
||||
botDatabase.SaveNeededDueToMigration = false;
|
||||
|
||||
Utilities.InBackground(botDatabase.Save);
|
||||
}
|
||||
|
||||
return botDatabase;
|
||||
}
|
||||
|
||||
|
||||
@@ -99,9 +99,6 @@ public sealed class GlobalConfig {
|
||||
[PublicAPI]
|
||||
public const EOptimizationMode DefaultOptimizationMode = EOptimizationMode.MaxPerformance;
|
||||
|
||||
[PublicAPI]
|
||||
public const bool DefaultStatistics = true;
|
||||
|
||||
[PublicAPI]
|
||||
public const string? DefaultSteamMessagePrefix = "/me ";
|
||||
|
||||
@@ -259,9 +256,6 @@ public sealed class GlobalConfig {
|
||||
[JsonProperty(Required = Required.DisallowNull)]
|
||||
public EOptimizationMode OptimizationMode { get; private set; } = DefaultOptimizationMode;
|
||||
|
||||
[JsonProperty(Required = Required.DisallowNull)]
|
||||
public bool Statistics { get; private set; } = DefaultStatistics;
|
||||
|
||||
[JsonProperty]
|
||||
[MaxLength(SteamChatMessage.MaxMessagePrefixBytes / SteamChatMessage.ReservedEscapeMessageBytes)]
|
||||
public string? SteamMessagePrefix { get; private set; } = DefaultSteamMessagePrefix;
|
||||
@@ -303,6 +297,10 @@ public sealed class GlobalConfig {
|
||||
|
||||
internal bool Saving { get; set; }
|
||||
|
||||
// TODO: Pending removal, Statistics property which got changed into RemoteConnection
|
||||
[JsonProperty(Required = Required.DisallowNull)]
|
||||
internal bool Statistics { get; private set; } = true;
|
||||
|
||||
[JsonProperty]
|
||||
internal string? WebProxyPassword {
|
||||
get => BackingWebProxyPassword;
|
||||
@@ -398,8 +396,11 @@ public sealed class GlobalConfig {
|
||||
[UsedImplicitly]
|
||||
public bool ShouldSerializeSSteamOwnerID() => !Saving;
|
||||
|
||||
// TODO: Pending removal, Statistics property which got changed into RemoteConnection, we never serialize it after update
|
||||
#pragma warning disable CA1822 // We can't mark it as static
|
||||
[UsedImplicitly]
|
||||
public bool ShouldSerializeStatistics() => !Saving || (Statistics != DefaultStatistics);
|
||||
public bool ShouldSerializeStatistics() => false;
|
||||
#pragma warning restore CA1822 // We can't mark it as static
|
||||
|
||||
[UsedImplicitly]
|
||||
public bool ShouldSerializeSteamMessagePrefix() => !Saving || (SteamMessagePrefix != DefaultSteamMessagePrefix);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<Project>
|
||||
<PropertyGroup>
|
||||
<Version>5.2.2.3</Version>
|
||||
<Version>5.2.3.1</Version>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
|
||||
@@ -3,9 +3,9 @@
|
||||
<PackageVersion Include="AngleSharp.XPath" Version="1.1.7" />
|
||||
<PackageVersion Include="ConfigureAwaitChecker.Analyzer" Version="5.0.0" />
|
||||
<PackageVersion Include="CryptSharpStandard" Version="1.0.0" />
|
||||
<PackageVersion Include="Humanizer" Version="2.13.14" />
|
||||
<PackageVersion Include="Humanizer" Version="2.14.1" />
|
||||
<PackageVersion Include="JetBrains.Annotations" Version="2021.3.0" />
|
||||
<PackageVersion Include="Markdig.Signed" Version="0.26.0" />
|
||||
<PackageVersion Include="Markdig.Signed" Version="0.27.0" />
|
||||
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.0.0" />
|
||||
<PackageVersion Include="MSTest.TestAdapter" Version="2.2.8" />
|
||||
<PackageVersion Include="MSTest.TestFramework" Version="2.2.8" />
|
||||
@@ -18,7 +18,7 @@
|
||||
<PackageVersion Include="Swashbuckle.AspNetCore.Newtonsoft" Version="6.2.3" />
|
||||
<PackageVersion Include="System.Composition" Version="6.0.0" />
|
||||
<PackageVersion Include="System.Composition.AttributedModel" Version="6.0.0" />
|
||||
<PackageVersion Include="System.Linq.Async" Version="5.1.0" />
|
||||
<PackageVersion Include="System.Linq.Async" Version="6.0.1" />
|
||||
<PackageVersion Include="zxcvbn-core" Version="7.0.92" />
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
2
wiki
2
wiki
Submodule wiki updated: 44c9c35ee3...089da4eeba
Reference in New Issue
Block a user