2024-06-12 22:16:40 +00:00
|
|
|
__version__ = "0.1.0"
|
|
|
|
from urllib.parse import urljoin
|
|
|
|
from typing import Optional, Union
|
|
|
|
import requests
|
|
|
|
|
|
|
|
|
|
|
|
# Exceptions
|
|
|
|
class LimitExceeded(Exception):
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
|
|
|
class QueryTimeout(Exception):
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
|
|
|
class BadRequest(Exception):
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
|
|
|
class ServerSeeker:
|
2024-07-10 16:37:30 +00:00
|
|
|
def __init__(self, api_key: str, endpoint: str = "https://api.serverseeker.net"):
|
2024-06-12 22:16:40 +00:00
|
|
|
self.endpoint = endpoint
|
|
|
|
self.session = requests.Session()
|
2024-07-10 16:37:30 +00:00
|
|
|
self.session.headers.update({"Authorization": "Bearer " + api_key})
|
2024-06-12 22:16:40 +00:00
|
|
|
self.session.headers.update({"User-Agent": f"ServerSeeker.py/{__version__} +https://git.magmaus3.eu.org/magmaus3/serverseeker.py"})
|
|
|
|
|
|
|
|
def server_info(self, ip: str, port: int = 25565) -> dict:
|
|
|
|
"""
|
|
|
|
Gives you info about a server.
|
|
|
|
"""
|
|
|
|
rq = self.session.post(
|
|
|
|
urljoin(self.endpoint, "/server_info"), json={"ip": ip, "port": port}
|
|
|
|
)
|
|
|
|
if not rq.ok:
|
|
|
|
if rq.status_code == 400:
|
|
|
|
raise BadRequest(rq.json()["error"])
|
|
|
|
elif rq.status_code == 429:
|
|
|
|
raise LimitExceeded(rq.json()["error"])
|
|
|
|
elif rq.status_code == 504:
|
|
|
|
raise QueryTimeout(rq.json()["error"])
|
|
|
|
|
|
|
|
return rq.json()
|
|
|
|
|
|
|
|
def servers(self,
|
|
|
|
country_code: Optional[str] = None,
|
|
|
|
max_players: Optional[int] = None,
|
2024-07-10 16:37:30 +00:00
|
|
|
online_players: Optional[Union[tuple[Union[int, str], Union[int, str]], int]] = None,
|
2024-06-12 22:16:40 +00:00
|
|
|
protocol: Optional[int] = None,
|
|
|
|
software: Optional[str] = None,
|
|
|
|
cracked: Optional[bool] = None,
|
|
|
|
description: Optional[str] = None,
|
|
|
|
asn: Optional[int] = None,
|
|
|
|
ignore_modded: Optional[bool] = None,
|
|
|
|
only_bungeespoofable: Optional[bool] = None
|
|
|
|
) -> list:
|
|
|
|
"""
|
|
|
|
Gives you a list of servers (with matching criteria). Limited to 100 results.
|
|
|
|
"""
|
|
|
|
rq = self.session.post(
|
2024-07-10 16:37:30 +00:00
|
|
|
urljoin(self.endpoint, "/servers"), json={
|
2024-06-12 22:16:40 +00:00
|
|
|
"asn": asn,
|
|
|
|
"country_code": country_code,
|
|
|
|
"cracked": cracked,
|
|
|
|
"description": description,
|
|
|
|
"ignore_modded": ignore_modded,
|
|
|
|
"max_players": max_players,
|
|
|
|
"online_players": online_players,
|
|
|
|
"only_bungeespoofable": only_bungeespoofable,
|
|
|
|
"protocol": protocol,
|
|
|
|
"software": software
|
|
|
|
}
|
|
|
|
)
|
|
|
|
if not rq.ok:
|
2024-07-10 16:37:30 +00:00
|
|
|
try:
|
|
|
|
if rq.status_code == 400:
|
|
|
|
raise BadRequest(rq.json()["error"])
|
|
|
|
elif rq.status_code == 429:
|
|
|
|
raise LimitExceeded(rq.json()["error"])
|
|
|
|
elif rq.status_code == 504:
|
|
|
|
raise QueryTimeout(rq.json()["error"])
|
|
|
|
except:
|
|
|
|
raise Exception(rq.text)
|
2024-06-12 22:16:40 +00:00
|
|
|
|
|
|
|
return rq.json()
|
|
|
|
|
|
|
|
def stats(self) -> dict:
|
|
|
|
"""
|
|
|
|
Gives you stats about ServerSeeker. Somewhat inaccurate.
|
|
|
|
"""
|
|
|
|
|
|
|
|
rq = self.session.get(
|
|
|
|
urljoin(self.endpoint, "/stats")
|
|
|
|
)
|
|
|
|
|
|
|
|
return rq.json()
|
|
|
|
|
|
|
|
def user_info(self) -> dict:
|
|
|
|
"""
|
|
|
|
Gives you information about your account (user id, username, avatar url).
|
|
|
|
Also gives you information about your rate limits.
|
|
|
|
Rate limits reset at midnight UTC.
|
|
|
|
"""
|
|
|
|
|
|
|
|
rq = self.session.post(
|
|
|
|
urljoin(self.endpoint, "/user_info")
|
|
|
|
)
|
|
|
|
if not rq.ok:
|
|
|
|
if rq.status_code == 400:
|
|
|
|
raise BadRequest(rq.json()["error"])
|
|
|
|
|
|
|
|
return rq.json()
|
|
|
|
|
2024-07-10 16:37:30 +00:00
|
|
|
def whereis(self, name: Optional[str] = None, uuid: Optional[str] = None) -> dict:
|
2024-06-12 22:16:40 +00:00
|
|
|
"""
|
|
|
|
Gives you a list of servers where a player was. Limited to 1000 results.
|
|
|
|
**Attention: You must use name OR uuid as your parameter, not both!**
|
|
|
|
"""
|
2024-07-10 16:37:30 +00:00
|
|
|
if name and not uuid:
|
|
|
|
data = {"name": name}
|
|
|
|
elif uuid and not name:
|
|
|
|
data = {"uuid": uuid}
|
|
|
|
else:
|
|
|
|
raise ValueError("You can only provide name or uuid, not both")
|
|
|
|
|
2024-06-12 22:16:40 +00:00
|
|
|
rq = self.session.post(
|
2024-07-10 16:37:30 +00:00
|
|
|
urljoin(self.endpoint, "/whereis"), json=data
|
2024-06-12 22:16:40 +00:00
|
|
|
)
|
2024-07-10 16:37:30 +00:00
|
|
|
|
2024-06-12 22:16:40 +00:00
|
|
|
if not rq.ok:
|
|
|
|
if rq.status_code == 400:
|
|
|
|
raise BadRequest(rq.json()["error"])
|
|
|
|
elif rq.status_code == 429:
|
|
|
|
raise LimitExceeded(rq.json()["error"])
|
|
|
|
elif rq.status_code == 504:
|
|
|
|
raise QueryTimeout(rq.json()["error"])
|
|
|
|
|
|
|
|
return rq.json()
|