Switch to LF line endings

This commit is contained in:
archfan 2019-08-29 21:54:08 -04:00 committed by GitHub
parent 054970daa2
commit 813701c5db
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 428 additions and 430 deletions

25
API.md
View File

@ -1,13 +1,12 @@
## API
`discordmt` offers a simple API which other mods can use to listen to and send messages with Discord.
It does not expose the command interface or logins to the API, and `discord.register_on_message` events will *not* recieve login information.
### `discord.send(message [, optional id])`
Sends `message` to Discord.
This function makes an HTTP request; therefore the sending of large volumes of data might be better grouped into a single request. **Do note that Discord limits messages to 2,000 characters, and the relay automatically cuts off messages.**
The optional `id` parameter specifies a specific Discord user to send the message to.
### `discord.register_on_message(function(name, message))`
Adds a function to `discord.registered_on_messages`, which are called every time a message is received from Discord, excluding logins. `name` is by default the Discord username of the user who sent the message (excluding the discriminator) and `message` is the message content. This function should be called on startup.
## API
`discordmt` offers a simple API which other mods can use to listen to and send messages with Discord.
It does not expose the command interface or logins to the API, and `discord.register_on_message` events will *not* recieve login information.
### `discord.send(message)`
Sends `message` to Discord.
This function makes an HTTP request; therefore the sending of large volumes of data might be better grouped into a single request. **Do note that Discord limits messages to 2,000 characters, and the relay automatically cuts off messages.**
### `discord.register_on_message(function(name, message))`
Adds a function to `discord.registered_on_messages`, which are called every time a message is received from Discord, excluding logins. `name` is by default the Discord username of the user who sent the message (excluding the discriminator) and `message` is the message content. This function should be called on startup.

View File

@ -1,21 +1,21 @@
MIT License
Copyright (c) 2019 archfan7411
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
MIT License
Copyright (c) 2019 archfan7411
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

118
README.md
View File

