Skip to content

Instantly share code, notes, and snippets.

@C4K3
Created May 2, 2015 20:52
Show Gist options
  • Save C4K3/63f137fae60c570c1198 to your computer and use it in GitHub Desktop.
Save C4K3/63f137fae60c570c1198 to your computer and use it in GitHub Desktop.
Count the time a Minecraft player has been online based on the server based on the logs (useful for logs prior to the implementation of statistics)
#!/usr/bin/env python3
import sys
import gzip
import datetime
import os
def checkDirectory(player, directory):
files = os.listdir(directory)
connectedTime = 0
for count,filename in enumerate(files, start=1):
print("Reading file %s/%s" % ( count, len(files)), end='\r')
connectedTime += checkFile(player, directory, filename)
return connectedTime
def checkFile(player, directory, filename):
"""Checks a single file for how many seconds given player has played"""
fullAddress = directory + filename
f = gzip.open(fullAddress, 'r')
# We can find out which log format this file is, if the very first character
# in the file is a [ then it's type 1, otherwise 0
if f.readline()[:1] == b'[':
logType = 1
# On the logType 1 the year, month and day are in the
# filename and are not in the content, therefore we must
# retrieve this information to pass to getUnixTime()
year = int(filename[0:4])
month = int(filename[5:7])
day = int(filename[8:10])
else:
logType = 0
year = None
month = None
day = None
connectedTime = 0
start = 0
# Start at 2 because file starts on line 1, and we already read one line
# to figure out the log format
for lineNumber,line in enumerate(f, start=2):
if (bytes(player, encoding="UTF-8") in line) and (b'logged in' in line):
start = getUnixTime(line, logType, year, month, day)
if ( bytes(player, encoding="UTF-8") in line) and (b'lost connection' in line) and (start != 0):
quit = getUnixTime(line, logType, year, month, day)
connectedTime += quit - start
start = 0
f.close()
return connectedTime
def getUnixTime(line, logType, year=None, month=None, day=None):
"""Returns the unix time a line was logged based on the text in it.
Supports both the old and new minecraft time-formatting"""
if (logType == 0):
year = int(line[0:4])
month = int(line[5:7])
day = int(line[8:10])
hour = int(line[11:13])
minute = int(line[14:16])
second = int(line[17:19])
elif (logType == 1):
hour = int(line[1:3])
minute = int(line[4:6])
second = int(line[7:9])
dt = datetime.datetime(year, month, day, hour, minute, second)
ut = int(dt.timestamp())
return ut
def main():
if (len(sys.argv) < 3):
print("Invalid arguments. Usage is ./timeconnected.py <LOG FILE DIRECTORY> [player name] ...")
exit()
log_dir = sys.argv[1]
players = sys.argv[2:len(sys.argv)]
for player in players:
time = checkDirectory(player, log_dir)
print(player + " has played for " + str(time) + " seconds.")
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment