I am making a python program that communicates with a minecraft server and tells it to start, stop, or any other commands. The program reads an email and executes the command given from the email. When the program enters the command to start the server, it freezes the python program until the minecraft server is stopped.
I have tried to have the program open a batch file that starts the server, but then I don't have any way of making the program turn it off, or type in commands, or read the console.
if data[0]+data[1]+data[2]+data[3]+data[4]+data[5] == 'start ':
comm = data.replace('start ','')
try:
mb = int(float(comm)*1024)
#calls the command to start the server
call('java -Xmx' + str(mb) + 'M -Xms' + str(mb) + 'M -jar server.jar nogui')
#program freezes here until server is stopped
except Exception:
call('java -Xmx1024M -Xms1024M -jar server.jar nogui')
print("started server")
elif data == "stop server" or data == "stop":
call('stop')
elif data[0]+data[1]+data[2]+data[3]+data[4] == 'call ':
comm = data.replace('call ','')
call(comm)
print("called command")
elif data[0]+data[1]+data[2] == 'op ':
comm = data
call(comm)
print("op player")
else:
print("not a command")
deletemail(mail,i)
print("deleted item")
I expected to see the program continue and respond to emails, but it froze instead. The program continued off normally after the server was stopped. I know this isn't an error, but is there a way to get the python program to continue while the server is running?
Its is better practice to use subprocess to handle this. You can use popen which will allow you to continue to run your script and send in commands. Here is a good answer on using popen that shows how to send in commands.
Related
I have created a task to wake up the laptop from hib each 2 hours and run a .bat file.
Inside that .bat file I run a python script.
Inside that python script I have something like this:
temp_timeout = 3
while temp_timeout:
try:
response = urlopen('http://google.com', timeout=1)
return
except URLError:
print("No internet")
os.system("netsh wlan disconnect interface=NAME")
time.sleep(10)
os.system("netsh wlan connect name=NAME ssid=SSID")
time.sleep(10)
temp_timeout = temp_timeout - 1
pass
quit()
#do some stuff and go to hibernation
The problem is that from 10 wakeups I get "No internet"(x3) 2-3 times and the rest of 8-7 it's working properly. What could be the problem, why it is not working every time?
I am looking at the python program which will check if list of remote openvpn servers are really working!!
I tried the following code but no luck. after connecting the vpn server the control is not passing back to execute next line unless pressed ctrl+c. How to check below:
If the openvpn is connecting server then print active message
Else print not active message.
The whole thing is in a loop and I want to run in a virtual environment.
Code is given below
path = tempfile.mkstemp()
print('Path:',path)
f = open(path, 'w')
f.write(base64.b64decode(winner[-1]).decode('utf-8'))
f.close()
x = subprocess.Popen(['sudo', 'openvpn', '--config', path])
print("\n\n Pid:",x.pid)
try:
print('############ inside try block############', x.pid)
while True:
print('############ inside while try block############', x.pid)
time.sleep(60)
if (x.wait() == 0):
# died_serv_list.append(winner)
print('\nDead server found....Exiting.....\n')
return
print('############terminating the current prosses############', x.pid)
x.send_signal(9)
# y = subprocess.Popen(['sudo', 'kill', '-9', x.pid])
break
# termination with Ctrl+C
except: #here issue only works with ctrl+C
try:
print('\n\n\n Nice server found...\n\n')
good_serv_list.append(winner)
print('we are inside exept.')
x.kill()
except:
pass
while x.poll() != 0:
print('\n\n Donot know what the hell is this')
time.sleep(1)
print('\nVPN terminated')
I've been trying to write a python script to control the starting and stopping of a minecraft server. I've got it to accept commands through input() but i also wanted the logs of the server to be printed on the console(or be processed someway), since that the process never ends, readline hangs everytime the server finished outputing text,no further input can be performed. Is there a way to let stdin and stdout to work simultaneously,or is there a way to time out readline so i can continue?
The code i've got so far:
import subprocess
from subprocess import PIPE
import os
minecraft_dir = "D:\Minecraft Server"
executable = 'java -Xms4G -Xmx4G -jar "D:\Minecraft Server\paper-27.jar" java'
process = None
def server_command(cmd):
if(process is not None):
cmd = cmd + '\n'
cmd = cmd.encode("utf-8")
print(cmd)
process.stdin.write(cmd)
process.stdin.flush()
else:
print("Server is not running.")
def server_stop():
if process is None:
print("Server is not running.")
else:
process.stdin.write("stop\n".encode("utf-8"))
process.stdin.flush()
while True:
command=input()
command=command.lower()
if(command == "start"):
if process is None:
os.chdir(minecraft_dir)
process = subprocess.Popen(executable,stdin=PIPE,stdout=PIPE)
print("Server started.")
else:
print("Server Already Running.")
elif(command == "stop"):
server_stop()
process=None
else:
server_command(command)
I've mentioned processing the server log someway or the other because i don't really need it on the console,since i can always read from a file that it generated. But this particular server i'm running needs the stdout=PIPE argument or it throws out
java.io.IOException: ReadConsoleInputW failed
at org.fusesource.jansi.internal.Kernel32.readConsoleInputHelper(Kernel32.java:816)
at org.fusesource.jansi.internal.WindowsSupport.readConsoleInput(WindowsSupport.java:99)
at org.jline.terminal.impl.jansi.win.JansiWinSysTerminal.processConsoleInput(JansiWinSysTerminal.java:112)
at org.jline.terminal.impl.AbstractWindowsTerminal.pump(AbstractWindowsTerminal.java:458)
at java.lang.Thread.run(Unknown Source)
and i think it breaks the PIPE? Because no further input is directed to the process(process.stdin.write not working), yet the process is still running.
Any help on either one of the issue would be greatly appreciated.
(Not native English, sorry for probably broken English. I'm also a newbie at programming).
Hello, I'm trying to connect to a TeamSpeak server using the QueryServer to make a bot. After days of struggling with it... it works, with only 1 problem, and I'm stuck with that one.
If you need to check, this is the TeamSpeak API that I'm using: http://py-ts3.readthedocs.org/en/latest/api/query.html
And this is the summary of what actually happens in my script:
It connects.
It checks for channel ID (and it's own client ID)
It joins the channel
Script ends so it disconnects.
My question is: How can I make it doesn't disconnects? How can I make the script stay in a "waiting" state so it can read if someone types "hi bot" in the channel? All the code needed to read texts and answer to them seems easy to program, however I'm facing a problem where I can't keep the bot "running" since it closes the file as soon as it ends running the script.
More info:
I am using Python 3.4.1.
I tried learning Threading http://www.tutorialspoint.com/python/python_multithreading.htm but either M'm dumb or it doesn't work the way I though it would.
In the API there's a function named on_event that I would like to keep running all the time. The bot code should only be run once and then stay "waiting" until an event happens. How should i do that? No clue.
Code:
import ts3
import telnetlib
import time
class BotPrincipal:
def Conectar(ts3conn):
MiID = [i["client_id"] for i in ts3conn.whoami()]
ChannelToJoin = "[Pruebas] Bots"
ts3conn.on_event = BotPrincipal.EventHappened()
try:
BuscandoIDCanal = ts3conn.channelfind(pattern=ChannelToJoin)
IDCanal = [i["cid"] for i in BuscandoIDCanal]
if not IDCanal:
print("No channel found with that name")
return None
else:
MiID = str(MiID).replace("'", "")
MiID = str(MiID).replace("]", "")
MiID = str(MiID).replace("[", "")
IDCanal = str(IDCanal).replace("'", "")
IDCanal = str(IDCanal).replace("]", "")
IDCanal = str(IDCanal).replace("[", "")
print("ID de canal " + ChannelToJoin + ": " + IDCanal)
print("ID de cliente " + Nickname + ": " + MiID)
try:
print("Moving you into: " + ChannelToJoin)
ts3conn.clientmove(cid=IDCanal, clid=MiID) #entra al canal
try:
print("Asking for notifications from: " + ChannelToJoin)
ts3conn.servernotifyregister(event="channel", id_=IDCanal)
ts3conn.servernotifyregister(event="textchannel", id_=IDCanal)
except ts3.query.TS3QueryError:
print("You have no permission to use the telnet command: servernotifyregister")
print("------- Bot Listo -------")
except ts3.query.TS3QueryError:
print("You have no permission to use the telnet command: clientmove")
except ts3.query.TS3QueryError:
print("Error finding ID for " + ChannelToJoin + ". telnet: channelfind")
def EventHappened():
print("Doesn't work")
# Data needed #
USER = "thisisafakename"
PASS = "something"
HOST = "111.111.111.111"
PORT = 10011
SID = 1
if __name__ == "__main__":
with ts3.query.TS3Connection(HOST, PORT) as ts3conn:
ts3conn.login(client_login_name=USER, client_login_password=PASS)
ts3conn.use(sid=SID)
print("Connected to "+HOST)
BotPrincipal.Conectar(ts3conn)
From a quick glimpse at the API, it looks like you need to explicitly tell the ts3conn object to wait for events. There seem to be a few ways to do it, but ts3conn.recv(True) seems like the most obvious:
Blocks untill all unfetched responses have been received or forever, if recv_forever is true.
Presumably as each command comes in, it will call your on_event handler, then when you return from that it will go back to waiting forever for the next command.
I don't know if you need threads here or not, but the docs for recv_in_thread make it sound like you might:
Calls recv() in a thread. This is useful, if you used servernotifyregister and you expect to receive events.
You presumably want to get both servernotify events and also commands, and I guess the way this library is written you need threads for that? If so, just call ts3conn.recv_in_thread() instead of ts3conn.recv(True). (If you look at the source, all that does is start a background thread and call self.recv(True) on that thread.)
I've been writing an IRC chatbot that checks Google Voice for SMS messages then relays them to the chatroom through a socket on port 6667. The chat message processing runs in the main sub, in an infinite loop, while the GV checking is done in a separate process. The actual checking and fetching works fine, but it's the socket that doesn't work; no message is posted to the channel. What's strange is that this works flawlessly under OS X, so I don't believe the problem is the Voice processing logic:
def checkVoice()
while 1:
print "Update voice!"
#voice processing... edited for brevity
sendPrivateMessage(CHANNEL,message) #This doesn't work
#more code
time.sleep(10)
#main block
if __name__ == '__main__':
sendPrivateMessage(CHANNEL,"Voice checking started") #This works
p = Process(target=checkVoice)
p.start()
I assumed that the problem was with the way Windows is with Python, seeing as it works with other platforms.
The full code for the chatbot can be seen here:
bot.py
As asked, here is the sendPrivateMessage method:
def sendPrivateMessage(channel, message):#private message send function
global mute
if mute == 0:
IRC.send("PRIVMSG " + channel + " :" + message + "\r\n")