Discord - autokick to red/blue voicechannel  (Read 4673 times)

Plakatowy

  • Full Member 
  • *
  • Posts: 97
  • Country: pl
  • Buritto
    • Biegan
Discord - autokick to red/blue voicechannel
« on: September 14, 2024, 18:20 »
Hi, during the last talk on Discord when there were 10 people (!), someone mentioned that on one of the UT2004 servers there is such a functionality that after starting the next arena it automatically "kick" the Discord user/UT2004 player to the appropriate "blue" or "red" channel ...

Even though there were 10 of us at the time, there was a bit of chaos because half of the people were on a different team. Unfortunately, I don't know which of the 10 people mentioned it, but ... maybe one of you remembers such a solution on another UT2004 server (what server it was)? Or maybe you know how to implement something like that in Discord? Maybe one of you would like to help? I don't know about "these things", but it seems to me that the easiest way would be to connect this website to a Discord bot.

I know that few people from our community use Discord, but those who use (have used) know that it works, there is more fun and satisfaction from playing on VCTF. This solution would make using Discord much more enjoyable for our community.

PS: I want burrito :'(

Piglet

  • 1337
  • *
  • Posts: 3255
  • Country: gb
Re: Discord - autokick to red/blue voicechannel
« Reply #1 on: September 14, 2024, 19:23 »
I wrote a solution to this on the old T32 teamspeak server. It was possible to link up teamspeak client to game client and put everyone in the right channel.

I had a look at the discord documentation I was able to find and couldn't see any way to do it.

If someone has more information about how to do it with Discord I'd be interested to see it.

sup

  • 1337
  • *
  • Posts: 408
  • Country: br
Re: Discord - autokick to red/blue voicechannel
« Reply #2 on: September 15, 2024, 00:59 »
It would be necessary to create a bot for Discord that obtains real-time information from the server logs about which players are on which team. (I don't know if the server has a log that updates this information in real time)

Another alternative (worse, but functional if there is no real-time log informing this) would be to webscrape the forum page. A while ago I made a code that webscraped the forum page and sent a WhatsApp message if a certain map that I liked was being played lol
It worked quite well  8)

If the server has a log with the information, i think this is a starting point:

Code: [Select]
import discord
import asyncio
import aiofiles

# Discord bot token
TOKEN = 'your_discord_bot_token'

# Discord voice channel IDs for red and blue teams
TEAM_RED_CHANNEL_ID = 123456789012345678  # Replace with your Red team's voice channel ID
TEAM_BLUE_CHANNEL_ID = 987654321098765432  # Replace with your Blue team's voice channel ID

# Path to the server log file
LOG_FILE_PATH = 'server_logs.txt'

# Dictionary to track which team each player belongs to
player_team = {}

# Setting up the Discord client with necessary intents
intents = discord.Intents.default()
intents.members = True  # Enable member events
client = discord.Client(intents=intents)

@client.event
async def on_ready():
    # This event triggers when the bot successfully logs in
    print(f'Bot logged in as {client.user}')
    # Start monitoring logs when the bot is ready
    client.loop.create_task(monitor_logs())

# Function to move a player to the correct voice channel based on their team
async def move_player_to_team_channel(member, team):
    try:
        # Check which team the player is on and get the appropriate voice channel
        if team == 'Red':
            channel = client.get_channel(TEAM_RED_CHANNEL_ID)
        elif team == 'Blue':
            channel = client.get_channel(TEAM_BLUE_CHANNEL_ID)
        else:
            return  # Unknown team, no action taken
       
        if member.voice:
            # Move player to the correct team channel
            await member.move_to(channel)
            print(f'Moved {member.name} to {team} channel.')
    except Exception as e:
        print(f'Error moving {member.name}: {e}')

# Function to monitor the server log file and detect team changes
async def monitor_logs():
    async with aiofiles.open(LOG_FILE_PATH, 'r') as f:
        await f.seek(0, 2)  # Go to the end of the log file
        while True:
            line = await f.readline()
            if not line:
                # If no new line is found, wait for a while and then check again
                await asyncio.sleep(1)
                continue

            # Example log line: "Player X moved to Team Red"
            if 'moved to Team' in line:
                parts = line.split()
                player_name = parts[1]  # Player name (adjust depending on your log format)
                team = parts[-1]  # Team (Red/Blue)

                # Update player's team in the dictionary
                player_team[player_name] = team

                # Try to find the player on the Discord server
                guild = client.guilds[0]  # Adjust if the bot is in multiple servers
                member = discord.utils.get(guild.members, name=player_name)

                if member:
                    # Move the player to the correct voice channel
                    await move_player_to_team_channel(member, team)

# Start the bot
client.run(TOKEN)

