Skip to content

Commit

Permalink
Merge branch 'asf-update'
Browse files Browse the repository at this point in the history
  • Loading branch information
Citrinate committed Apr 2, 2024
2 parents 68a0715 + 1eab5a5 commit 534c2d1
Show file tree
Hide file tree
Showing 12 changed files with 535 additions and 168 deletions.
2 changes: 1 addition & 1 deletion ArchiSteamFarm
Submodule ArchiSteamFarm updated 278 files
42 changes: 0 additions & 42 deletions CS2Interface/AdapterBridge.cs

This file was deleted.

75 changes: 38 additions & 37 deletions CS2Interface/CS/Client.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using System.Threading;
using System.Threading.Tasks;
using ArchiSteamFarm.Steam;
using CS2Interface.Localization;
using ProtoBuf;
using SteamKit2;
using SteamKit2.GC;
Expand Down Expand Up @@ -38,17 +39,17 @@ internal async Task<bool> Run() {
}

if (ConnectionSemaphore.CurrentCount != 1) {
throw new ClientException(EClientExceptionType.Failed, "CS2 Client is already attempting to run, please wait");
throw new ClientException(EClientExceptionType.Failed, Strings.ClientAlreadyStarting);
}

if (FatalError) {
throw new ClientException(EClientExceptionType.FatalError, "CS2 Client experienced a fatal error");
throw new ClientException(EClientExceptionType.FatalError, Strings.ClientFatalError);
}

await ConnectionSemaphore.WaitAsync().ConfigureAwait(false);
try {
if (!await GameData.IsLoaded(0).ConfigureAwait(false)) {
throw new ClientException(EClientExceptionType.Failed, "Failed to load Game Data");
throw new ClientException(EClientExceptionType.Failed, Strings.GameDataLoadingFailed);
}

// TODO: Verify that this account owns CS2
Expand All @@ -69,10 +70,10 @@ internal async Task<bool> Run() {
}};
var fetcher = new GCFetcher<CMsgClientHello, CMsgClientWelcome>((uint) EGCBaseClientMsg.k_EMsgGCClientWelcome);

Bot.ArchiLogger.LogGenericDebug("Sending hello message");
Bot.ArchiLogger.LogGenericDebug(Strings.SendingHello);

if (fetcher.Fetch(this, msg, resendMsg: true) == null) {
throw new ClientException(EClientExceptionType.Timeout, "CS2 Client wasn't able to connect to GC");
throw new ClientException(EClientExceptionType.Timeout, Strings.GCConnectionFailed);
}

HasGCSession = true;
Expand Down Expand Up @@ -110,7 +111,7 @@ internal async Task<bool> VerifyConnection() {
return false;
}

Bot.ArchiLogger.LogGenericDebug("Verifying CS2 Client's connection to GC");
Bot.ArchiLogger.LogGenericDebug(Strings.VerifyingGCConnection);
try {
await RequestPlayerProfile(Bot.SteamID).ConfigureAwait(false);
} catch {
Expand All @@ -126,7 +127,7 @@ private void OnGCMessage(SteamGameCoordinator.MessageCallback callback) {
}

#if DEBUG
Bot.ArchiLogger.LogGenericDebug(String.Format("Message Received: {0}", callback.EMsg));
Bot.ArchiLogger.LogGenericDebug(String.Format("{0}: {1}", Strings.MessageRecieved, callback.EMsg));
#endif

OnGCMessageRecieved?.Invoke(callback);
Expand Down Expand Up @@ -167,7 +168,7 @@ private void OnClientWelcome(IPacketGCMsg packetMsg) {
}
}));

Bot.ArchiLogger.LogGenericDebug("CS2 inventory loaded");
Bot.ArchiLogger.LogGenericDebug(Strings.InventoryLoaded);

return;
}
Expand All @@ -177,7 +178,7 @@ private void OnClientWelcome(IPacketGCMsg packetMsg) {
private void OnFatalLogonError(IPacketGCMsg packetMsg) {
var msg = new ClientGCMsgProtobuf<CMsgGCCStrike15_v2_ClientLogonFatalError>(packetMsg);

Bot.ArchiLogger.LogGenericError(String.Format("Fatal CS2 logon error {0}: {1}", msg.Body.errorcode, msg.Body.message));
Bot.ArchiLogger.LogGenericError(String.Format("{0}: {1}", String.Format(Strings.FatalLogonError, msg.Body.errorcode), msg.Body.message));
FatalError = true;
}

Expand Down Expand Up @@ -253,7 +254,7 @@ private void OnMultiItemUpdated(IPacketGCMsg packetMsg) {

internal async Task<CMsgGCCStrike15_v2_Client2GCEconPreviewDataBlockResponse> InspectItem(ulong param_s, ulong param_a, ulong param_d, ulong param_m) {
if (!HasGCSession) {
throw new ClientException(EClientExceptionType.Failed, "CS2 Client is not connected to GC");
throw new ClientException(EClientExceptionType.Failed, Strings.ClientNotConnectedToGC);
}

await GCSemaphore.WaitAsync().ConfigureAwait(false);
Expand All @@ -271,11 +272,11 @@ internal async Task<CMsgGCCStrike15_v2_Client2GCEconPreviewDataBlockResponse> In
VerifyFunc = response => response.Body.iteminfo.itemid == param_a
};

Bot.ArchiLogger.LogGenericDebug(String.Format("Inspecting item: s {0} a {1} d {2} m {3}", param_s, param_a, param_d, param_m));
Bot.ArchiLogger.LogGenericDebug(String.Format("{0}: s {1} a {2} d {3} m {4}", Strings.InspectingItem, param_s, param_a, param_d, param_m));

var response = fetcher.Fetch(this, msg);
if (response == null) {
throw new ClientException(EClientExceptionType.Timeout, "Request timed out");
throw new ClientException(EClientExceptionType.Timeout, Strings.RequestTimeout);
}

return response.Body;
Expand All @@ -286,12 +287,12 @@ internal async Task<CMsgGCCStrike15_v2_Client2GCEconPreviewDataBlockResponse> In

internal async Task<CMsgGCCStrike15_v2_PlayersProfile> RequestPlayerProfile(ulong steam_id) { //uint account_id) {
if (!HasGCSession) {
throw new ClientException(EClientExceptionType.Failed, "CS2 Client is not connected");
throw new ClientException(EClientExceptionType.Failed, Strings.ClientNotConnectedToGC);
}

SteamID SteamID = new(steam_id);
if (!SteamID.IsValid || SteamID.AccountUniverse != EUniverse.Public || SteamID.AccountType != EAccountType.Individual || SteamID.AccountInstance != SteamID.DesktopInstance) {
throw new ClientException(EClientExceptionType.BadRequest, "Invalid Steam ID");
throw new ClientException(EClientExceptionType.BadRequest, Strings.InvalidSteamID);
}

await GCSemaphore.WaitAsync().ConfigureAwait(false);
Expand All @@ -308,11 +309,11 @@ internal async Task<CMsgGCCStrike15_v2_PlayersProfile> RequestPlayerProfile(ulon
VerifyFunc = response => response.Body.account_profiles.FirstOrDefault()?.account_id == account_id
};

Bot.ArchiLogger.LogGenericDebug(String.Format("Getting CS2 player profile: {0}", steam_id));
Bot.ArchiLogger.LogGenericDebug(String.Format("{0}: {1}", Strings.InspectingPlayer, steam_id));

var response = fetcher.Fetch(this, msg);
if (response == null) {
throw new ClientException(EClientExceptionType.Timeout, "Request timed out");
throw new ClientException(EClientExceptionType.Timeout, Strings.RequestTimeout);
}

return response.Body;
Expand All @@ -323,21 +324,21 @@ internal async Task<CMsgGCCStrike15_v2_PlayersProfile> RequestPlayerProfile(ulon

internal async Task<List<InventoryItem>> GetCasketContents(ulong casket_id) {
if (!HasGCSession) {
throw new ClientException(EClientExceptionType.Failed, "CS2 Client is not connected to GC");
throw new ClientException(EClientExceptionType.Failed, Strings.ClientNotConnectedToGC);
}

if (Inventory == null) {
throw new ClientException(EClientExceptionType.Failed, "Inventory not loaded yet");
throw new ClientException(EClientExceptionType.Failed, Strings.InventoryNotLoaded);
}

InventoryItem? casket = Inventory.Values.FirstOrDefault(x => x.ItemInfo.id == casket_id);
if (casket == null) {
throw new ClientException(EClientExceptionType.BadRequest, "Storage unit not found in inventory");
throw new ClientException(EClientExceptionType.BadRequest, Strings.CasketNotFound);
}

uint? items_count = casket.GetAttribute("items count")?.ToUInt32();
if (items_count == null) {
throw new ClientException(EClientExceptionType.Failed, "Could not determine storage unit item count");
throw new ClientException(EClientExceptionType.Failed, Strings.CasketContentsUndefined);
}

if (items_count == 0) {
Expand All @@ -362,21 +363,21 @@ internal async Task<List<InventoryItem>> GetCasketContents(ulong casket_id) {
VerifyFunc = response => response.Body.item_id.FirstOrDefault() == casket_id && response.Body.request == (uint) EGCItemCustomizationNotification.k_EGCItemCustomizationNotification_CasketContents
};

Bot.ArchiLogger.LogGenericDebug(String.Format("Opening casket {0}", casket_id));
Bot.ArchiLogger.LogGenericDebug(String.Format(Strings.OpeningCasket, casket_id));

if (fetcher.Fetch(this, msg) == null) {
throw new ClientException(EClientExceptionType.Timeout, "Request timed out");
throw new ClientException(EClientExceptionType.Timeout, Strings.RequestTimeout);
}

// Casket contents can sometimes continue to come in after we've recieved the k_EMsgGCItemCustomizationNotification response
DateTime waitTime = DateTime.Now.AddSeconds(30);
while (Inventory.Values.Where(x => x.CasketID == casket_id).Count() != items_count && DateTime.Now < waitTime) {
Bot.ArchiLogger.LogGenericDebug(String.Format("Waiting for casket {0} items", casket_id));
Bot.ArchiLogger.LogGenericDebug(String.Format(Strings.CasketContentsLoading, casket_id));
await Task.Delay(TimeSpan.FromSeconds(1)).ConfigureAwait(false);
}

if (Inventory.Values.Where(x => x.CasketID == casket_id).Count() != items_count) {
throw new ClientException(EClientExceptionType.Failed, String.Format("Casket item count mismatch, casket should have {0} items but only found {1}", items_count, Inventory.Values.Where(x => x.CasketID == casket_id).Count()));
throw new ClientException(EClientExceptionType.Failed, String.Format(Strings.CasketItemCountMismatch, items_count, Inventory.Values.Where(x => x.CasketID == casket_id).Count()));
}

return Inventory.Values.Where(x => x.CasketID == casket_id).ToList();
Expand All @@ -387,27 +388,27 @@ internal async Task<List<InventoryItem>> GetCasketContents(ulong casket_id) {

internal async Task<bool> AddItemToCasket(ulong casket_id, ulong item_id) {
if (!HasGCSession) {
throw new ClientException(EClientExceptionType.Failed, "CS2 Client is not connected to GC");
throw new ClientException(EClientExceptionType.Failed, Strings.ClientNotConnectedToGC);
}

if (Inventory == null) {
throw new ClientException(EClientExceptionType.Failed, "Inventory not loaded yet");
throw new ClientException(EClientExceptionType.Failed, Strings.InventoryNotLoaded);
}

if (Inventory.Values.FirstOrDefault(x => x.ItemInfo.id == item_id) == null) {
throw new ClientException(EClientExceptionType.BadRequest, "Item not found in inventory");
throw new ClientException(EClientExceptionType.BadRequest, Strings.InventoryItemNotFound);
}

InventoryItem? casket = Inventory.Values.FirstOrDefault(x => x.ItemInfo.id == casket_id);
if (casket == null) {
throw new ClientException(EClientExceptionType.BadRequest, "Storage unit not found in inventory");
throw new ClientException(EClientExceptionType.BadRequest, Strings.CasketNotFound);
}

uint? items_count = casket.GetAttribute("items count")?.ToUInt32();
if (items_count == null) {
throw new ClientException(EClientExceptionType.Failed, "Could not determine storage unit item count");
throw new ClientException(EClientExceptionType.Failed, Strings.CasketContentsUndefined);
} else if (items_count == 1000) {
throw new ClientException(EClientExceptionType.BadRequest, "Storage unit is full");
throw new ClientException(EClientExceptionType.BadRequest, Strings.CasketFull);
}

await GCSemaphore.WaitAsync().ConfigureAwait(false);
Expand Down Expand Up @@ -437,10 +438,10 @@ internal async Task<bool> AddItemToCasket(ulong casket_id, ulong item_id) {
}
};

Bot.ArchiLogger.LogGenericDebug(String.Format("Adding item {0} to casket {1}", item_id, casket_id));
Bot.ArchiLogger.LogGenericDebug(String.Format(Strings.AddingItemToCasket, item_id, casket_id));

if (fetcher.Fetch(this, msg) == null) {
throw new ClientException(EClientExceptionType.Timeout, "Request timed out");
throw new ClientException(EClientExceptionType.Timeout, Strings.RequestTimeout);
}

return true;
Expand All @@ -451,16 +452,16 @@ internal async Task<bool> AddItemToCasket(ulong casket_id, ulong item_id) {

internal async Task<bool> RemoveItemFromCasket(ulong casket_id, ulong item_id) {
if (!HasGCSession) {
throw new ClientException(EClientExceptionType.Failed, "CS2 Client is not connected to GC");
throw new ClientException(EClientExceptionType.Failed, Strings.ClientNotConnectedToGC);
}

if (Inventory == null) {
throw new ClientException(EClientExceptionType.Failed, "Inventory not loaded yet");
throw new ClientException(EClientExceptionType.Failed, Strings.InventoryNotLoaded);
}

InventoryItem? casket = Inventory.Values.FirstOrDefault(x => x.ItemInfo.id == casket_id);
if (casket == null) {
throw new ClientException(EClientExceptionType.BadRequest, "Storage unit not found in inventory");
throw new ClientException(EClientExceptionType.BadRequest, Strings.CasketNotFound);
}

// Does not verify that the item is actually in the crate, to do that we would need to request the crate contents first
Expand Down Expand Up @@ -492,10 +493,10 @@ internal async Task<bool> RemoveItemFromCasket(ulong casket_id, ulong item_id) {
}
};

Bot.ArchiLogger.LogGenericDebug(String.Format("Removing item {0} from casket {1}", item_id, casket_id));
Bot.ArchiLogger.LogGenericDebug(String.Format(Strings.RemovingItemFromCasket, item_id, casket_id));

if (fetcher.Fetch(this, msg) == null) {
throw new ClientException(EClientExceptionType.Timeout, "Request timed out");
throw new ClientException(EClientExceptionType.Timeout, Strings.RequestTimeout);
}

return true;
Expand Down
55 changes: 28 additions & 27 deletions CS2Interface/CS/GameData.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using System.Threading;
using System.Threading.Tasks;
using ArchiSteamFarm.Core;
using CS2Interface.Localization;

namespace CS2Interface {
internal static class GameData {
Expand All @@ -21,7 +22,7 @@ internal static void Update(bool forceUpdate = false) {
ItemsGameCdn.Updated = false;
CsgoEnglish.Updated = false;
DoNotUpdateUntil = DateTime.Now.AddMinutes(15);
ASF.ArchiLogger.LogGenericInfo("Refreshing CS2 game data");
ASF.ArchiLogger.LogGenericInfo(Strings.GameDataRefreshing);
}

if (!ItemsGame.Updated || !ItemsGameCdn.Updated || !CsgoEnglish.Updated) {
Expand Down Expand Up @@ -72,7 +73,7 @@ private static async Task DoUpdate() {
if (ItemsGame.Updated && ItemsGameCdn.Updated && CsgoEnglish.Updated) {
UpdateTimer.Change(Timeout.Infinite, Timeout.Infinite);
IsUpdating = false;
ASF.ArchiLogger.LogGenericInfo("CS2 game data loaded");
ASF.ArchiLogger.LogGenericInfo(Strings.GameDataLoadingSuccess);
}
} catch (Exception e) {
ASF.ArchiLogger.LogGenericException(e);
Expand All @@ -94,31 +95,31 @@ private static async Task DoUpdate() {
internal static string? GetOriginName(uint origin) {
// https://raw.githubusercontent.com/SteamDatabase/SteamTracking/b5cba7a22ab899d6d423380cff21cec707b7c947/ItemSchema/CounterStrikeGlobalOffensive.json
return origin switch {
0 => "Timed Drop",
1 => "Achievement",
2 => "Purchased",
3 => "Traded",
4 => "Crafted",
5 => "Store Promotion",
6 => "Gifted",
7 => "Support Granted",
8 => "Found in Crate",
9 => "Earned",
10 => "Third-Party Promotion",
11 => "Wrapped Gift",
12 => "Halloween Drop",
13 => "Steam Purchase",
14 => "Foreign Item",
15 => "CD Key",
16 => "Collection Reward",
17 => "Preview Item",
18 => "Steam Workshop Contribution",
19 => "Periodic Score Reward",
20 => "Recycling",
21 => "Tournament Drop",
22 => "Stock Item",
23 => "Quest Reward",
24 => "Level Up Reward",
0 => Strings.ItemOrigin0, // Timed Drop
1 => Strings.ItemOrigin1, // Achievement
2 => Strings.ItemOrigin2, // Purchased
3 => Strings.ItemOrigin3, // Traded
4 => Strings.ItemOrigin4, // Crafted
5 => Strings.ItemOrigin5, // Store Promotion
6 => Strings.ItemOrigin6, // Gifted
7 => Strings.ItemOrigin7, // Support Granted
8 => Strings.ItemOrigin8, // Found in Crate
9 => Strings.ItemOrigin9, // Earned
10 => Strings.ItemOrigin10, // "Third-Party Promotion
11 => Strings.ItemOrigin11, // "Wrapped Gift
12 => Strings.ItemOrigin12, // "Halloween Drop
13 => Strings.ItemOrigin13, // "Steam Purchase
14 => Strings.ItemOrigin14, // "Foreign Item
15 => Strings.ItemOrigin15, // "CD Key
16 => Strings.ItemOrigin16, // "Collection Reward
17 => Strings.ItemOrigin17, // "Preview Item
18 => Strings.ItemOrigin18, // "Steam Workshop Contribution
19 => Strings.ItemOrigin19, // "Periodic Score Reward
20 => Strings.ItemOrigin20, // "Recycling
21 => Strings.ItemOrigin21, // "Tournament Drop
22 => Strings.ItemOrigin22, // "Stock Item
23 => Strings.ItemOrigin23, // "Quest Reward
24 => Strings.ItemOrigin24, // "Level Up Reward
_ => null
};
}
Expand Down
Loading

0 comments on commit 534c2d1

Please sign in to comment.