-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.py
114 lines (99 loc) · 4.35 KB
/
main.py
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
104
105
106
107
108
109
110
111
112
113
114
import os
import asyncio
import json
import time
from fivem import FiveM # async-fivem package
import discord
from discord.ext import commands, tasks
# Discord bot setup, you can ignore these.
intents = discord.Intents.all()
intents.typing = False
intents.presences = False
intents.messages = True # Enable privileged message content intent
intents.guilds = True # Enable privileged guilds intent
bot = commands.Bot(command_prefix='!', intents=intents)
# You need to configure all these to fit your specifications.
bot_token = "" # Type your Discord Bot token here.
join_leave_channel_id = 1234567890 # Type the channel ID on Discord where you want it to output the join/leave messages. You find this by Enabling Discord Developer Mode and right-clicking a channel and Copy ID.
allowed_user_ids = [1237, 2345, 2347] # Discord User IDs that are allowed to use the !playerlist command.
ip = "123.123.123.123" # IP of the FiveM Server
port = 30120 # Port of FiveM server. Default is 30120
# Command to output all online players.
@bot.command()
async def playerlist(ctx):
user_id = str(ctx.author.id)
if user_id in allowed_user_ids:
players = await fivem_player_list()
# Join the player names with a newline character to form a single string
message = "\n".join(players)
await ctx.send(f"Current online players:\n{message}")
else:
await ctx.send("Sorry, you don't have permission to use this command.")
# A task that checks the server list every minute, can increase/decrease this as needed.
@tasks.loop(minutes=1)
async def fivem_join_leave():
print("Checking online players...") # Debugging, you can remove this line.
status_file = 'current_players.json'
new_players = await fivem_player_list()
current_time = time.time()
# Load the old status from the file
with open(status_file, 'r') as file:
if file.read().strip():
file.seek(0) # reset file pointer to beginning
old_status = json.load(file)
else:
old_status = {}
for player in new_players:
# If the player is not in the old status, they have just joined
if player not in old_status:
old_status[player] = current_time
try:
await bot.get_channel(discord_channel_id).send(f":green_square: ``{player}``")
except Exception as e:
print(f"Error sending message: {e}")
for player, join_time in list(old_status.items()):
if player not in new_players:
# The player has left
duration = current_time - join_time
hours, remainder = divmod(duration, 3600)
minutes, _ = divmod(remainder, 60)
try:
await bot.get_channel(discord_channel_id).send(f":red_square: ``{player}`` (Online for {int(hours)} hours and {int(minutes)} minutes)")
del old_status[player]
except Exception as e:
print(f"Error sending message: {e}")
# Save the new status to the file
with open(status_file, 'w') as file:
json.dump(old_status, file)
# Checks online players every minute and sets it as discord status.
@tasks.loop(minutes=1)
async def playercount_status():
players = await fivem_player_list(ip, port)
online_player_count = len(players)
await bot.change_presence(activity=discord.Game(name=f"FiveM Online Players: {online_player_count}/200"))
# A function to get the current online players from a server.
async def fivem_player_list():
fivem = FiveM(ip=ip, port=port)
for _ in range(3): # Try 3 times
try:
players = await fivem.get_players()
# Extract and sort the player names
player_names = sorted([player.name for player in players])
return player_names
except Exception as e:
print(f"Error getting player list: {e}")
await asyncio.sleep(10) # Wait for 10 seconds before retrying
print("Failed to get player list after 3 attempts")
return []
# To start the functions
@bot.event
async def on_ready():
print("Bot is ready.")
fivem_join_leave.start()
playercount_status.start()
# Check if the file exists and is not empty
status_file = 'current_players.json'
if not os.path.isfile(status_file) or os.stat(status_file).st_size == 0:
with open(status_file, 'w') as file:
json.dump({}, file)
bot.run(bot_token)