Skip to content

Commit ff1bbfc

Browse files
committed
Adds Fetch/Ping for Blocked Users during CSFloat Market Trades
1 parent f27b332 commit ff1bbfc

File tree

9 files changed

+142
-16
lines changed

9 files changed

+142
-16
lines changed

package-lock.json

Lines changed: 8 additions & 16 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/lib/alarms/blocked_users.ts

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
import {Trade} from '../types/float_market';
2+
import {gStore} from '../storage/store';
3+
import {StorageKey} from '../storage/keys';
4+
import {FetchSteamUser} from '../bridge/handlers/fetch_steam_user';
5+
import {FetchBlockedUsers} from '../bridge/handlers/fetch_blocked_users';
6+
import {PingBlockedUsers} from '../bridge/handlers/ping_blocked_users';
7+
8+
export async function reportBlockedBuyers(pendingTrades: Trade[]) {
9+
const lastPing = await gStore.getWithStorage<number>(
10+
chrome.storage.local,
11+
StorageKey.LAST_TRADE_BLOCKED_PING_ATTEMPT
12+
);
13+
if (lastPing && lastPing > Date.now() - 10 * 60 * 1000) {
14+
// Report blocked users at most once every 10 minutes
15+
return;
16+
}
17+
18+
await gStore.setWithStorage<number>(chrome.storage.local, StorageKey.LAST_TRADE_BLOCKED_PING_ATTEMPT, Date.now());
19+
20+
const steamUser = await FetchSteamUser.handleRequest({}, {});
21+
if (!steamUser.sessionID || !steamUser.steamID) {
22+
return;
23+
}
24+
25+
const hasTrade = pendingTrades.some((e) => e.seller_id === steamUser.steamID || e.buyer_id === steamUser.steamID);
26+
if (!hasTrade) {
27+
// Logged-in user on Steam doesn't have any CSFloat trades, not relevant
28+
return;
29+
}
30+
31+
const {blocked_steam_ids} = await FetchBlockedUsers.handleRequest(
32+
{
33+
steam_id: steamUser.steamID,
34+
},
35+
{}
36+
);
37+
38+
const filteredIDs = blocked_steam_ids.filter((steamID) => {
39+
// Is it a buyer or seller in one of the trades?
40+
return pendingTrades.some((e) => e.seller_id == steamID || e.buyer_id == steamID);
41+
});
42+
43+
if (filteredIDs.length === 0) {
44+
// Nothing to report
45+
return;
46+
}
47+
48+
await PingBlockedUsers.handleRequest({blocked_steam_ids: filteredIDs}, {});
49+
}

src/lib/alarms/csfloat_trade_pings.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import {PingExtensionStatus} from '../bridge/handlers/ping_extension_status';
77
import {AccessToken, getAccessToken} from './access_token';
88
import {gStore} from '../storage/store';
99
import {StorageKey} from '../storage/keys';
10+
import {reportBlockedBuyers} from './blocked_users';
1011

1112
export const PING_CSFLOAT_TRADE_STATUS_ALARM_NAME = 'ping_csfloat_trade_status_alarm';
1213

