-
Notifications
You must be signed in to change notification settings - Fork 1
/
minetest-trackr.py
executable file
·137 lines (121 loc) · 4.11 KB
/
minetest-trackr.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
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
#!/usr/bin/python3
#
# Minetest player tracker
# This is the deprectated version 1 code, please visit
# https://gitlab.com/luk3yx/minetest-trackr or
# https://github.com/luk3yx/minetest-trackr for the latest version.
#
# © 2018 by luk3yx
#
import miniirc, os, time
# Create the IRC object
_irc = miniirc.IRC(
'xeroxirc.net', 6697, 'trackr', ['#Edgy1'],
realname = 'Minetest player tracker',
ns_identity = 'username password',
auto_connect = False
)
servers = {}
admins = {'invalid/your-hostmask-here'}
cooldown = 15
# Odd/even
plural = lambda n : '' if n == 1 else 's'
# Handle PRIVMSGs
last_list = 0
@miniirc.Handler('PRIVMSG')
def _handle_privmsg(irc, hostmask, args):
global last_list
nick = hostmask[0]
msg = args[-1][1:]
# Check for join/leave/connected players messages
if nick in servers:
if args[-1].startswith(':***'):
n = args[-1].split(' ', 3)
if len(n) <= 2:
return
if n[2] == 'joined':
servers[nick].add(n[1])
elif n[2] == 'left' and n[1] in servers[nick]:
servers[nick].remove(n[1])
return
elif args[-1].startswith(':Connected players: '):
servers[nick] = set(args[-1][20:].replace(' ', '').split(','))
if '' in servers[nick]:
servers[nick].remove('')
return
# Check for MT players
if msg.startswith('<'):
n = msg.split(' ', 1)
if len(n) > 1 and n[0].endswith('>') and (n[0][1].isalnum() or
n[0][1] == '\x03'):
nick = '{}@{}'.format(n[0][1:-1], nick)
msg = n[1].strip()
# Check for the players command
if msg == '.players':
t = time.time()
if t <= last_list + cooldown:
irc.msg(args[0], nick + ': You can only run \2.players\2 once',
'every \2{} seconds\2.'.format(cooldown))
return
last_list = t
# Get the player list
total = 0
tplayers = 0
for server in servers:
if len(servers[server]) > 0:
total += 1
tplayers += len(servers[server])
players = list(servers[server])
players.sort()
irc.msg(args[0], 'Players on \2{}\2: {}'.format(server,
', '.join(players)))
last_list += 0.5
time.sleep(0.5)
inactive = len(servers) - total
irc.msg(args[0], ('Total: \2{} player{}\2 across \2{} active server{}\2'
' (and {} inactive server{}).').format(tplayers, plural(tplayers),
total, plural(total), inactive, plural(inactive)))
elif hostmask[-1] in admins and msg == (irc.nick + ': die'):
irc.disconnect(hostmask[0] +
' ordered me to die- wait, why did I listen?')
os._exit(0)
# Add a server
def add_server(irc, server):
if type(server) != str:
server = server[0]
if server not in servers:
servers[server] = set()
irc.msg(server, 'players - If you are a human, report this to luk3yx.')
# Handle WHO replies
@miniirc.Handler('352')
def _handle_who(irc, hostmask, args):
nick, status = args[-3:-1]
if '+' in status:
add_server(irc, nick)
# Hadle MODEs - This is primitive but should work
@miniirc.Handler('MODE')
def _handle_mode(irc, hostmask, args):
if len(args) < 3 or not args[0].startswith('#'):
return
if args[1] == '+v':
add_server(irc, args[2])
elif args[1].startswith('+') and 'v' in args[1]:
# Don't bother handling this and just send a WHO
irc.quote('WHO', args[0])
# Handle JOIN of this bot
@miniirc.Handler('JOIN')
def _handle_join(irc, hostmask, args):
if hostmask[0].lower() == irc.nick.lower():
irc.quote('WHO', args[0])
# Handle PARTs and QUITs from MT servers
@miniirc.Handler('PART', 'QUIT')
def _handle_quit(irc, hostmask, args):
if hostmask[0] in servers:
del servers[hostmask[0]]
# Handle KICKs
@miniirc.Handler('KICK')
def _handle_kick(irc, hostmask, args):
if args[-2] in servers:
del servers[args[-2]]
_irc.persist = True
_irc.connect()