@ -1,59 +1,59 @@
## Minetest-Discord Relay `[discordmt]`
A feature-filled Discord relay for Minetest, supporting:
- Relaying server chat to Discord, and Discord chat to the server
- Allowing anyone to get the server status via a command
- Logging into the server from Discord *(configurable)*
- Running commands from Discord *(configurable)*
- A simple API
## Great! How do I use it?
Easy! `discordmt` works by running a Python program which converses with a serverside mod using HTTP requests. Don't have or want Python? No problem! Binaries are also available.
If you want to run the source, however, Python 3.6.3+, `aiohttp` 3.5+ and `discord.py` 1.2.0+ are required.
### Basic setup
1. Download the mod and binary executable (or the source code and its dependencies.)
2. Create an application at the [Discord Developer Dashboard](https://discordapp.com/developers/applications/) and enable it as a bot (in the Bot tab.)
3. Copy the token from your newly-created bot, and use it to finish setting up `relay.conf`.
Example `relay.conf`: *(The token shown below has been regenerated)*
```
[BOT]
token = NjEwODk0MDU4ODY4NzAzMjMz.XVL5dA.8j8d2XN8_5UwRheG91P2XksYDoM
command_prefix = !
[RELAY]
port = 8080
channel_id = 576585506658189332
allow_logins = true
clean_invites = true
use_nicknames = true
```
4. Set `discord.port` in your `minetest.conf` to match the port you used in `relay.conf`. You may also set `discord.text_color` to a hex color string if you'd like to color relayed messages from Discord.
Example `minetest.conf` excerpt:
```
discord.port = 8080
discord.text_color = #a7a7a7
```
*(Side note: The port must be set in both `relay.conf` and `minetest.conf` because users may decide to run the relay in a different location than the mod, or to run multiple relays/servers at once.)*
5. Run the relay and, when you're ready, the Minetest server. The relay may be left up even when the server goes down, or may run continuously between several server restarts, for maximum convenience.
## Frequently Asked Questions
**Q: I just want a normal relay. Can I disable logins?**
A: Yep! Just set `allow_logins = false` in `relay.conf`.
**Q: Do I need to re-login after a server restart, like with the IRC mod?**
A: Nope, logins persist as long as the relay is up.
**Q: I'm getting an HTTP error - it says the server can't be found?**
A: Make sure the relay is running and that you've configured the correct port in both `minetest.conf` and `relay.conf`.
## Minetest-Discord Relay `[discordmt]`
A feature-filled Discord relay for Minetest, supporting:
- Relaying server chat to Discord, and Discord chat to the server
- Allowing anyone to get the server status via a command
- Logging into the server from Discord *(configurable)*
- Running commands from Discord *(configurable)*
- A simple API
## Great! How do I use it?
Easy! `discordmt` works by running a Python program which converses with a serverside mod using HTTP requests. Don't have or want Python? No problem! Binaries are also available.
If you want to run the source, however, Python 3.6.3+, `aiohttp` 3.5+ and `discord.py` 1.2.0+ are required.
### Basic setup
1. Download the mod and binary executable (or the source code and its dependencies.)
2. Create an application at the [Discord Developer Dashboard](https://discordapp.com/developers/applications/) and enable it as a bot (in the Bot tab.)
3. Copy the token from your newly-created bot, and use it to finish setting up `relay.conf`.
Example `relay.conf`: *(The token shown below has been regenerated)*
```
[BOT]
token = NjEwODk0MDU4ODY4NzAzMjMz.XVL5dA.8j8d2XN8_5UwRheG91P2XksYDoM
command_prefix = !
[RELAY]
port = 8080
channel_id = 576585506658189332
allow_logins = true
clean_invites = true
use_nicknames = true
```
4. Set `discord.port` in your `minetest.conf` to match the port you used in `relay.conf`. You may also set `discord.text_color` to a hex color string if you'd like to color relayed messages from Discord.
Example `minetest.conf` excerpt:
```
discord.port = 8080
discord.text_color = #a7a7a7
```
*(Side note: The port must be set in both `relay.conf` and `minetest.conf` because users may decide to run the relay in a different location than the mod, or to run multiple relays/servers at once.)*
5. Run the relay and, when you're ready, the Minetest server. The relay may be left up even when the server goes down, or may run continuously between several server restarts, for maximum convenience.
## Frequently Asked Questions
**Q: I just want a normal relay. Can I disable logins?**
A: Yep! Just set `allow_logins = false` in `relay.conf`.
**Q: Do I need to re-login after a server restart, like with the IRC mod?**
A: Nope, logins persist as long as the relay is up.
**Q: I'm getting an HTTP error - it says the server can't be found?**
A: Make sure the relay is running and that you've configured the correct port in both `minetest.conf` and `relay.conf`.

280
init.lua
View File

@ -1,140 +1,140 @@
local http = minetest.request_http_api()
local settings = minetest.settings
local port = settings:get('discord.port') or 8080
local timeout = 10
discord = {}
discord.text_colorization = settings:get('discord.text_color') or '#ffffff'
discord.registered_on_messages = {}
discord.register_on_message = function(func)
table.insert(discord.registered_on_messages, func)
end
local old_chat_send_all = minetest.chat_send_all
discord.handle_response = function(response)
local data = response.data
if data == '' or data == nil then
return
end
local data = minetest.parse_json(response.data)
if not data then
return
end
if data.messages then
for _, message in pairs(data.messages) do
for _, func in pairs(discord.registered_on_messages) do
func(message.author, message.content)
end
local msg = ('<%s@Discord> %s'):format(message.author, message.content)
old_chat_send_all(minetest.colorize(discord.text_colorization, msg))
minetest.log('[Discord] Message: '..msg)
end
end
if data.commands then
local commands = minetest.registered_chatcommands
for _, v in pairs(data.commands) do
if commands[v.command] then
if minetest.get_ban_description(v.name) ~= '' then
discord.send('You cannot run commands because you are banned.', v.context or nil)
return
end
-- Check player privileges
local required_privs = commands[v.command].privs or {}
local player_privs = minetest.get_player_privs(v.name)
for priv, value in pairs(required_privs) do
if player_privs[priv] ~= value then
discord.send('Insufficient privileges.', v.context or nil)
return
end
end
local old_chat_send_player = minetest.chat_send_player
minetest.chat_send_player = function(name, message)
old_chat_send_player(name, message)
if name == v.name then
discord.send(message, v.context or nil)
end
end
success, ret_val = commands[v.command].func(v.name, v.params or '')
if ret_val then
discord.send(ret_val, v.context or nil)
end
minetest.chat_send_player = old_chat_send_player
else
discord.send(('Command not found: `%s`'):format(v.command), v.context or nil)
end
end
end
if data.logins then
local auth = minetest.get_auth_handler()
for _, v in pairs(data.logins) do
local authdata = auth.get_auth(v.username)
local result = false
if authdata then
result = minetest.check_password_entry(v.username, authdata.password, v.password)
end
local request = {
type = 'DISCORD_LOGIN_RESULT',
user_id = v.user_id,
username = v.username,
success = result
}
http.fetch({
url = 'localhost:'..tostring(port),
timeout = timeout,
post_data = minetest.write_json(request)
}, discord.handle_response)
end
end
end
discord.send = function(message, id)
local data = {
type = 'DISCORD-RELAY-MESSAGE',
content = minetest.strip_colors(message)
}
if id then
data['context'] = id
end
http.fetch({
url = 'localhost:'..tostring(port),
timeout = timeout,
post_data = minetest.write_json(data)
}, function(_) end)
end
minetest.chat_send_all = function(message)
old_chat_send_all(message)
discord.send(message)
end
minetest.register_on_chat_message(function(name, message)
discord.send(('<%s> %s'):format(name, message))
end)
local timer = 0
minetest.register_globalstep(function(dtime)
if dtime then
timer = timer + dtime
if timer > 0.2 then
http.fetch({
url = 'localhost:'..tostring(port),
timeout = timeout,
post_data = minetest.write_json({
type = 'DISCORD-REQUEST-DATA'
})
}, discord.handle_response)
timer = 0
end
end
end)
minetest.register_on_shutdown(function()
discord.send('*** Server shutting down...')
end)
discord.send('*** Server started!')
local http = minetest.request_http_api()
local settings = minetest.settings
local port = settings:get('discord.port') or 8080
local timeout = 10
discord = {}
discord.text_colorization = settings:get('discord.text_color') or '#ffffff'
discord.registered_on_messages = {}
discord.register_on_message = function(func)
table.insert(discord.registered_on_messages, func)
end
local old_chat_send_all = minetest.chat_send_all
discord.handle_response = function(response)
local data = response.data
if data == '' or data == nil then
return
end
local data = minetest.parse_json(response.data)
if not data then
return
end
if data.messages then
for _, message in pairs(data.messages) do
for _, func in pairs(discord.registered_on_messages) do
func(message.author, message.content)
end
local msg = ('<%s@Discord> %s'):format(message.author, message.content)
old_chat_send_all(minetest.colorize(discord.text_colorization, msg))
minetest.log('[Discord] Message: '..msg)
end
end
if data.commands then
local commands = minetest.registered_chatcommands
for _, v in pairs(data.commands) do
if commands[v.command] then
if minetest.get_ban_description(v.name) ~= '' then
discord.send('You cannot run commands because you are banned.', v.context or nil)
return
end
-- Check player privileges
local required_privs = commands[v.command].privs or {}
local player_privs = minetest.get_player_privs(v.name)
for priv, value in pairs(required_privs) do
if player_privs[priv] ~= value then
discord.send('Insufficient privileges.', v.context or nil)
return
end
end
local old_chat_send_player = minetest.chat_send_player
minetest.chat_send_player = function(name, message)
old_chat_send_player(name, message)
if name == v.name then
discord.send(message, v.context or nil)
end
end
success, ret_val = commands[v.command].func(v.name, v.params or '')
if ret_val then
discord.send(ret_val, v.context or nil)
end
minetest.chat_send_player = old_chat_send_player
else
discord.send(('Command not found: `%s`'):format(v.command), v.context or nil)
end
end
end
if data.logins then
local auth = minetest.get_auth_handler()
for _, v in pairs(data.logins) do
local authdata = auth.get_auth(v.username)
local result = false
if authdata then
result = minetest.check_password_entry(v.username, authdata.password, v.password)
end
local request = {
type = 'DISCORD_LOGIN_RESULT',
user_id = v.user_id,
username = v.username,
success = result
}
http.fetch({
url = 'localhost:'..tostring(port),
timeout = timeout,
post_data = minetest.write_json(request)
}, discord.handle_response)
end
end
end
discord.send = function(message, id)
local data = {
type = 'DISCORD-RELAY-MESSAGE',
content = minetest.strip_colors(message)
}
if id then
data['context'] = id
end
http.fetch({
url = 'localhost:'..tostring(port),
timeout = timeout,
post_data = minetest.write_json(data)
}, function(_) end)
end
minetest.chat_send_all = function(message)
old_chat_send_all(message)
discord.send(message)
end
minetest.register_on_chat_message(function(name, message)
discord.send(('<%s> %s'):format(name, message))
end)
local timer = 0
minetest.register_globalstep(function(dtime)
if dtime then
timer = timer + dtime
if timer > 0.2 then
http.fetch({
url = 'localhost:'..tostring(port),
timeout = timeout,
post_data = minetest.write_json({
type = 'DISCORD-REQUEST-DATA'
})
}, discord.handle_response)
timer = 0
end
end
end)
minetest.register_on_shutdown(function()
discord.send('*** Server shutting down...')
end)
discord.send('*** Server started!')

View File

@ -1,9 +1,9 @@
[BOT]
token = <Discord bot token goes here>
command_prefix = !
[RELAY]
port = 8080
channel_id = <Discord channel ID goes here>
allow_logins = true
clean_invites = true
[BOT]
token = <Discord bot token goes here>
command_prefix = !
[RELAY]
port = 8080
channel_id = <Discord channel ID goes here>
allow_logins = true
clean_invites = true
use_nicknames = true

377
server.py
View File

@ -1,189 +1,188 @@
#!/usr/bin/env python3
import sys
from aiohttp import web
import aiohttp
import discord
from discord.ext import commands
import asyncio
import json
import time
import configparser
config = configparser.ConfigParser()
config.read('relay.conf')
class Queue():
def __init__(self):
self.queue = []
def add(self, item):
self.queue.append(item)
def get(self):
if len(self.queue) >=1:
item = self.queue[0]
del self.queue[0]
return item
else:
return None
def get_all(self):
items = self.queue
self.queue = []
return items
def isEmpty(self):
return len(self.queue) == 0
def clean_invites(string):
return ' '.join([word for word in string.split() if not ('discord.gg' in word) and not ('discordapp.com/invite' in word)])
outgoing_msgs = Queue()
command_queue = Queue()
login_queue = Queue()
prefix = config['BOT']['command_prefix']
bot = commands.Bot(command_prefix=prefix, help_command=None)
channel_id = int(config['RELAY']['channel_id'])
connected = False
port = int(config['RELAY']['port'])
token = config['BOT']['token']
logins_allowed = True if config['RELAY']['allow_logins'] == 'true' else False
do_clean_invites = True if config['RELAY']['clean_invites'] == 'true' else False
do_use_nicknames = True if config['RELAY']['use_nicknames'] == 'true' else False
last_request = 0
channel = None
authenticated_users = {}
def check_timeout():
return time.time() - last_request <= 1
async def handle(request):
global last_request
last_request = time.time()
text = await request.text()
try:
data = json.loads(text)
if data['type'] == 'DISCORD-RELAY-MESSAGE':
msg = discord.utils.escape_mentions(data['content'])[0:2000]
if 'context' in data.keys():
id = int(data['context'])
user = bot.get_user(id)
if user is not None:
await user.send(msg)
else:
print('unyay')
else:
await channel.send(msg)
return web.Response(text = 'Acknowledged') # discord.send should NOT block extensively on the Lua side
if data['type'] == 'DISCORD_LOGIN_RESULT':
user = bot.get_user(int(data['user_id']))
if user is not None:
if data['success'] is True:
authenticated_users[int(data['user_id'])] = data['username']
await user.send('Login successful.')
else:
await user.send('Login failed.')
except:
pass
response = json.dumps({
'messages' : outgoing_msgs.get_all(),
'commands' : command_queue.get_all(),
'logins' : login_queue.get_all()
})
return web.Response(text = response)
app = web.Application()
app.add_routes([web.get('/', handle),
web.post('/', handle)])
@bot.event
async def on_ready():
global connected
if not connected:
connected = True
global channel
channel = await bot.fetch_channel(channel_id)
@bot.event
async def on_message(message):
global outgoing_msgs
if check_timeout():
if (message.channel.id == channel_id) and (message.author.id != bot.user.id):
msg = {
'author': message.author.name if not do_use_nicknames else message.author.display_name,
'content': message.content.replace('\n', '/')
}
if do_clean_invites:
msg['content'] = clean_invites(msg['content'])
if msg['content'] != '':
outgoing_msgs.add(msg)
await bot.process_commands(message)
@bot.command(help='Runs an ingame command from Discord.')
async def cmd(ctx, command, *, args=''):
if ((ctx.channel.id != channel_id) and ctx.guild is not None) or not logins_allowed:
return
if ctx.author.id not in authenticated_users.keys():
await ctx.send('Not logged in.')
return
command = {
'name': authenticated_users[ctx.author.id],
'command': command,
'params': args.replace('\n', '')
}
if ctx.guild is None:
command['context'] = str(ctx.author.id)
command_queue.add(command)
@bot.command(help='Logs into your ingame account from Discord so you can run commands. You should only run this command in DMs with the bot.')
async def login(ctx, username, password=''):
if not check_timeout() or not logins_allowed:
return
if ctx.guild is not None:
await ctx.send(ctx.author.mention+' You\'ve quite possibly just leaked your password; it is advised that you change it at once.\n*This message will be automatically deleted*', delete_after = 10)
return
login_queue.add({
'username' : username,
'password' : password,
'user_id' : str(ctx.author.id)
})
@bot.command(help='Lists connected players and server information.')
async def status(ctx, *, args=None):
if not check_timeout():
return
if ((ctx.channel.id != channel_id) and ctx.guild is not None):
return
data = {
'name': 'discord_relay',
'command': 'status',
'params': '',
}
if ctx.guild is None:
data['context'] = str(ctx.author.id)
command_queue.add(data)
async def runServer():
runner = web.AppRunner(app)
await runner.setup()
site = web.TCPSite(runner, 'localhost', port)
await site.start()
async def runBot():
await bot.login(token)
await bot.connect()
try:
print('='*37+'\nStarting relay. Press Ctrl-C to exit.\n'+'='*37)
loop = asyncio.get_event_loop()
futures = asyncio.gather(runBot(), runServer())
loop.run_until_complete(futures)
except (KeyboardInterrupt, SystemExit):
sys.exit()
import sys
from aiohttp import web
import aiohttp
import discord
from discord.ext import commands
import asyncio
import json
import time
import configparser
config = configparser.ConfigParser()
config.read('relay.conf')
class Queue():
def __init__(self):
self.queue = []
def add(self, item):
self.queue.append(item)
def get(self):
if len(self.queue) >=1:
item = self.queue[0]
del self.queue[0]
return item
else:
return None
def get_all(self):
items = self.queue
self.queue = []
return items
def isEmpty(self):
return len(self.queue) == 0
def clean_invites(string):
return ' '.join([word for word in string.split() if not ('discord.gg' in word) and not ('discordapp.com/invite' in word)])
outgoing_msgs = Queue()
command_queue = Queue()
login_queue = Queue()
prefix = config['BOT']['command_prefix']
bot = commands.Bot(command_prefix=prefix, help_command=None)
channel_id = int(config['RELAY']['channel_id'])
connected = False
port = int(config['RELAY']['port'])
token = config['BOT']['token']
logins_allowed = True if config['RELAY']['allow_logins'] == 'true' else False
do_clean_invites = True if config['RELAY']['clean_invites'] == 'true' else False
do_use_nicknames = True if config['RELAY']['use_nicknames'] == 'true' else False
last_request = 0
channel = None
authenticated_users = {}
def check_timeout():
return time.time() - last_request <= 1
async def handle(request):
global last_request
last_request = time.time()
text = await request.text()
try:
data = json.loads(text)
if data['type'] == 'DISCORD-RELAY-MESSAGE':
msg = discord.utils.escape_mentions(data['content'])[0:2000]
if 'context' in data.keys():
id = int(data['context'])
user = bot.get_user(id)
if user is not None:
await user.send(msg)
else:
print('unyay')
else:
await channel.send(msg)
return web.Response(text = 'Acknowledged') # discord.send should NOT block extensively on the Lua side
if data['type'] == 'DISCORD_LOGIN_RESULT':
user = bot.get_user(int(data['user_id']))
if user is not None:
if data['success'] is True:
authenticated_users[int(data['user_id'])] = data['username']
await user.send('Login successful.')
else:
await user.send('Login failed.')
except:
pass
response = json.dumps({
'messages' : outgoing_msgs.get_all(),
'commands' : command_queue.get_all(),
'logins' : login_queue.get_all()
})
return web.Response(text = response)
app = web.Application()
app.add_routes([web.get('/', handle),
web.post('/', handle)])
@bot.event
async def on_ready():
global connected
if not connected:
connected = True
global channel
channel = await bot.fetch_channel(channel_id)
@bot.event
async def on_message(message):
global outgoing_msgs
if check_timeout():
if (message.channel.id == channel_id) and (message.author.id != bot.user.id):
msg = {
'author': message.author.name if not do_use_nicknames else message.author.display_name,
'content': message.content.replace('\n', '/')
}
if do_clean_invites:
msg['content'] = clean_invites(msg['content'])
if msg['content'] != '':
outgoing_msgs.add(msg)
await bot.process_commands(message)
@bot.command(help='Runs an ingame command from Discord.')
async def cmd(ctx, command, *, args=''):
if ((ctx.channel.id != channel_id) and ctx.guild is not None) or not logins_allowed:
return
if ctx.author.id not in authenticated_users.keys():
await ctx.send('Not logged in.')
return
command = {
'name': authenticated_users[ctx.author.id],
'command': command,
'params': args.replace('\n', '')
}
if ctx.guild is None:
command['context'] = str(ctx.author.id)
command_queue.add(command)
@bot.command(help='Logs into your ingame account from Discord so you can run commands. You should only run this command in DMs with the bot.')
async def login(ctx, username, password=''):
if not check_timeout() or not logins_allowed:
return
if ctx.guild is not None:
await ctx.send(ctx.author.mention+' You\'ve quite possibly just leaked your password; it is advised that you change it at once.\n*This message will be automatically deleted*', delete_after = 10)
return
login_queue.add({
'username' : username,
'password' : password,
'user_id' : str(ctx.author.id)
})
@bot.command(help='Lists connected players and server information.')
async def status(ctx, *, args=None):
if not check_timeout():
return
if ((ctx.channel.id != channel_id) and ctx.guild is not None):
return
data = {
'name': 'discord_relay',
'command': 'status',
'params': '',
}
if ctx.guild is None:
data['context'] = str(ctx.author.id)
command_queue.add(data)
async def runServer():
runner = web.AppRunner(app)
await runner.setup()
site = web.TCPSite(runner, 'localhost', port)
await site.start()
async def runBot():
await bot.login(token)
await bot.connect()
try:
print('='*37+'\nStarting relay. Press Ctrl-C to exit.\n'+'='*37)
loop = asyncio.get_event_loop()
futures = asyncio.gather(runBot(), runServer())
loop.run_until_complete(futures)
except (KeyboardInterrupt, SystemExit):
sys.exit()

View File

@ -1,2 +1,2 @@
discord.port (Port to run the relay on.) int 8080
discord.port (Port to run the relay on.) int 8080
discord.text_color (Custom color for relayed messages.) string #ffffff