@@ -67,11 +68,19 @@ export async function pingTradeStatus(expectedSteamID?: string) {
6768
interface UpdateErrors {
6869
history_error?: string;
6970
trade_offer_error?: string;
71+
blocked_buyers_error?: string;
7072
}
7173

7274
async function pingUpdates(pendingTrades: Trade[]): Promise<UpdateErrors> {
7375
const errors: UpdateErrors = {};
7476

77+
try {
78+
await reportBlockedBuyers(pendingTrades);
79+
} catch (e) {
80+
console.error('failed to report blocked buyers', e);
81+
errors.blocked_buyers_error = (e as any).toString();
82+
}
83+
7584
try {
7685
await cancelUnconfirmedTradeOffers(pendingTrades);
7786
} catch (e) {
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import {SimpleHandler} from './main';
2+
import {RequestType} from './types';
3+
4+
interface FetchBlockedUsersRequest {
5+
// Steam ID to use to fetch who they've blocked. If this doesn't match the logged
6+
// in user, then an error will be thrown.
7+
steam_id: string;
8+
}
9+
10+
interface FetchBlockedUsersResponse {
11+
blocked_steam_ids: string[];
12+
}
13+
14+
export const FetchBlockedUsers = new SimpleHandler<FetchBlockedUsersRequest, FetchBlockedUsersResponse>(
15+
RequestType.FETCH_BLOCKED_USERS,
16+
async (req) => {
17+
const resp = await fetch(
18+
`https://steamcommunity.com/profiles/${req.steam_id}/friends/blocked?ajax=1&l=english`
19+
);
20+
if (!resp.ok) {
21+
throw new Error('non-ok response for blocked users');
22+
}
23+
24+
const text = await resp.text();
25+
26+
if (!text.toLowerCase().includes('blocked')) {
27+
throw new Error('failed to parse blocked users, requested steam id might not be logged in');
28+
}
29+
30+
const matches = text.matchAll(/class=".+?ignored.+?".*?id=".+?".*?data-steamid="(7656\d+)"/gs);
31+
32+
const blocked_steam_ids = [...matches].map((match) => {
33+
return match[1];
34+
});
35+
36+
return {blocked_steam_ids};
37+
}
38+
);

src/lib/bridge/handlers/handlers.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ import {PingStatus} from './ping_status';
2424
import {FetchOwnInventory} from './fetch_own_inventory';
2525
import {CancelTradeOffer} from './cancel_trade_offer';
2626
import {FetchSteamTrades} from './fetch_steam_trades';
27+
import {FetchBlockedUsers} from './fetch_blocked_users';
28+
import {PingBlockedUsers} from './ping_blocked_users';
2729

2830
export const HANDLERS_MAP: {[key in RequestType]: RequestHandler<any, any>} = {
2931
[RequestType.EXECUTE_SCRIPT_ON_PAGE]: ExecuteScriptOnPage,
@@ -50,4 +52,6 @@ export const HANDLERS_MAP: {[key in RequestType]: RequestHandler<any, any>} = {
5052
[RequestType.FETCH_OWN_INVENTORY]: FetchOwnInventory,
5153
[RequestType.CANCEL_TRADE_OFFER]: CancelTradeOffer,
5254
[RequestType.FETCH_STEAM_TRADES]: FetchSteamTrades,
55+
[RequestType.FETCH_BLOCKED_USERS]: FetchBlockedUsers,
56+
[RequestType.PING_BLOCKED_USERS]: PingBlockedUsers,
5357
};
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import {SimpleHandler} from './main';
2+
import {RequestType} from './types';
3+
import {environment} from '../../../environment';
4+
5+
export interface PingBlockedUsersRequest {
6+
blocked_steam_ids: string[];
7+
}
8+
9+
export interface PingBlockedUsersResponse {}
10+
11+
export const PingBlockedUsers = new SimpleHandler<PingBlockedUsersRequest, PingBlockedUsersResponse>(
12+
RequestType.PING_BLOCKED_USERS,
13+
async (req) => {
14+
const resp = await fetch(`${environment.csfloat_base_api_url}/v1/trades/steam-status/blocked-users`, {
15+
credentials: 'include',
16+
method: 'POST',
17+
headers: {
18+
'Content-Type': 'application/json',
19+
},
20+
body: JSON.stringify(req),
21+
});
22+
23+
if (resp.status !== 200) {
24+
throw new Error('invalid status');
25+
}
26+
27+
return {};
28+
}
29+
);

src/lib/bridge/handlers/types.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,4 +23,6 @@ export enum RequestType {
2323
FETCH_OWN_INVENTORY = 21,
2424
CANCEL_TRADE_OFFER = 22,
2525
FETCH_STEAM_TRADES = 23,
26+
FETCH_BLOCKED_USERS = 24,
27+
PING_BLOCKED_USERS = 25,
2628
}

src/lib/storage/keys.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ export enum StorageKey {
1010
GLOBAL_FILTERS = 'global',
1111
ACCESS_TOKEN = 'access_token',
1212
LAST_TRADE_PING_ATTEMPT = 'last_trade_ping_attempt',
13+
LAST_TRADE_BLOCKED_PING_ATTEMPT = 'last_trade_blocked_ping_attempt',
1314
}
1415

1516
export type DynamicStorageKey = string;

src/lib/types/float_market.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,4 +104,6 @@ export interface Trade {
104104
trade_url: string;
105105
steam_offer: SteamOffer;
106106
wait_for_cancel_ping?: boolean;
107+
seller_blocked_buyer_at?: string;
108+
buyer_blocked_seller_at?: string;
107109
}

0 commit comments

Comments
 (0)