1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
|
# Steam Relationships
## A tool to discover friend relationships between steam profiles
Ever ran into a cheater, looked at their profile, and realized all their friends are cheaters too? I have, and this tool is a way to measure degrees of separation from a specific individual
Steam Relationships querries the Steam WebAPI to get public friends lists, and then recursively search those friend lists as well. This process repeats until a certain number of "degrees" have been met (a set recursion level specified by the user). The results of these querries are put in a database that can then be shared and used for other purposes
## REQUIREMENTS
1. Python 3.10 or greater
2. [Requests](https://docs.python-requests.org/en/latest/index.html) 2.31.0 or greater
3. A [Steam Developer API key](https://steamcommunity.com/dev/apikey)
If using [Poetry](https://python-poetry.org/), all Python dependencies are fetched automatically
## INSTALLATION
### Pip version
1. Run `pip install steamrelationships`
### Poetry Version
1. In a poetry shell, run `poetry add steamrelationships`
2. Import the package `import steamrelationships`
3. See the documentation on methods & objects
## DOCUMENTATION
### Objects
| Object | Full Name | Description |
| :----: | :-------: | :---------- |
| SteamRelationships | steamrelationships.sr.SteamRelationships | A class implementing Steam friends list scanning |
| Object | steamrelationships.constants._Const | A class containing constant values used throughout the SteamRelationships Class |
### Constants
| Name | Value | Description |
| :-- | ---: | ----------- |
| STEAMAPI_MAXREQ | 100000 | Steam's daily API request limit |
| DAY_IN_NANO | 8.64 * (10 ** 13) | The amount of nanoseconds in 24 hours |
| JSON_INDENT | 4 | The indent used when dumping a Python object to a .json file |
### `steamrelationships.sr.SteamRelationships()` methods
| Function | Params | Return Values | Description |
| :------: | :----- | :------------ | :---------- |
| basicscan | **`(str) steamid64`** - A 64 bit decimal Steam id | **`(dict)`** A dict with a single key, that of the scanned user, which maps to a list of the users's friends. **Empty on error** | Send a request to Steam's API to retrieve a specified user's friends list |
| recursivescan | **`(str) steamid64`** - A 64 bit decimal Steam id; **`(int, Default = 2) recurselevel`** - The number of recursive scans to complete | **`(dict)`** A dict containing the starting steamid, then the friends contained in the original scan with the results of their scan. **Empty on error** | Scan a person's friends list, then scan for their friends' lists. This process repeats for every level of "`recurselevel`" |
<details>
<summary>Private steamrelationships.sr.SteamRelationships() methods</summary>
### Private `steamrelationships.sr.SteamRelationships()` methods
| Function | Params | Return Values | Description |
| :------: | :----- | :------------ | :---------- |
| __readjsonfile | **`(str) filepath`** - Path to json file | **`(dict)`** The contents of the json file. **Empty on error** | Read the specified json file for previous requests. Will create an "empty" json file if the specified file at the `filepath` doesn't exist |
| __checkrequests | **`(str) filename`** - filepath to requests log | **`(int)`** The number of requests in the last 24 hours. **`-1` on error**, `0` *on too many requests*, and `>1` if a valid number of requests | Check the requests log to make sure Steam's request limit hasn't been passed. Will create a file at `filepath` if it doesn't exist, also will *never go over 100,000 requests*, regardless of what `reqsafetybuffer` is |
| __getFriendsList | **`(str) steamid64`** - A Steam User's id, in the steamid64 format; **`(int, Default = 0) _retries`** - An internal value used to limit the number of retries after a timeout. Increments by one automatically on every timeout | **`(dict)`** The json representation of Steam's response. **Empty on error** | Send a request to the Steam Web API to get a user's friends list |
| __parseFriendsList | **`(dict) friendsdict`** - The return value of `__getFriendsList` | **`(list)`** The steamid64's of a user's friends. **Empty on error** | Parse a response from Steam and extract a user's friend's Steam IDs |
</details>
Example program
```python
#!/usr/bin/env -S python3 -i
import steamrelationships
from steamrelationships.constants import _Const
CONST = _Const()
if __name__ == "__main__":
print(f"Constants:\n\t> Max API Requests per Day: {CONST.STEAMAPI_MAXREQ}\n\t> Number of Nanoseconds In a Day: {CONST.DAY_IN_NANO}\n\t> .json File Indent: {CONST.JSON_INDENT}")
# Replace the XXXX's with your dev api key
steamuser: object = steamrelationships.SteamRelationships(webapikey="XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", reqsafetybuffer=0.01)
# Replace the XXXX's with the steam id of the guy you want to scan
bigscan: dict = steamuser.recursivescan("XXXXXXXXXXXXXXXXX", recurselevel=1)
littlescan: dict = steamuser.basicscan("XXXXXXXXXXXXXXXXX")
del steamuser
print(f'Original scanned user: {list(littlescan.keys())[0]}\nOriginal Friends: {littlescan[list(littlescan.keys())[0]]}')
totalscanned: int = 0
alreadyscanned: list = []
for scanned in bigscan.keys():
totalscanned += 1
alreadyscanned.append(scanned)
for friend in bigscan[scanned]:
if friend not in alreadyscanned:
totalscanned += 1
alreadyscanned.append(friend)
print(f"Total users found: {totalscanned}")
```
|