Skip to content

Instantly share code, notes, and snippets.

@luc99a
Last active August 27, 2015 08:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save luc99a/0013f9bcb369928e07f2 to your computer and use it in GitHub Desktop.
Save luc99a/0013f9bcb369928e07f2 to your computer and use it in GitHub Desktop.
A Minecraft server wrapper that sends server's output to a socket, need a lot of improovement
#!/usr/bin/python
#Minecraft server wrapper
#sends stdout via socket to DESTINATION_IP DESTINATION_PORT
#by luc99
#Configuration
#Put here the server path
SERVER_PATH = "/home/maurizio/Scrivania/.wrapper/craftbukkit.jar"
#Java executable path, put where the java executable is, if PATH is set
#just the program name is fine
JAVA_EXECUTABLE = "java"
#Put here Java Virtual Machine arguments
JVM_ARGS = ""
#Restart server if not stopped by this wrapper
RESTART_SERVER = True
#IP where stdout will be sent
DESTINATION_IP = "127.0.0.1"
#Port where stdout will be sent
DESTINATION_PORT = 1234
#Connection attempts, if negative infinite
CONNECTION_ATTEMPTS = -1
#Logging configuration
USE_LOGGING = True
LOG_FILE = "/home/maurizio/wrapper.log"
#Cofiguration end, start of the script, modify only if you know what you
#are doing
#Imports
import subprocess
import socket
import logging
import select
import sys
import signal
#Global variables
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
socket_connected = False
socket_buffer = []
server_process = None
running = True
r_list = []
def start_socket():
global CONNECTION_ATTEMPTS, socket_connected, socket_buffer
if CONNECTION_ATTEMPTS == 0:
return
try:
server_socket.connect((DESTINATION_IP, DESTINATION_PORT))
socket_connected = True
info("Connected to " + DESTINATION_IP + " " + str(DESTINATION_PORT))
for s in socket_buffer:
socket_send(s)
socket_buffer = []
except Exception, e:
warning("Cannot connect to " + DESTINATION_IP + " " + str(DESTINATION_PORT))
if CONNECTION_ATTEMPTS > 0:
CONNECTION_ATTEMPTS -= 1
def check_socket():
if not socket_connected:
start_socket()
def socket_send(string):
if socket_connected:
server_socket.send(string)
else:
socket_buffer.append(string)
def run_console_command(string):
if is_process_terminated():
return
info("Running console command " + string.strip("\n"))
server_process.stdin.write(string.strip("\n") + "\n")
def debug(string):
info("DEBUG: " + string)
def info(string):
if USE_LOGGING:
logging.info(string)
def warning(string):
if USE_LOGGING:
logging.warning(string)
def is_process_terminated():
server_process.poll()
return False if server_process.returncode == None else True
def start_process():
global server_process, r_list
start_command = JAVA_EXECUTABLE + " " + JVM_ARGS + " -jar " + SERVER_PATH
info("Using this command to start the server: " + start_command)
server_process = subprocess.Popen(start_command, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, stdin=subprocess.PIPE, shell=True)
r_list = [sys.stdin, server_process.stdout]
def terminate(signame):
info("Received " + signame + ", terminating server")
run_console_command("stop")
server_process.wait()
if not server_process.returncode == 0:
warning("Server exited with exit status " + str(server_process.returncode))
server_socket.close()
running = False
exit(0)
def sigterm():
terminate("SIGTERM")
def sigint(a, aa):
terminate("SIGINT")
def main():
global running
if USE_LOGGING:
logging.basicConfig(filename=LOG_FILE, level=logging.INFO, format="[%(asctime)s][%(levelname)s] %(message)s")
signal.signal(signal.SIGTERM, sigterm)
signal.signal(signal.SIGINT, sigint)
start_process()
while running:
check_socket()
r, w, x = select.select(r_list, [], [], 3)
if len(r) == 0 and is_process_terminated():
if RESTART_SERVER:
start_process()
else:
server_socket.close()
running = False
for i in r:
line = i.readline()
if line == "":
r_list.remove(i)
continue
if i == sys.stdin:
run_console_command(line)
elif i == server_process.stdout:
socket_send(line)
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment