Created
May 2, 2015 20:52
-
-
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)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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