diff --git a/Update.bat b/Update.bat index 0257bd2..b3c8e9c 100644 --- a/Update.bat +++ b/Update.bat @@ -9,4 +9,5 @@ echo Averaging CSV files py MaptickAverager.py echo Plotting Graphs gnuplot maptick_plot.gnuplot -popd "%~dp0" \ No newline at end of file +popd "%~dp0" +pause \ No newline at end of file diff --git a/root/MaptickAverager.py b/root/MaptickAverager.py index 060e68d..da81d9d 100644 --- a/root/MaptickAverager.py +++ b/root/MaptickAverager.py @@ -15,7 +15,15 @@ data_file = "data/last_run.dat" old_data_file = f"{output_loc}last_run.dat" -#Converts a log file into a dict +# converts a float input measured in seconds to one in microseconds + + +def to_microseconds(value): + return value * 1000 * 1000 + +# Converts a log file into a dict + + def log_file_to_dict(): write_to = {} file_path = data_file @@ -24,43 +32,47 @@ def log_file_to_dict(): file_path = old_data_file if not os.path.exists(file_path): return write_to - - #A data file holding info about the last "compile" - #In the format Key:Data\n - info_file = open(file_path, 'r') + + # A data file holding info about the last "compile" + # In the format Key:Data\n + info_file = open(file_path, 'r') info = info_file.read() info_file.close() - info = info.split("\n") #Split the file into lines + info = info.split("\n") # Split the file into lines for line in info: - packet = line.split(":") #Convert the file into a dict - if not line: #Damn new lines + packet = line.split(":") # Convert the file into a dict + if not line: # Damn new lines continue write_to[packet[0]] = str(packet[1]) - + return write_to -#Converts a log file into a dict, in the format described above +# Converts a log file into a dict, in the format described above + + def dict_to_log_file(dict): write_string = "" file_path = data_file - + for key in dict: write_string += f"{key}:{dict[key]}\n" - + write_string.strip("\n") - info_file = open(file_path, 'w') + info_file = open(file_path, 'w') info_file.write(write_string) info_file.close() -#Returns true if the two dicts match in terms of method, false otherwise +# Returns true if the two dicts match in terms of method, false otherwise + + def compare_dict_methods(dict1, dict2, compare_by): for entry in compare_by: if entry not in dict1 and entry not in dict2: print(f"{entry} was in nothing, wtf") continue - #One file is newer then the other, do a full rerun + # One file is newer then the other, do a full rerun if entry not in dict1 or entry not in dict2: print(f"The dat file was outdated") return False @@ -69,73 +81,79 @@ def compare_dict_methods(dict1, dict2, compare_by): return False return True + def copy_dict_into_dict(copy_from, copy_into, keys_to_ignore): for key in copy_from: if key in keys_to_ignore: continue copy_into[key] = copy_from[key] -#Modified binary search. check_function returns 1 if the first index is "larger" then the second, -1 if it's smaller, and 0 if they're the same def round_binary_search(arr, look_for): look_for = int(look_for) low = 0 high = len(arr) - 1 mid = 0 - + while low <= high: - + mid = (high + low) // 2 - properties = arr[mid].split("-") #This will get messy if you have a - in the system path - working_rnd_id = int(properties[1]) #Hopefully the second line in this file is always the round's id + # This will get messy if you have a - in the system path + properties = arr[mid].split("-") + # Hopefully the second line in this file is always the round's id + working_rnd_id = int(properties[1]) if working_rnd_id < look_for: low = mid + 1 elif working_rnd_id > look_for: high = mid - 1 else: return mid - + # If we reach here, then the element was not present return -1 + def file_binary_search(arr, look_for): look_for = int(look_for) low = 0 high = len(arr) - 1 mid = 0 - + while low <= high: - + mid = (high + low) // 2 - properties = arr[mid].split(",") #This will get messy if you have a - in the system path - working_rnd_id = int(properties[0]) #First line's always the id, right? RIGHT? + # This will get messy if you have a - in the system path + properties = arr[mid].split(",") + # First line's always the id, right? RIGHT? + working_rnd_id = int(properties[0]) if working_rnd_id < look_for: low = mid + 1 elif working_rnd_id > look_for: high = mid - 1 else: return mid - + if mid <= 0: - return mid #This is for the empty files, since you can't take away more then nothing can you + return mid # This is for the empty files, since you can't take away more then nothing can you roundid = int(arr[mid].split(",")[0]) lastmid = mid - #While we're greater then the target round id + # While we're greater then the target round id while roundid >= look_for: - if mid - 1 <= -1: #If this is the last item in the list give up - break - lastmid = mid #Set lastmid to our current value - mid -= 1 #Lower mid by one - roundid = int(arr[mid].split(",")[0]) #Set roundid to the new value - - #This will keep looping until we either hit the end, or go below the last round id - #Should prevent rounding issues with the binary search - + if mid - 1 <= -1: # If this is the last item in the list give up + break + lastmid = mid # Set lastmid to our current value + mid -= 1 # Lower mid by one + roundid = int(arr[mid].split(",")[0]) # Set roundid to the new value + + # This will keep looping until we either hit the end, or go below the last round id + # Should prevent rounding issues with the binary search + # If we reach here, then the element was not present return lastmid + def make_list_into_string(headers): output = "" for header in headers: @@ -144,6 +162,7 @@ def make_list_into_string(headers): output += "\n" return output + def turn_dict_into_comma_seperated_string(dict_to_convert, headers): output = "" for key in headers: @@ -152,10 +171,11 @@ def turn_dict_into_comma_seperated_string(dict_to_convert, headers): output += "\n" return output + def recalculate_value(list, default_value, value_creator): current_val = list[0] first = list[1][0] - list[1].pop(0) #Remove the first item in the list + list[1].pop(0) # Remove the first item in the list if first == current_val: holder = default_value for value in list[1]: @@ -164,27 +184,29 @@ def recalculate_value(list, default_value, value_creator): holder = 0 list[0] = holder + def add_new_value(list, new_value, value_creator): list[0] = value_creator(new_value, list[0]) list[1] += [new_value] -#A dict of information about this run, used to determin if a full run is needed next time + +# A dict of information about this run, used to determin if a full run is needed next time data_log = {} -tags_to_compare_with = ["backward_avg", "forward_avg", "backward_bound", "forward_bound", "starting_at", "highpass_threshold"] +tags_to_compare_with = ["backward_avg", "forward_avg", "backward_bound","forward_bound", "starting_at", "highpass_threshold"] tags_to_leave_pure = tags_to_compare_with + ["last_round_fully_processed"] -#A dict of information about the last run we did +# A dict of information about the last run we did old_log = log_file_to_dict() -#Modify these tochange the size of the moving average -movingbackward = 50 -movingforward = 50 +# Modify these tochange the size of the moving average +movingbackward = 30 +movingforward = 30 total_moving_space = movingbackward + movingforward data_log["backward_avg"] = str(movingbackward) data_log["forward_avg"] = str(movingforward) -#Modify these to effect the size of moving minimums and maximums. so how large should our bucket of items to min/max be basically +# Modify these to effect the size of moving minimums and maximums. so how large should our bucket of items to min/max be basically boundbackward = 20 boundforward = 20 total_bound = boundbackward + boundforward @@ -192,28 +214,29 @@ def add_new_value(list, new_value, value_creator): data_log["backward_bound"] = str(boundbackward) data_log["forward_bound"] = str(boundforward) -#Knock on wood +# Knock on wood data_log["last_round_fully_processed"] = 10000000000 -#A reminder of the farthest back you can go +# A reminder of the farthest back you can go ON_THE_MORNING_OF_THE_FIRST_DAY = 150043 -#This is useful for making graphs that scale a little bit better, fucking carpets man +# This is useful for making graphs that scale a little bit better, fucking carpets man PAST_CARPETS = 156000 -#What round id to start reading at +# What round id to start reading at head_rnd = ON_THE_MORNING_OF_THE_FIRST_DAY data_log["starting_at"] = head_rnd -highpass = 2.5 #Cuts out the pain stuff while still allowing the carpet bump to remain clear +highpass = 2.5 # Cuts out the pain stuff while still allowing the carpet bump to remain clear data_log["highpass_threshold"] = highpass -keys_to_average = ["maptick_to_player", "maptick", "players", "td", "td_to_player"] +keys_to_average = ["maptick_to_player", "maptick", "players", "td", "td_to_player", "sendmaps_cost_per_tick", "per_client", "look_for_movable_changes", "check_turf_vis_conts", "check_hud/image_vis_contents", "turfs_in_range", "obj_changes", "mob_changes", "movables_examined"] input = glob.glob("output/*.csv") -#The index to start reading at +# The index to start reading at id_start_at = round_binary_search(input, head_rnd) -preserve_old_files = compare_dict_methods(data_log, old_log, tags_to_compare_with) +preserve_old_files = compare_dict_methods( + data_log, old_log, tags_to_compare_with) if preserve_old_files: round_start_at = old_log["last_round_fully_processed"] @@ -225,15 +248,18 @@ def add_new_value(list, new_value, value_creator): for key in keys_to_average: fieldnames += [f"avg_{key}"] fieldnames += [f"min_{key}"] - fieldnames += [f"max_{key}"] + fieldnames += [f"max_{key}"] fieldnames = ["id"] + fieldnames -#I despise janitors -maps_we_care_about = ["Delta%20Station", "Ice%20Box%20Station", "Kilo%20Station", "MetaStation", "Tramstation"] +# I despise janitors +maps_we_care_about = ["Delta%20Station", "Ice%20Box%20Station", + "Kilo%20Station", "MetaStation", "Tramstation"] + +# Dictionary of file names to dictionaries of data to be written later. +data = {} -data = {} #Dictionary of file names to dictionaries of data to be written later. - +# first pass of data parsing: populate the data dictionary with info # for all round ids we've not ingested before for index in range(id_start_at, len(input)): f_name = input[index] @@ -242,128 +268,185 @@ def add_new_value(list, new_value, value_creator): player_total = 0 td_total = 0 + has_sendmaps_profiler_logs = False + csvfile = open(f_name, newline='') reader = csv.DictReader(csvfile) - #read all the data + + #raw_rows = csvfile.readlines() + #rows_with_fields = dict(zip(reader.fieldnames, raw_rows)) + + get_value = lambda row, row_stat, null_val=0: float(row.get(row_stat) or null_val) if row != None else null_val + + last_row = None + + # read all the data for row in reader: lines_read += 1 - maptick_total += float(row["maptick"]) - player_total += float(row["players"]) - td_total += float(row["tidi_avg"]) + last_row = row.copy() + + maptick_total += get_value(row, "maptick") + player_total += get_value(row, "players") + td_total += get_value(row, "tidi_avg") + + # the last row read is the final value for these + sendmaps_total_cost = get_value(last_row, "send_maps") + # have to use .get(index) or 0 because not all logs have these indices + sendmaps_total_calls = get_value(last_row, "send_maps_count") + if sendmaps_total_cost != 0.0: + has_sendmaps_profiler_logs = True + + sendmaps_client_cost = get_value(last_row, "per_client") + sendmaps_client_calls = get_value(last_row, "per_client_count") + + movable_changes_cost = get_value(last_row, "look_for_movable_changes") + movable_changes_calls = get_value(last_row, "look_for_movable_changes_count") + + check_turf_vis_contents_cost = get_value(last_row, "check_turf_vis_conts") + check_turf_vis_contents_calls = get_value(last_row, "check_turf_vis_conts_count") + + check_hud_image_vis_contents_cost = get_value(last_row, "check_hud/image_vis_contents") + check_hud_image_vis_contents_calls = get_value(last_row, "check_hud/image_vis_contents_count") + + loop_turfs_in_range_cost = get_value(last_row, "turfs_in_range") + loop_turfs_in_range_calls = get_value(last_row, "turfs_in_range_count") + + obj_changes_cost = get_value(last_row, "obj_changes") + obj_changes_calls = get_value(last_row, "obj_changes_count") + + mob_changes_cost = get_value(last_row, "mob_changes") + mob_changes_calls = get_value(last_row, "mob_changes_count") + + movables_examined = get_value(last_row, "movables_examined") + csvfile.close() - #In the template perf-[roundid]-[mapname]-[servername].csv - file_without_ending = f_name.split(".")[0] - properties = file_without_ending.split("-") #This will get messy if you have a - in the system path + # In the template perf-[roundid]-[mapname]-[servername].csv + file_without_ending = f_name.split(".")[0] + # This will get messy if you have a - in the system path + properties = file_without_ending.split("-") if len(properties) < 3: print(f"ERROR: [{f_name}] Is being improperly parsed") - id = properties[1] #The second item in this list should be id - map = properties[2] #The third item is the map name - server = properties[3] #Fourth term's the server this round came from, we'll need that soon + id = properties[1] # The second item in this list should be id + map = properties[2] # The third item is the map name + # Fourth term's the server this round came from, we'll need that soon + server = properties[3] if not id.isnumeric(): print("Found a non numeric round id, [id], skipping") continue - #There was a short period where we were parsing byond's maptick values incorrectly. - #This lead to irrecovorably broken logs. This check exists to handle them - #Let's try not to add any more yeah? + # There was a short period where we were parsing byond's maptick values incorrectly. + # This lead to irrecovorably broken logs. This check exists to handle them + # Let's try not to add any more yeah? intid = int(id) if intid >= 164722 and intid <= 164824: - continue + continue + + def average_if_valid(numerator, denominator): return numerator / denominator if denominator > 0 else 0 + def average_if_exists(numerator, denominator): return average_if_valid(numerator, denominator) if has_sendmaps_profiler_logs == True else 0 + + td_per_player = average_if_exists(td_total, player_total) + if td_per_player > 1.2: + td_per_player = 0.6 + + to_write = {} + + to_write["id"] = id + to_write["maptick_to_player"] = average_if_valid(maptick_total, player_total) + to_write["maptick"] = average_if_valid(maptick_total, lines_read) + to_write["players"] = average_if_valid(player_total, lines_read) + to_write["td"] = average_if_exists(td_total, lines_read) - maptick_by_players = 0 - td_by_players = 0 - avg_maptick = 0 - avg_players = 0 - avg_td = 0 - if player_total: - maptick_by_players = maptick_total / player_total - td_by_players = td_total / player_total - if lines_read: - avg_maptick = maptick_total / lines_read - avg_players = player_total / lines_read - avg_td = td_total / lines_read - - #I'm sorry + to_write["td_to_player"] = td_per_player + + to_write["sendmaps_cost_per_tick"] = to_microseconds(average_if_exists(sendmaps_total_cost, sendmaps_total_calls)) + to_write["per_client"] = to_microseconds(average_if_exists(sendmaps_client_cost, sendmaps_client_calls)) + to_write["look_for_movable_changes"] = to_microseconds(average_if_exists(movable_changes_cost, movable_changes_calls)) + to_write["check_turf_vis_conts"] = to_microseconds(average_if_exists(check_turf_vis_contents_cost, check_turf_vis_contents_calls)) + to_write["check_hud/image_vis_contents"] = to_microseconds(average_if_exists(check_hud_image_vis_contents_cost, check_hud_image_vis_contents_calls)) + to_write["turfs_in_range"] = to_microseconds(average_if_exists(loop_turfs_in_range_cost, loop_turfs_in_range_calls)) + to_write["obj_changes"] = to_microseconds(average_if_exists(obj_changes_cost, obj_changes_calls)) + to_write["mob_changes"] = to_microseconds(average_if_exists(mob_changes_cost, mob_changes_calls)) + to_write["movables_examined"] = average_if_exists(movables_examined, sendmaps_client_calls) + + # finalize our data collection by map, server, and generic single stat files pending = [map, server, "maptick", "highpass_maptick"] for index in pending: - if index not in data: #If one doesn't already exist, make a new list to put our map data into + if index not in data: # If one doesn't already exist, make a new list to put our map data into data[index] = [] - if index == "highpass_maptick" and (maptick_by_players > highpass): + if index == "highpass_maptick" and (to_write["maptick_to_player"] > highpass): continue - to_write = {} - to_write["id"] = id - to_write["maptick_to_player"] = maptick_by_players - to_write["maptick"] = avg_maptick - to_write["players"] = avg_players - to_write["td"] = avg_td - if td_by_players > 1.2: - td_by_players = 0.6 - to_write["td_to_player"] = td_by_players - data[index].append(to_write) + #print(to_write.copy()) + data[index].append(to_write.copy()) print(f"Read [{id}] [{map}] [{server}]") -#Now that we've done a first pass, we need to go back over things again -#These are all the file names that need operating on +# Now that we've done a first pass, we need to go back over things again +# These are all the file names that need operating on for index in data: working_list = data[index] - #Before you open it for writing, if we're working from a starting point, write all the untouched lines into the cache + # Before you open it for writing, if we're working from a starting point, write all the untouched lines into the cache write_to_file = "" - + write_to_file += make_list_into_string(fieldnames) key = f"last_round_fully_processed_{index}" - #Preps existing csv files for our new input, careful this gets messy fast + # Preps existing csv files for our new input, careful this gets messy fast if preserve_old_files and id_start_at and key in old_log: round_start_at = old_log[key] - - round_start_at = min(int(round_start_at), int(old_log["last_round_fully_processed"])) + + round_start_at = min(int(round_start_at), int( + old_log["last_round_fully_processed"])) read_from = open(f"{output_loc}{index}.csv", 'r') - + file_contents = read_from.read() read_from.close() file_contents = file_contents.strip("\n") file_contents = file_contents.split("\n") - file_contents = file_contents[1:]#Get rid of the first line, which should just be the headers + # Get rid of the first line, which should just be the headers + file_contents = file_contents[1:] last_sane_round = file_binary_search(file_contents, round_start_at) if last_sane_round > 0: - file_contents = file_contents[:last_sane_round + 1] #Cut out the entries we're going to touch + # Cut out the entries we're going to touch + file_contents = file_contents[:last_sane_round + 1] write_to_file += "\n".join(file_contents) - length_of_rows = len(working_list) - 1 # If there's one item, I want this to be 0 - - #These two dicts are key -> list[interested value, [list of members]] + # If there's one item, I want this to be 0 + length_of_rows = len(working_list) - 1 + + # These two dicts are key -> list[interested value, [list of members]] local_min = {} local_max = {} for key_type in keys_to_average: local_min[key_type] = [MAX, []] - local_max[key_type] = [0, []] + local_max[key_type] = [0, []] for i in range(length_of_rows): row = working_list[i] - + look_behind = i - movingbackward look_ahead = i + movingforward do_not_remove = False do_not_add = False - #Wrapping, this is why there's those flat lines at the edges of the graph + # Wrapping, this is why there's those flat lines at the edges of the graph if look_behind < 0: - delta_behind = abs(look_behind) #delta will be the remainder of look_ahead + # delta will be the remainder of look_ahead + delta_behind = abs(look_behind) look_behind = 0 - look_ahead = min(look_ahead + delta_behind, length_of_rows) + look_ahead = min(look_ahead + delta_behind, length_of_rows) if look_ahead > length_of_rows: - delta_ahead = look_ahead - length_of_rows #delta will be the remainder of look_behind + # delta will be the remainder of look_behind + delta_ahead = look_ahead - length_of_rows look_ahead = length_of_rows - look_behind = max(look_behind - delta_ahead, 0) - + look_behind = max(look_behind - delta_ahead, 0) + if i - boundforward < 0: do_not_add = True @@ -371,7 +454,7 @@ def add_new_value(list, new_value, value_creator): do_not_remove = True totals = {} - + for key_type in keys_to_average: totals[key_type] = 0 @@ -384,32 +467,35 @@ def add_new_value(list, new_value, value_creator): if do_not_add: continue - + newest_val = data[index][i][key_type] add_new_value(min_list, newest_val, min) add_new_value(max_list, newest_val, max) - for ii in range(look_behind, look_ahead): #Look through them all + for ii in range(look_behind, look_ahead): # Look through them all look_at = data[index][ii] for key_type in keys_to_average: totals[key_type] += look_at[key_type] - total_read = (look_ahead - look_behind) + 1 #Add 1 so reading one line doesn't read an average of 0 - + # Add 1 so reading one line doesn't read an average of 0 + total_read = (look_ahead - look_behind) + 1 + for key_type in keys_to_average: row[f"avg_{key_type}"] = totals[key_type] / total_read row[f"min_{key_type}"] = local_min[key_type][0] - row[f"max_{key_type}"] = local_max[key_type][0] + row[f"max_{key_type}"] = local_max[key_type][0] write_to_file += turn_dict_into_comma_seperated_string(row, fieldnames) rnd_id = row["id"] print(f"Write [{index}] [{i}] [{rnd_id}]") - last_good_subset_round = working_list[-min(len(working_list), total_moving_space)]["id"] + last_good_subset_round = working_list[-min( + len(working_list), total_moving_space)]["id"] data_log[key] = last_good_subset_round if index in maps_we_care_about: - data_log["last_round_fully_processed"] = min(int(last_good_subset_round), int(data_log["last_round_fully_processed"])) + data_log["last_round_fully_processed"] = min( + int(last_good_subset_round), int(data_log["last_round_fully_processed"])) output = open(f"{output_loc}{index}.csv", 'w') output.write(write_to_file) diff --git a/root/RawLogsScraper.py b/root/RawLogsScraper.py index 7a61e08..2ee8cdd 100644 --- a/root/RawLogsScraper.py +++ b/root/RawLogsScraper.py @@ -95,6 +95,7 @@ def __init__(self, expression, message): class Buffer: def __init__(self, size, server, lastUrl = ""): + #how many files we can hold in our buffer before we have to write them all to data buffers self.size = size # List of [url, fileName, text]s self.fileBuffer = [] @@ -103,6 +104,7 @@ def __init__(self, size, server, lastUrl = ""): # Our last saved url self.previousUrl = lastUrl + #write every data file we have in our buffer to a data file in the output folder def dumpBuffer(self): if len(self.fileBuffer) == 0: return @@ -127,6 +129,7 @@ def writeToBuffer(self, url, fileName, text): return self.dumpBuffer() +#writes to the lastrun.dat file to store info on the current scraping run def writeDataFile(server, roundUrl, previousUrl): master_info = scraped_info @@ -168,6 +171,7 @@ def clearDataFile(): #fakingIdentity = json.load(do_not_post_this_4head) #Loads a .json file containing the cookie and other params to send to mso #do_not_post_this_4head.close() +#return the file located at the given url if possible def get_url(requestTarget) : for i in range(1, retry_limit): response = requests.get(requestTarget, headers = fakingIdentity) @@ -236,7 +240,7 @@ def listFD(url): #return [node.get('href') for node in soup.find_all('a')] def readFile(url, name, serverName, fileBuffer): - response = get_url(url) + targeted_file = get_url(url) name = name.rstrip('.gz') name_parts = name.split(".") name_parts[0] += f"-{serverName}" @@ -244,13 +248,13 @@ def readFile(url, name, serverName, fileBuffer): filename = outputFolder + name #The exists check prevents overscanning, if you fuck something up comment it out - if not response: + if not targeted_file: return -1 if os.path.exists(filename): return -1 - fileBuffer.writeToBuffer(url, filename, response.text) + fileBuffer.writeToBuffer(url, filename, targeted_file.text) def roundAge(round): # If you're not a string (Not a round id) I'm not interested diff --git a/root/SingleRound.py b/root/SingleRound.py index 695c153..2996c80 100644 --- a/root/SingleRound.py +++ b/root/SingleRound.py @@ -3,15 +3,11 @@ import sys import subprocess import os.path - -#output_loc = "maptick/" -#if not os.path.exists(output_loc): -# os.makedir(output_loc) output_to = "single_round/temporary" read_from = "output/" sendmaps_starting = ["send_maps", "initial_house", "cleanup", "client_loop", "per_client", "deleted_images", "hud_update", "statpanel_update", "map_data", "check_eye_pos", "update_chunks", "turfmap_updates", "changed_turfs", "turf_chunk_info", "obj_changes", "mob_changes", "send_turf_vis_conts", "pending_animations", "look_for_movable_changes", "check_turf_vis_conts", "check_hud/image_vis_contents", "turfs_in_range", "movables_examined"] -sendmaps_grunge = [] +sendmaps_grunge = []#like above but everything ends in _count. theyre just # of calls for that thing for name in sendmaps_starting: sendmaps_grunge += [name + "_count"] @@ -36,7 +32,7 @@ reader = csv.DictReader(csvfile) output = open(f"{output_to}.csv", 'w') -writer = csv.DictWriter(output, fieldnames=fieldnames+sendmaps_grunge+sendmaps_starting) +writer = csv.DictWriter(output, fieldnames=fieldnames + sendmaps_grunge + sendmaps_starting) writer.writeheader() for row in reader: diff --git a/root/maptick_plot.gnuplot b/root/maptick_plot.gnuplot index cb233c2..0981d8f 100644 --- a/root/maptick_plot.gnuplot +++ b/root/maptick_plot.gnuplot @@ -28,6 +28,12 @@ outputfile10 = sprintf("%s Average By Map%s", filename, outputformat) outputfile11 = sprintf("%s Average By Server%s", filename, outputformat) outputfile12 = sprintf("%s%s", filename, outputformat) +filename = "SendMaps Profiler" +filename = sprintf("%s%s", outputfolder, filename) +outputfile13 = sprintf("%s Average%s", filename, outputformat) +outputfile14 = sprintf("%s Average By Map%s", filename, outputformat) +outputfile15 = sprintf("%s Average By Server%s", filename, outputformat) + set key autotitle columnheader set key noenhanced set term png size 1000, 600 @@ -41,11 +47,12 @@ set yrange [0:] set grid ytics #CSV file is formatted like this -# id, maptick_to_player, maptick, players, td, td_to_player -# followed by three entries for everything but the id. avg, min, and max +# id, maptick_to_player, maptick, players, td, td_to_player, sendmaps_cost_per_tick, per_client, look_for_movable_changes, check_turf_vis_conts, check_hud/image_vis_contents, turfs_in_range, obj_changes, mob_changes, movables_examined +# followed by three entries for everything but the id: the avg, the min, and the max #To find the index of the header you want, use this forumula -# 6 + ((spot in list - 2) * 3) + (spot in list - 1) * header you want +# 15 + ((spot in list - 2) * 3) + (spot in list - 1) * header you want +#I HAVE NO IDEA HOW THESE ARE DERIVED REEEEEEEEEEEEEE highpass = "highpass_maptick.csv" highpass = sprintf("%s%s", inputfolder, highpass) @@ -53,12 +60,12 @@ highpass = sprintf("%s%s", inputfolder, highpass) set rmargin 13 set output outputfile1 set title "MPP (High Pass Filter)" -plot highpass using 1:2 with lines title "Maptick Per Player" +plot highpass using 1:7 with lines title "Maptick Per Player" set rmargin 13 set output outputfile2 set title "MPP" -plot inputfile using 1:2 with lines title "Maptick Per Player" +plot inputfile using 1:7 with lines title "Maptick Per Player" set rmargin 22 set output outputfile3 @@ -72,40 +79,57 @@ serverfiles = "manuel.csv basil.csv sybil.csv terry.csv" set output outputfile4 set title "Average Maptick Over Player Count By Map" -plot for [file in mapfiles] sprintf("%s%s", inputfolder, file) using 1:7 with lines title file +plot for [file in mapfiles] sprintf("%s%s", inputfolder, file) using 1:16 with lines title file set output outputfile5 set title "Average Maptick Over Player Count By Server" -plot for [file in serverfiles] sprintf("%s%s", inputfolder, file) using 1:7 with lines title file +plot for [file in serverfiles] sprintf("%s%s", inputfolder, file) using 1:16 with lines title file set ylabel 'Player Count' set output outputfile6 set title "Average Player Count" -plot inputfile using 1:15 with lines +plot inputfile using 1:22 with lines set output outputfile7 set title "Average Player Count By Map" -plot for [file in mapfiles] sprintf("%s%s", inputfolder, file) using 1:15 with lines title file +plot for [file in mapfiles] sprintf("%s%s", inputfolder, file) using 1:22 with lines title file set output outputfile8 set title "Average Player Count By Server" -plot for [file in serverfiles] sprintf("%s%s", inputfolder, file) using 1:15 with lines title file +plot for [file in serverfiles] sprintf("%s%s", inputfolder, file) using 1:22 with lines title file set ylabel 'TD' set output outputfile9 set title "Average TD" -plot inputfile using 1:16 with lines +plot inputfile using 1:25 with lines set output outputfile10 set title "Average TD By Map" -plot for [file in mapfiles] sprintf("%s%s", inputfolder, file) using 1:16 with lines title file +plot for [file in mapfiles] sprintf("%s%s", inputfolder, file) using 1:25 with lines title file set output outputfile11 set title "Average TD By Server" -plot for [file in serverfiles] sprintf("%s%s", inputfolder, file) using 1:16 with lines title file +plot for [file in serverfiles] sprintf("%s%s", inputfolder, file) using 1:25 with lines title file set output outputfile12 set title "TD" -plot inputfile using 1:5 with lines title "TD" \ No newline at end of file +plot inputfile using 1:5 with lines title "TD" + +set ylabel 'Microseconds' +set xrange [163000:] + +set output outputfile13 +set title "Average Costs" +plot inputfile using 1:34 with lines, '' using 1:37 with lines, '' using 1:40 with lines, '' using 1:43 with lines, '' using 1:46 with lines, '' using 1:49 with lines, '' using 1:52 with lines#, '' using 1:55 with lines + +set ylabel "Count" + +set output outputfile14 +set title "Movable Count By Map" +plot for [file in mapfiles] sprintf("%s%s", inputfolder, file) using 1:55 with lines title file + +set output outputfile15 +set title "Movable Count By Server" +plot for [file in serverfiles] sprintf("%s%s", inputfolder, file) using 1:55 with lines title file \ No newline at end of file