Piglet

  • 1337
  • *
  • Posts: 3255
  • Country: gb
Re: Discord - autokick to red/blue voicechannel
« Reply #3 on: September 15, 2024, 15:58 »
I can arrange for the server/hax server to send out information - or to make it easily available to a bot.

However, even with a bot which has the ability to switch players' channels...the core of the problem is linking the Discord user with the player on the server.

The player on the server is normally identified by a GUID & IP (you can have two different players from the same address with the same GUID...). On Discord, I don't believe the bot would have access to IP....

Hmmm

sup

  • 1337
  • *
  • Posts: 408
  • Country: br
Re: Discord - autokick to red/blue voicechannel
« Reply #4 on: September 15, 2024, 16:22 »
It's not a big deal, the list of players who use discord is small, just create a list of these players and associate their names with the in-game names, then the bot will know which player needs to be moved to which voice channel by making the association

If someone else wants to join the discord, the bot can have an option to add this new player and associate his nickname in game

sup

  • 1337
  • *
  • Posts: 408
  • Country: br
Re: Discord - autokick to red/blue voicechannel
« Reply #5 on: September 15, 2024, 16:37 »
something like this:

Code: [Select]
import discord
import asyncio
import aiofiles

# Discord bot token
TOKEN = 'your_discord_bot_token'

# Discord voice channel IDs for red and blue teams
TEAM_RED_CHANNEL_ID = 123456789012345678  # Replace with your Red team's voice channel ID
TEAM_BLUE_CHANNEL_ID = 987654321098765432  # Replace with your Blue team's voice channel ID

# Path to the server log file
LOG_FILE_PATH = 'server_logs.txt'

# Dictionary to track which team each player belongs to
player_team = {}

# Mapping of in-game player names to Discord usernames
player_to_discord = {
    "Sup(BR)": "lala",  # Example: Sup(BR) is the in-game name, and lala is the Discord username
    # Add more mappings as needed
    # "Player_in_game": "Discord_username",
}

# Setting up the Discord client with necessary intents
intents = discord.Intents.default()
intents.members = True  # Enable member events
intents.message_content = True  # Enable message events
client = discord.Client(intents=intents)

@client.event
async def on_ready():
    print(f'Bot logged in as {client.user}')
    client.loop.create_task(monitor_logs())

@client.event
async def on_message(message):
    # Check if the message starts with the command to add a player
    if message.content.startswith('!addplayer'):
        # Extract the in-game player name from the message
        try:
            in_game_name = message.content.split(' ')[1]
            discord_username = message.author.name  # Get the Discord username of the person who sent the message

            # Add the player to the dictionary
            player_to_discord[in_game_name] = discord_username

            # Send a confirmation message
            await message.channel.send(f'Player {in_game_name} has been linked to Discord user {discord_username}.')
            print(f'Added {in_game_name} -> {discord_username}')
       
        except IndexError:
            # If the player name was not provided in the message
            await message.channel.send('Please provide the in-game name using the command: !addplayer NomeInGame')

async def move_player_to_team_channel(member, team):
    try:
        if team == 'Red':
            channel = client.get_channel(TEAM_RED_CHANNEL_ID)
        elif team == 'Blue':
            channel = client.get_channel(TEAM_BLUE_CHANNEL_ID)
        else:
            return  # Unknown team, no action taken
       
        if member.voice:
            await member.move_to(channel)
            print(f'Moved {member.name} to {team} channel.')
    except Exception as e:
        print(f'Error moving {member.name}: {e}')

async def monitor_logs():
    async with aiofiles.open(LOG_FILE_PATH, 'r') as f:
        await f.seek(0, 2)  # Go to the end of the log file
        while True:
            line = await f.readline()
            if not line:
                await asyncio.sleep(1)
                continue

            if 'moved to Team' in line:
                parts = line.split()
                player_name = parts[1]  # Player name
                team = parts[-1]  # Team (Red/Blue)

                player_team[player_name] = team
                discord_username = player_to_discord.get(player_name)

                if discord_username:
                    guild = client.guilds[0]
                    member = discord.utils.get(guild.members, name=discord_username)

                    if member:
                        await move_player_to_team_channel(member, team)
                    else:
                        print(f'Member {discord_username} not found in the guild.')
                else:
                    print(f'Player {player_name} not mapped to a Discord user.')

client.run(TOKEN)

Ottiishiia

  • Newbie
  • *
  • Posts: 13
  • Country: se
  • ~O m m m 💎
Re: Discord - autokick to red/blue voicechannel
« Reply #6 on: September 15, 2024, 17:30 »
something like this:

Code: [Select]
import discord
import asyncio
import aiofiles

# Discord bot token
TOKEN = 'your_discord_bot_token'

