-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathminecraft.py
executable file
·153 lines (100 loc) · 4.11 KB
/
minecraft.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
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
#! /usr/bin/python3
# by FvH, released under Apache License v2.0
# either install 'python3-paho-mqtt' or 'pip3 install paho-mqtt'
# pip3 install mcstatus
from mcstatus import JavaServer
import paho.mqtt.client as mqtt
import threading
import time
import socket
import sys
mqtt_server = 'mqtt.vm.nurd.space'
topic_prefix = 'GHBot/'
channels = ['nurdbottest', 'nurds', 'nurdsbofh']
prefix = '!'
mc_server = 'minecraft.vm.nurd.space'
last_ring = None
def announce_commands(client):
target_topic = f'{topic_prefix}to/bot/register'
client.publish(target_topic, 'cmd=minecraft|descr=Minecraft server statistics')
def on_message(client, userdata, message):
global last_ring
global prefix
try:
text = message.payload.decode('utf-8')
topic = message.topic[len(topic_prefix):]
if topic == 'from/bot/command' and text == 'register':
announce_commands(client)
return
if topic == 'from/bot/parameter/prefix':
prefix = text
return
if len(text) == 0:
return
parts = topic.split('/')
channel = parts[2] if len(parts) >= 3 else 'nurds'
nick = parts[3] if len(parts) >= 4 else 'jemoeder'
if text[0] != prefix:
return
command = text[1:].split(' ')[0]
if channel in channels or (len(channel) >= 1 and channel[0] == '\\'):
response_topic = f'{topic_prefix}to/irc/{channel}/privmsg'
if command == 'minecraft':
try:
server = JavaServer(mc_server)
latency = server.ping()
query = server.query()
if len(query.players.names) > 0:
client.publish(response_topic, f'The server at {mc_server}/space.nurdspace.nl has the following players online: {", ".join(query.players.names)} and responds in {latency}ms.')
else:
client.publish(response_topic, f'The server at {mc_server}/space.nurdspace.nl has no players on-line currently and responds in {latency}ms.')
except Exception as e:
client.publish(response_topic, f'Problem contacting minecraft server: {e}')
except Exception as e:
print(f'fail: {e}')
def on_connect(client, userdata, flags, rc):
client.subscribe(f'{topic_prefix}from/irc/#')
client.subscribe(f'{topic_prefix}from/bot/command')
def announce_thread(client):
while True:
try:
announce_commands(client)
time.sleep(4.1)
except Exception as e:
print(f'Failed to announce: {e}')
def poller_thread(client):
people = set()
while True:
try:
server = JavaServer(mc_server)
latency = server.ping()
query = server.query()
new_people = []
for user in query.players.names:
if not user in people:
new_people.append(user)
people.add(user)
if len(new_people) > 0:
response_topic = f'{topic_prefix}to/irc/nurds/privmsg'
msg = f'New people in the minecraft server: {", ".join(new_people)}'
client.publish(response_topic, msg)
UDP_IP = 'ticker-proxy.vm.nurd.space' # ticker proxy
UDP_PORT = 5001
msg = value.strip()
msg = msg.replace('$i$', '')
msg = msg.encode('utf-8', 'ignore')
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.sendto(msg, (UDP_IP, UDP_PORT))
s.close()
time.sleep(2.5)
except Exception as e:
print(f'Failed to announce: {e}')
client = mqtt.Client(f'{socket.gethostname()}_{sys.argv[0]}', clean_session=False)
client.on_message = on_message
client.on_connect = on_connect
client.connect(mqtt_server, port=1883, keepalive=4, bind_address="")
t = threading.Thread(target=announce_thread, args=(client,))
t.start()
t2 = threading.Thread(target=poller_thread, args=(client,))
t2.start()
client.loop_forever()