Skip to content

Commit

Permalink
First commit
Browse files Browse the repository at this point in the history
  • Loading branch information
LeGeRyChEeSe committed Aug 29, 2024
0 parents commit 2401ce8
Show file tree
Hide file tree
Showing 15 changed files with 671 additions and 0 deletions.
9 changes: 9 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
.env
**\__pycache__
*.json
**.jpg
Dockerfile
venv
dev*.txt
ressources
.gitignore
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
.env
venv
**/__pycache__
*.json
dev*.txt
17 changes: 17 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
FROM python:3.12.5-alpine3.20

COPY requirements.txt /app/

WORKDIR /app

RUN apk update && \
apk add gcc musl-dev linux-headers libc-dev libffi-dev openssl-dev make && \
pip install --default-timeout=100 --upgrade pip && \
pip install --default-timeout=100 -r requirements.txt

ENV LANG=fr_FR.UTF-8
ENV LC_ALL=fr_FR.UTF-8

COPY . /app/

CMD ["python", "-u", "main.py"]
164 changes: 164 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
<h1 align='center'>Lansbot</h1>
<p align="center">
<img src="https://github.com/LeGeRyChEeSe/LanPlay-DiscordBot/blob/main/lansbot.jpg?raw=true" align="center" height=205 alt="Lansbot" />
</p>
<p align="center">
<img src='https://visitor-badge.laobi.icu/badge?page_id=LeGeRyChEeSe.Lansbot', alt='Visitors'/>
<a href="https://github.com/LeGeRyChEeSe/LanPlay-DiscordBot/stargazers">
<img src="https://img.shields.io/github/stars/LeGeRyChEeSe/LanPlay-DiscordBot" alt="Stars"/>
</a>
<a href="https://github.com/LeGeRyChEeSe/LanPlay-DiscordBot/issues">
<img src="https://img.shields.io/github/issues/LeGeRyChEeSe/LanPlay-DiscordBot" alt="Issues"/>
</a>

<p align="center">
A Discord bot that provides information on <a href="http://lan-play.com">LAN Play</a> servers, players, and games played.
<p align="center">

# Table of Contents
- [Get API Key](#get-api-key)
- [Create a Bot Account](#create-a-bot-account)
- [Invite the bot into your server](#invite-the-bot-into-your-server)
- [Run the Bot](#run-the-bot)
- [Commands Available](#commands-available)
- [Contributing](#contributing)
- [License](#license)
- [Acknowledgements](#acknowledgements)
- [Star History](#star-history)


## Get API Key

To use the LanPlay package you will need a specific, non-transferable API key that can be retrieved from <a href="http://www.lan-play.com">LanPlay</a>.<br>

Please follow these steps :

1. Open a Web Browser and go to http://www.lan-play.com

2. Open a Console Mode (<b>Ctrl + Shift + C</b> or <b>F12</b> should work, or Google is your friend to find how to access the Console Mode 🫠)

3. Go to `Network` tab and refresh the current page

4. Search a line named `getMonitors` and click on it

5. Open the `Payload` tab

6. Copy the `api_key` value and store it in safe location for the [Run the Bot](#run-the-bot) step.

## Create a Bot Account

1. Make sure you’re logged on to the [Discord website](https://discord.com/).

2. Navigate to the [Discord Application](https://discord.com/developers/applications) for developers.

3. Click on the `New Application` button.

4. Give the application a name and click `Create`.

5. Navigate to the `Bot` tab to configure it.

6. Make sure that `Public Bot` is ticked if you want others to invite your bot.

- You should also make sure that `Require OAuth2 Code Grant` is unchecked.

7. Copy the token using the `Copy` button and store it in safe location for the [Run the Bot](#run-the-bot) step.

- <b>This is not the Client Secret at the General Information page.</b>

> It should be worth noting that this token is essentially your bot’s password. You should never share this with someone else. In doing so, someone can log in to your bot and do malicious things, such as leaving servers, ban all members inside a server, or pinging everyone maliciously.
>
> The possibilities are endless, so do not share this token.
>
> If you accidentally leaked your token, click the `Regenerate` button as soon as possible. This revokes your old token and re-generates a new one. Now you need to use the new token to login.

## Invite the bot into your server

1. Navigate to the [Discord Application](https://discord.com/developers/applications) for developers.

2. Open the App you previously created for the Bot.

3. Navigate to `OAuth2` tab.

4. Scroll down and in `OAuth2 URL Generator` -> `SCOPES`, tick these boxes:

- `bot`
- `applications.commands`

5. Scroll down and in `BOT PERMISSIONS`, tick these boxes:

- `Manage Expressions`
- `Create Expressions`
- `Send Messages`
- `Send Messages in Threads`
- `Embed Links`
- `Read Message History`

6. Make sure that `INTEGRATION TYPE` value is `Guild Install`.

7. Copy/Paste the `GENERATED URL` at bottom to a new Browser Tab and add it to your Discord Server.

## Run the Bot

- Download [Docker](https://www.docker.com) and install it on your computer.

- Make sure you got both [api_key](#get-api-key) and [token](#create-a-bot-account) values, and [invited the bot to your server](#invite-the-bot-into-your-server).

- Open a <b>Windows Terminal</b> and execute the following command to run the Discord Bot:

```docker
docker run -e API_LAN_KEY=<your_lan_api_key> -e TOKEN=<your_discord_token> LeGeRyChEeSe/lanplay-discordbot:latest
```

- If you want the Discord Bot running in background:

```docker
docker run -d -e API_LAN_KEY=<your_lan_api_key> -e TOKEN=<your_discord_token> LeGeRyChEeSe/lanplay-discordbot:latest
```

> Replace `<your_lan_api_key>` with your [`api_key`](#get-api-key) and replace `<your_discord_token>` with your [`token`](#create-a-bot-account).
## Commands Available

| Command | Input | Output | Permission |
| :-----: | :--------: | :----: | :--------: |
| `/help` | `None` | ![Help Menu](https://github.com/LeGeRyChEeSe/LanPlay-DiscordBot/blob/main/ressources/help.png?raw=true) | `Everybody` |
| `/lan` | <i>select a server</i> | ![LanPlay Server Infos](https://github.com/LeGeRyChEeSe/LanPlay-DiscordBot/blob/main/ressources/lan.png?raw=true) | `Everybody` |
| `/add` | `server`<br><i>e.g. 'tekn0.net:11451'</i> | ![Status of server addition](https://github.com/LeGeRyChEeSe/LanPlay-DiscordBot/blob/main/ressources/add.png?raw=true) | `Admin` |
| `/delete` | `server`<br><i>e.g. 'tekn0.net:11451'</i> | ![Status of server deletion](https://github.com/LeGeRyChEeSe/LanPlay-DiscordBot/blob/main/ressources/delete.png?raw=true) | `Admin` |

## Contributing

Any contributions you make are **greatly appreciated**.

1. Fork the Project
2. Create your Feature Branch (`git checkout -b feature/NewFeature`)
3. Commit your Changes (`git commit -m 'Add some NewFeature'`)
4. Push to the Branch (`git push origin feature/NewFeature`)
5. Open a Pull Request


<i>Thanks to every [contributors](https://github.com/LeGeRyChEeSe/LanPlay-DiscordBot/graphs/contributors) who have contributed in this project.</i>

## License

Distributed under the MIT License. See [LICENSE](https://github.com/LeGeRyChEeSe/LanPlay-DiscordBot/blob/main/LICENSE) for more information.

## Acknowledgements

Shoutout to <b>LizardByte</b> for the Sunshine repo: https://github.com/LizardByte/Sunshine

Shoutout to <b>itsmikethetech</b> for the Virtual Display Driver repo: https://github.com/itsmikethetech/Virtual-Display-Driver

Thanks to <b>Cynary</b> for the Sunshine Virtual Monitor scripts: https://github.com/Cynary/sunshine-virtual-monitor

Shoutout to <b>JosefNemec</b> for Playnite: https://github.com/JosefNemec/Playnite

Shoutout to <b>Nonary</b> for the PlayNiteWatcher script: https://github.com/Nonary/PlayNiteWatcher

## Star History

[![Star History Chart](https://api.star-history.com/svg?repos=LeGeRyChEeSe/LanPlay-DiscordBot&type=Date)](https://star-history.com/#LeGeRyChEeSe/LanPlay-DiscordBot&Date)

----

Author/Maintainer: [Garoh](https://github.com/LeGeRyChEeSe/) | Discord: garohrl
Empty file added __init__.py
Empty file.
170 changes: 170 additions & 0 deletions functions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
import requests
import disnake
import json
import os
import typing
from datetime import datetime
from decouple import config
from disnake.ext import commands
from gql import gql, Client
from gql.transport.aiohttp import AIOHTTPTransport

list_all_games_url = "https://tinfoil.media/Title/ApiJson/"
monitors_url = "https://api.uptimerobot.com/v2/getMonitors"
API_LAN_KEY = config('API_LAN_KEY')
lan_menu_url = "http://lan-play.com"
lan_config_url = "http://lan-play.com/install-switch"
image_lanplay_url = "http://lan-play.com/img/logo.f64272e3.png"


async def getLanPlayInfos(lan_server_url: str) -> typing.Optional[typing.Dict]:
transport = AIOHTTPTransport(url=lan_server_url)
async with Client(
transport=transport,
) as session:

query = gql("""
query getUsers {
room {
contentId
hostPlayerName
nodeCountMax
nodeCount
advertiseData
nodes {
playerName
}
}
serverInfo {
online
idle
}
}
""")

try:
result = await session.execute(query)
except:
return
else:
if hasRooms(result):
list_games = matchGame(result["room"])
if list_games and len(list_games) > 0:
for room in result["room"]:
for game in list_games:
if room["contentId"].lower() == game["id"].lower():
gameName = game["name"][game["name"].find(
'\"\u003e') + 2: game["name"].find('\u003c/a\u003e')]
iconUrl = game["icon"][game["icon"].find(
'url') + 4: game["icon"].find(')\"')]
room["gameName"] = gameName
room["iconUrl"] = iconUrl
return result


async def getNumberOfRooms(lan_server_url: str) -> int:
transport = AIOHTTPTransport(url=lan_server_url)
async with Client(
transport=transport,
) as session:

query = gql("""
query getUsers {
room {
nodeCount
}
}
""")

result = await session.execute(query)
return len(result["room"])


def hasRooms(server: typing.Dict) -> bool:
return isinstance(server.get("room", []), list) and bool(server["room"])


def matchGame(rooms: list) -> list:
list_all_games = requests.get(list_all_games_url)
if not list_all_games.ok:
return []

list_all_games = list_all_games.json()
content_ids = set([room["contentId"].lower() for room in rooms])
list_games = [game for game in list_all_games["data"]
if game["id"].lower() in content_ids]

for game in list_games:
if game["id"].lower() == "ffffffffffffffff":
game["id"] = "0100B04011742000"

return list_games


def getLanServers() -> typing.Dict:
response = requests.post(monitors_url, json={
"api_key": API_LAN_KEY, "format": "json", "all_time_uptime_ratio": 1})
return response.json()


def getLocalization(bot: commands.InteractionBot, key: str, locale: disnake.Locale, **kwargs) -> typing.Optional[str]:
text_localized = bot.i18n.get(key).get(str(locale))

for k, value in kwargs.items():
k_formatted = "{" + k + "}"
text_localized = text_localized.replace(k_formatted, str(value))

return text_localized if text_localized else None


def load_lan_servers(filename: str = 'lan_servers.json') -> typing.Optional[typing.Union[typing.List[typing.Dict[str, typing.Union[str, int]]], list]]:
if os.path.exists(filename):
with open(filename, 'r') as file:
return json.load(file)
return []


def save_lan_servers(lan_servers: typing.List[typing.Dict[str, typing.Union[str, int]]], filename: str = 'lan_servers.json') -> None:
with open(filename, 'w') as file:
json.dump(lan_servers, file, indent=4)


def create_custom_server(friendly_name: str) -> typing.Dict[str, typing.Union[str, int]]:
return {
"id": friendly_name.split(':')[0], # Utiliser la partie avant les ':'
"friendly_name": friendly_name,
"url": f"http://{friendly_name}/info",
"type": 1,
"sub_type": "",
"keyword_type": "None",
"keyword_case_type": 0,
"keyword_value": "",
"http_username": "",
"http_password": "",
"port": "",
"interval": 300,
"timeout": 30,
"status": 9,
"create_datetime": int(datetime.now().timestamp()), # Timestamp actuel
"all_time_uptime_ratio": "99.999"
}


def add_custom_server(temp_lan_servers: typing.List[typing.Dict[str, typing.Union[str, int]]], friendly_name, lan_servers=None) -> bool:
custom_server = create_custom_server(friendly_name)

for server in temp_lan_servers:
if custom_server["id"] == server["id"]:
return False

if lan_servers:
for server in lan_servers["monitors"]:
if custom_server["friendly_name"] == server["friendly_name"]:
return False

temp_lan_servers.append(custom_server)
return True


def delete_custom_server(lan_servers: typing.List[typing.Dict[str, typing.Union[str, int]]], friendly_name: str) -> typing.List[typing.Dict[str, typing.Union[str, int]]]:
return [server for server in lan_servers if server.get("friendly_name") != friendly_name]
Binary file added lansbot.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading

0 comments on commit 2401ce8

Please sign in to comment.