# Discord voice channel IDs for red and blue teams
TEAM_RED_CHANNEL_ID = 123456789012345678  # Replace with your Red team's voice channel ID
TEAM_BLUE_CHANNEL_ID = 987654321098765432  # Replace with your Blue team's voice channel ID

# Path to the server log file
LOG_FILE_PATH = 'server_logs.txt'

# Dictionary to track which team each player belongs to
player_team = {}

# Mapping of in-game player names to Discord usernames
player_to_discord = {
    "Sup(BR)": "lala",  # Example: Sup(BR) is the in-game name, and lala is the Discord username
    # Add more mappings as needed
    # "Player_in_game": "Discord_username",
}

# Setting up the Discord client with necessary intents
intents = discord.Intents.default()
intents.members = True  # Enable member events
intents.message_content = True  # Enable message events
client = discord.Client(intents=intents)

@client.event
async def on_ready():
    print(f'Bot logged in as {client.user}')
    client.loop.create_task(monitor_logs())

@client.event
async def on_message(message):
    # Check if the message starts with the command to add a player
    if message.content.startswith('!addplayer'):
        # Extract the in-game player name from the message
        try:
            in_game_name = message.content.split(' ')[1]
            discord_username = message.author.name  # Get the Discord username of the person who sent the message

            # Add the player to the dictionary
            player_to_discord[in_game_name] = discord_username

            # Send a confirmation message
            await message.channel.send(f'Player {in_game_name} has been linked to Discord user {discord_username}.')
            print(f'Added {in_game_name} -> {discord_username}')
       
        except IndexError:
            # If the player name was not provided in the message
            await message.channel.send('Please provide the in-game name using the command: !addplayer NomeInGame')

async def move_player_to_team_channel(member, team):
    try:
        if team == 'Red':
            channel = client.get_channel(TEAM_RED_CHANNEL_ID)
        elif team == 'Blue':
            channel = client.get_channel(TEAM_BLUE_CHANNEL_ID)
        else:
            return  # Unknown team, no action taken
       
        if member.voice:
            await member.move_to(channel)
            print(f'Moved {member.name} to {team} channel.')
    except Exception as e:
        print(f'Error moving {member.name}: {e}')

async def monitor_logs():
    async with aiofiles.open(LOG_FILE_PATH, 'r') as f:
        await f.seek(0, 2)  # Go to the end of the log file
        while True:
            line = await f.readline()
            if not line:
                await asyncio.sleep(1)
                continue

            if 'moved to Team' in line:
                parts = line.split()
                player_name = parts[1]  # Player name
                team = parts[-1]  # Team (Red/Blue)

                player_team[player_name] = team
                discord_username = player_to_discord.get(player_name)

                if discord_username:
                    guild = client.guilds[0]
                    member = discord.utils.get(guild.members, name=discord_username)

                    if member:
                        await move_player_to_team_channel(member, team)
                    else:
                        print(f'Member {discord_username} not found in the guild.')
                else:
                    print(f'Player {player_name} not mapped to a Discord user.')

client.run(TOKEN)
Heart eyes
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⡴⠒⠦⣄⣠⠶⠞⠳⣆⠀⠀⠀⠀
⠀⠀⠀⣴⠛⠛⠛⠲⢦⣤⡴⠶⠶⢶⠏⠀⢀⣄⣹⣇⡀⠀⠀⣻⡀⠀⠀⠀
⠀⠀⠀⡿⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⠂⠀⢿⣼⠋⠀⠉⣿⣍⠉⠉⡆⠀⠀
⠀⠀⠀⢿⡤⠀⠀⠀⠀⠀⠀⠀⠀⠈⠧⠤⠤⠿⢦⣀⣤⠿⠼⠀⣰⠃⠀⠀
⠀⠀⠀⡾⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠳⠤⠶⢿⡀⠀⠀
⠀⠀⢸⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣠⣼⡧⠤⠆
⣠⣤⢼⡧⢤⠀⠀⠀⢠⣦⠀⠀⠀⠀⠀⠀⠀⠀⠀⣾⡇⠀⠀⠀⣤⣧⣄⡀
⠀⠀⢀⡿⠉⠹⡄⠀⠈⠋⠀⠀⠀⣴⠒⡆⠀⠀⠀⠀⠀⠀⠀⣀⣼⠁⠀⠀
⢠⡞⠉⠛⠀⠀⠹⠶⠶⣄⠀⠀⠀⠈⠉⠀⠀⠀⠀⠀⠀⠀⣀⠾⠉⠙⠒⠀
⠀⠳⢤⣀⠀⠀⢠⠖⠒⠈⢳⣀⠀⠀⢀⣀just a signature,relax