import json
from websockets.sync.client import connect
with open('./buff.json', 'r') as f:
buff = json.load(f)
cookie = 'session=s%3AxLorVvLv1jgU_iiN9ZI300O1igdlMd4T.65APthoviMVcX3UhIQTPxrGa%2BhcAmUvrWmosS1qYX2M'
header = [
('Pragma', 'no-cache'),
('Cache-Control', 'no-cache'),
('User-Agent',
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Safari/537.36'),
('Accept-Encoding', 'gzip, deflate, br'),
('Accept-Language', 'en-GB,en-US;q=0.9,en;q=0.8'),
('Sec-WebSocket-Extensions', 'permessage-deflate; client_max_window_bits'),
('Sec-WebSocket-Protocol', 'graphql-transport-ws'),
('Cookie',cookie)
]
msg_con = '{"type":"connection_init"}'
msg_sub_remove = '{"id":"7e987ea8-36f1-4bf9-840e-289a69b4c106","type":"subscribe","payload":{"variables":{},"extensions":{},"operationName":"OnRemoveFromListedTrade","query":"subscription OnRemoveFromListedTrade { removeFromListedTrade { tradeId __typename }}"}}'
msg_sub_add = '{"id":"696f26db-b696-4564-a40e-2e1d5768fa64","type":"subscribe","payload":{"variables":{},"extensions":{},"operationName":"OnCreateTrade","query":"subscription OnCreateTrade($userId: ID) { createTrade(userId: $userId) { trade { ...Trade __typename } __typename }}fragment Trade on Trade { id status steamAppName cancelReason canJoinAfter markupPercent createdAt depositor { id steamId avatar displayName steamDisplayName __typename } promoCode { id percentageReward maxBalance __typename } expiresAt withdrawerSteamTradeUrl customValue withdrawer { id steamId avatar displayName steamDisplayName __typename } totalValue updatedAt tradeItems { id marketName value customValue itemVariant { ...ItemVariant __typename } markupPercent __typename } trackingType suspectedTraderCanJoinAfter joinedAt __typename}fragment ItemVariant on ItemVariant { id itemId name brand iconUrl value currency displayValue exchangeRate shippingCost usable obtainable withdrawable depositable externalId type category { id name __typename } color size rarity availableAssets { steamAssetId availableAt __typename } purchasable totalRequested totalAvailable totalFulfilled totalUnfulfilled createdAt __typename}"}}'
msg_sub_wallet = '{"id":"ad44beda-85a5-45c0-972f-f13007b0ba82","type":"subscribe","payload":{"variables":{},"extensions":{},"operationName":"OnUpdateWallet","query":"subscription OnUpdateWallet { updateWallet { wallet { id amount name __typename } walletChange { id type externalId valueChange __typename } __typename }}"}}'
msg_buy1 = '{"id":"138e87a5-842c-4f84-8b7b-ade522c06858","type":"subscribe","payload":{"variables":{"input":{"tradeIds":["--TRADEID--"],"recaptcha":"03AL8dmw98RhV6axsNrSfSbobgxj3WRlH86Qi5il4AixFP0NZ-fzRs4hTdvxfLvX5lEayuiff_tAwAieydD5qkpR8ALagmjhPpud0ZdAZdnTwqTnvjKBDWd_mJ9u7Mb12senBCpNuCtOFnJU8XTigAurhGKoN4HzvajfLPFahtAAC-YowrOLJbCDTxabH2hOmMhyUiCas-tvu3JuQZb4sRPrGKZyIHKUtLZLZ7AD9D_5irlLL10esRXgGo5krCeDpAnESpN-g0ve-FBNYOVPtGYiuG_uSHwuGCq7pXah9U15bjUpFg_HJV9Hr_1m4e1UEd1qgTkiVH9n_-jq4wpGA4nMIsciTlS7QJTTz9PIolobSO0nnyeUHOQMCxX14mKWmwAbj1XPNnuQlU8dSCvDxtMj9KN_rWruBY4Su2VpH-hhdSCagnBR3hG-7C9FaySq-0L_AYqTMh_CIiNdKt91PHHSawCLLmncqd09BMgNWB2y5v4lSBy8wZFiBZvbCjg7iHqJ2npRySMxBTvHFwtpUxPLAZ2cy7w_Faa_gpZklqtLBhsPjxEFwturSS-T6jHzsV5rDtWGEzPgMFdaC91ief6POI0tZ2yeivLHcuvMtQyJejW64u1sI2VQdbw4OfLyKUAO2Rbz3Vm9xxwQAIcxbFWYe4SyA92q1JyaiodduovDmRIkQRbKEHbVg96_LX8_aZAEc2ItnpSTBXoizHR96Rb6o7XTu8WvMcbfZRkARuOMIvSAwZlZyN4nnUzFvLdY5b01hjJqvD6h4uixsJvtsQL4o6yM0CyzVH56SPY70XL3QryKe0uPkCccqHZtACPYGLplnPYOC6599gAOdnqND5znccdbeb5LxScYvan6mAbxkp9Y61QtePkdqwTVkiw5u8Hss2GGwTMC4Gv1Y2QkXMvHLqn0B0Sus1rTyrCT-wcLN2qwttYgVPJVOcjACF99KnO-Vc03cyKdWW2wfVe61xle0oTw9LGOmeikYk46LEIx1Lt3KEd9IRXRWF0FSnoQ9kCno8th8pcprk0NMlNN_YSkQH5of5p4TmQQadwnhIUt7a4LB34ycYq-h_B2XrStxeeHseBqvnU7H_qE25LhwU832E0PKlc9Llaa1Y70raDI6q2bDwErIlwFRGnnf_-EiRndAjrEoUgxnwPpDTBW0Omnq3NkO4g6KqS99-S4hCC-1iZjC6W2vZp_2QJmvgr1UFkvYkGwRqzPo-QwW67Y7kuYeTLoq_zKcmZTqh6EdlmfxsL2-rkocettXFl3hPyHCXhYJ-ja7ypfWhCwAj_am7SSUJ685N76etsnrMFEaQO0vaS5kR9azA8a1BZsBnguhUUom0ubztcXlo3y_K5dh9wWnGywh-2y723VQisuf_rUcItVdFhW7IxN7xcQH8WkWRWYJXmF89bic7iCdtftb3-x3a_oHILpok8mmGylJq4DrJfRIPdD6g-H-4eowlL4DYPHs_Ncm1UxwtWiG6zH7nPr-9r_6gqUCTNw"}},"extensions":{},"operationName":"JoinTrades","query":"mutation JoinTrades($input: JoinTradesInput!) { joinTrades(input: $input) { trades { id status totalValue updatedAt expiresAt withdrawer { id steamId avatar displayName steamDisplayName __typename } __typename } __typename }}"}}'
msg_buy2 = '{"id":"138e87a5-842c-4f84-8b7b-ade522c06858","type":"subscribe","payload":{"variables":{"input":{"tradeIds":["--TRADEID--"],"recaptcha":"03AL8dmw-mKumz8NlsiHxKeVO_whWTAjzqKTPb4tOLSA7jbVx54-4BjU9y6z7200J6NkmJA-Hz6cZCrekzxzndxxgR3Qeh89tQk0xNcs61CC9g_RLYPiBmx1bAcixy0MUpVDJ6Oy3qsQVO1Jme23Gc1qQcxVQ9W5r2P-oQg0gnWPdCUAZ3rhpzytNBqo5fUVwqgLWs5ZyrIfFFf8T4aZadvb1EddCynXIj5WwofY_NLbZ5D-HU8ibeuD8pzZ2oSY6qywpIDPMngaX74e-G71GQmgj10_5_uRzsUZB6VhdHyMiJGPTTzOn9JiZP_1lrURSpBZoTn69jNQfAJxeTttJWYCGnqBqGUulbrvIHMQLEhqS69HF2NJsARpYsHvM4CRqxSG5T3wPY2u8rD6bp5vDXfDg3rFrZbeqoceuGFIivCXL2sF5g_TAFHGzv5XJFD04B1mVBk0vOnM-VnAttZK5KidOkLSm6eLZeCVmPgoJhpzsT8_0NODhlhI3d_iIdcK80OzP3RbgS8UG14rp-5iEalyJpfZNjK2ds-9RY6WicZgfHn1J_s2zuCefdfc591oFapEp3WacA-Yy426j8Bfu80FJJN9Mg0pT9isOtnZvdZkNNnYhI1C2e9cJr0vhC25FH4Vmqu0pFtT1FiZ_58tymRcri19CxyeH1S5yGnPwX1UCHn25BLC1zDGVt4cqiOhDu2jrgZaifJp7MlGSxW14s9pxMmLm-8w98WSvTyhhbDHfcS_coWUbdt0gA6HhH3c-KezDeSWlF2Dtt6ChXOJfBjIOq5dPNF6nbISQRneKCXbEudG9lG0sLAQqcGJ8pGlzvNtZdXPoTQTCD9jGNvR2ImjjhUfX83p-9pPH0IywD-eY4kKrhex2dHwbVgF_cKkc_7yysVOM1iIyOhcvEEZXN6Uvn8HMYR0ukYMOWDUamcWs0P10gJOfW7gLWFVGmihty8R63tfkjOV_fxLzdeLqerlogJ4MOTA6RfDaibsVNLMc8DZyFPzBtgry3dy7ujI5m_H_hzaCp-3P5KiOL7O6KbHKwiSYMBCzSMFMDm8RnX5BxhYCQTxt_ce8t4M7DJHVWAlEwG18ElbIa9xEkO4DKoAZ4qBjBs9uZ-G0ZliWBEDIukI9H0AUHow60lKf44TMkKl8wC9hpmmEkTKdyL6jAcYUUtHs8pzcooqRCTkQJ4JxAv7ImCY--tFhijbpjeGktR9l5Hq45Y3qZC3QQ5rpX2u9UKboXqvSFO5RFRruD9SIzYfE6ALn8Kaii7Cayvu2ZsIl2c--nzJzEsZNs3BIu8_7wh1yrqs6wkFMzPu6fcA-B_gE4YmqAKZ1GyEXcga5RYgQETV08W13Oi-Zy0pGMVQdSPUddlTxWgKNPp3j9BQY3bJ6hCZ31g28iWfK2wKwVkm2L6sOFzavzlZpRG9BQyd7QXU5SHsDZaBQ5qfNreSQxGqYjgBfFr2awq5KREaI4cRXJeoXVROAQp0hH1tT8rQtEfcuZNkLUTA"}},"extensions":{},"operationName":"JoinTrades","query":"mutation JoinTrades($input: JoinTradesInput!) { joinTrades(input: $input) { trades { id status totalValue updatedAt expiresAt withdrawer { id steamId avatar displayName steamDisplayName __typename } __typename } __typename }}"}}'
msg_sub_complete = '{"id":"a0d79d83-c9f4-4fac-b7c5-a013ce121920","type":"complete"}'
while True:
try:
current = 1
ws = connect("wss://api.csgoroll.com/graphql", additional_headers=header, origin="https://www.csgoroll.com",subprotocols=['graphql-transport-ws'])
ws.send(msg_con)
print("connection message sent")
while not "connection_ack" in ws.recv():
pass
print("connection ack received")
ws.send(msg_sub_add)
#ws.send(msg_sub_remove)
ws.send(msg_sub_wallet)
#ws.send(msg_sub_complete)
print("subscription messages sent")
trades = {}
balance = 30
def process(data):
try:
if 'createTrade' in data['payload']['data']:
process_create_trade(data)
except Exception:
pass
try:
if 'removeFromListedTrade' in data['payload']['data']:
process_remove_trade(data)
except Exception:
pass
try:
if 'updateWallet' in data['payload']['data']:
process_wallet_update(data)
except Exception:
pass
try:
if 'joinTrades' in data['payload']['data']:
process_success(data)
except Exception:
pass
try:
if 'error' in data['payload']:
process_failure(data)
except Exception:
pass
def process_create_trade(data):
global trades
id = data['payload']['data']['createTrade']['trade']['id']
name = data['payload']['data']['createTrade']['trade']['tradeItems'][0]['marketName']
value = data['payload']['data']['createTrade']['trade']['tradeItems'][0]['value']
if id in trades.keys():
return
trades[id] = (id, name, value)
prices = buff.get(name)
if prices is None or "buy_max_price" not in prices:
current_buy_margin = -1
else:
current_buy_margin = prices["buy_max_price"] / (5.1 * value) - 1
if prices is None or "sell_min_price" not in prices:
current_sell_margin = -1
else:
current_sell_margin = prices["sell_min_price"] / (5.1 * value) - 1
print(f"Item available: {name:<70} coins: {value:<7} buy margin: {current_buy_margin:<7.2f} sell margin: {current_sell_margin:<7.2f}")
if current_buy_margin - 0.1 > current_sell_margin:
to_buy = (0.35 <= current_sell_margin and 0.1 < current_buy_margin)
else:
to_buy = (0.2 <= current_buy_margin) or (0.35 <= current_sell_margin and 0.1 < current_buy_margin)
if to_buy and value < 50 and "Revolution Case" not in name and "Black Nile" not in name and "Steel Delta" not in name and "Copper Coated" not in name and "Mummy's Rot" not in name and "ScaraB Rush" not in name and "Sobek's Bite" not in name and "Mud-Spec" not in name and "Ramese's Reach" not in name and "Echoing Sands" not in name and "Apep's Curse" not in name and "Waters of Nephthys" not in name:
buy(id)
print(f"Trying to buy: {name:<70} coins: {value:<7} buy margin: {current_buy_margin:<7.2f} sell margin: {current_sell_margin:<7.2f}")
def process_remove_trade(data):
global trades
id = data['payload']['data']['removeFromListedTrade']['tradeId']
def process_wallet_update(data):
global balance
balance = data['payload']['data']['updateWallet']['wallet']['amount']
def process_success(data):
print(f"Success: {data}")
def process_failure(data):
print(f"Failure: {data}")
def buy(id):
global msg_buy1,msg_buy2,current
if current == 1:
msg_buy = msg_buy1
current = 2
else:
msg_buy = msg_buy2
current = 1
msg = msg_buy.replace('--TRADEID--', id)
ws.send(msg)
while True:
new = ws.recv()
data = json.loads(new)
process(data)
except Exception:
pass