Committing these because it seems to be the only way to get rid of them ever.

This commit is contained in:
Shadowmech88
2016-01-12 14:46:12 -06:00
parent 48128950c9
commit 8de9a63e78
10 changed files with 5501 additions and 5501 deletions

View File

@@ -1,54 +1,54 @@
/* /*
Written by contributor Doohl for the /tg/station Open Source project, hosted on Google Code. Written by contributor Doohl for the /tg/station Open Source project, hosted on Google Code.
(2012) (2012)
*/ */
var/list/config_stream = list() var/list/config_stream = list()
var/list/servers = list() var/list/servers = list()
var/list/servernames = list() var/list/servernames = list()
var/list/adminfiles = list() var/list/adminfiles = list()
var/list/adminkeys = list() var/list/adminkeys = list()
proc/gen_configs() proc/gen_configs()
config_stream = dd_file2list("config.txt") config_stream = dd_file2list("config.txt")
var/server_gen = 0 // if the stream is looking for servers var/server_gen = 0 // if the stream is looking for servers
var/admin_gen = 0 // if the stream is looking for admins var/admin_gen = 0 // if the stream is looking for admins
for(var/line in config_stream) for(var/line in config_stream)
if(line == "\[SERVERS\]") if(line == "\[SERVERS\]")
server_gen = 1 server_gen = 1
if(admin_gen) if(admin_gen)
admin_gen = 0 admin_gen = 0
else if(line == "\[ADMINS\]") else if(line == "\[ADMINS\]")
admin_gen = 1 admin_gen = 1
if(server_gen) if(server_gen)
server_gen = 0 server_gen = 0
else else
if(findtext(line, ".") && !findtext(line, "##")) if(findtext(line, ".") && !findtext(line, "##"))
if(server_gen) if(server_gen)
var/filterline = replacetext(line, " ", "") var/filterline = replacetext(line, " ", "")
var/serverlink = copytext(filterline, findtext( filterline, ")") + 1) var/serverlink = copytext(filterline, findtext( filterline, ")") + 1)
servers.Add(serverlink) servers.Add(serverlink)
servernames.Add( copytext(line, findtext(line, "("), findtext(line, ")") + 1)) servernames.Add( copytext(line, findtext(line, "("), findtext(line, ")") + 1))
else if(admin_gen) else if(admin_gen)
adminfiles.Add(line) adminfiles.Add(line)
to_chat(world, line) to_chat(world, line)
// Generate the list of admins now // Generate the list of admins now
for(var/file in adminfiles) for(var/file in adminfiles)
var/admin_config_stream = dd_file2list(file) var/admin_config_stream = dd_file2list(file)
for(var/line in admin_config_stream) for(var/line in admin_config_stream)
var/akey = copytext(line, 1, findtext(line, " ")) var/akey = copytext(line, 1, findtext(line, " "))
adminkeys.Add(akey) adminkeys.Add(akey)

View File

@@ -1,21 +1,21 @@
// DM Environment file for Redirect_Tgstation.dme. // DM Environment file for Redirect_Tgstation.dme.
// All manual changes should be made outside the BEGIN_ and END_ blocks. // All manual changes should be made outside the BEGIN_ and END_ blocks.
// New source code should be placed in .dm files: choose File/New --> Code File. // New source code should be placed in .dm files: choose File/New --> Code File.
// BEGIN_INTERNALS // BEGIN_INTERNALS
// END_INTERNALS // END_INTERNALS
// BEGIN_FILE_DIR // BEGIN_FILE_DIR
#define FILE_DIR . #define FILE_DIR .
// END_FILE_DIR // END_FILE_DIR
// BEGIN_PREFERENCES // BEGIN_PREFERENCES
// END_PREFERENCES // END_PREFERENCES
// BEGIN_INCLUDE // BEGIN_INCLUDE
#include "Configurations.dm" #include "Configurations.dm"
#include "Redirector.dm" #include "Redirector.dm"
#include "textprocs.dm" #include "textprocs.dm"
#include "skin.dmf" #include "skin.dmf"
// END_INCLUDE // END_INCLUDE

View File

@@ -1,88 +1,88 @@
/* /*
Written by contributor Doohl for the /tg/station Open Source project, hosted on Google Code. Written by contributor Doohl for the /tg/station Open Source project, hosted on Google Code.
(2012) (2012)
*/ */
/* TODO: work on server selection for detected admins */ /* TODO: work on server selection for detected admins */
#define ADMINS 1 #define ADMINS 1
#define PLAYERS 0 #define PLAYERS 0
var/player_weight = 1 // players are more likely to join a server with less players var/player_weight = 1 // players are more likely to join a server with less players
var/admin_weight = 5 // admins are more likely to join a server with less admins var/admin_weight = 5 // admins are more likely to join a server with less admins
var/player_substr = "players=" // search for this substring to locate # of players var/player_substr = "players=" // search for this substring to locate # of players
var/admin_substr = "admins=" // search for this to locate # of admins var/admin_substr = "admins=" // search for this to locate # of admins
world world
name = "TGstation Redirector" name = "TGstation Redirector"
New() New()
..() ..()
gen_configs() gen_configs()
/datum/server /datum/server
var/players = 0 var/players = 0
var/admins = 0 var/admins = 0
var/weight = 0 // lower weight is good; highet weight is bad var/weight = 0 // lower weight is good; highet weight is bad
var/link = "" var/link = ""
mob/Login() mob/Login()
..() ..()
var/list/weights = list() var/list/weights = list()
var/list/servers = list() var/list/servers = list()
for(var/x in global.servers) for(var/x in global.servers)
to_chat(world, "[x] [servernames[ global.servers.Find(x) ]]") to_chat(world, "[x] [servernames[ global.servers.Find(x) ]]")
var/info = world.Export("[x]?status") var/info = world.Export("[x]?status")
var/datum/server/S = new() var/datum/server/S = new()
S.players = extract(info, PLAYERS) S.players = extract(info, PLAYERS)
S.admins = extract(info, ADMINS) S.admins = extract(info, ADMINS)
S.weight += player_weight * S.players S.weight += player_weight * S.players
S.link = x S.link = x
to_chat(world, S.players) to_chat(world, S.players)
to_chat(world, S.admins) to_chat(world, S.admins)
weights.Add(S.weight) weights.Add(S.weight)
servers.Add(S) servers.Add(S)
var/lowest = min(weights) var/lowest = min(weights)
var/serverlink var/serverlink
for(var/datum/server/S in servers) for(var/datum/server/S in servers)
if(S.weight == lowest) if(S.weight == lowest)
serverlink = S.link serverlink = S.link
to_chat(src, link(serverlink)) to_chat(src, link(serverlink))
proc/extract(var/data, var/type = PLAYERS) proc/extract(var/data, var/type = PLAYERS)
var/nextpos = 0 var/nextpos = 0
if(type == PLAYERS) if(type == PLAYERS)
nextpos = findtextEx(data, player_substr) nextpos = findtextEx(data, player_substr)
nextpos += length(player_substr) nextpos += length(player_substr)
else else
nextpos = findtextEx(data, admin_substr) nextpos = findtextEx(data, admin_substr)
nextpos += length(admin_substr) nextpos += length(admin_substr)
var/returnval = "" var/returnval = ""
for(var/i = 1, i <= 10, i++) for(var/i = 1, i <= 10, i++)
var/interval = copytext(data, nextpos + (i-1), nextpos + i) var/interval = copytext(data, nextpos + (i-1), nextpos + i)
if(interval == "&") if(interval == "&")
break break
else else
returnval += interval returnval += interval
return returnval return returnval

View File

@@ -1,12 +1,12 @@
[SERVERS] [SERVERS]
## Simply enter a list of servers to poll. Be sure to specify a server name in parentheses. ## Simply enter a list of servers to poll. Be sure to specify a server name in parentheses.
(Sibyl #1) byond://game.nanotrasen.com:1337 (Sibyl #1) byond://game.nanotrasen.com:1337
(Sibyl #2) byond://game.nanotrasen.com:2337 (Sibyl #2) byond://game.nanotrasen.com:2337
[ADMINS] [ADMINS]
## Specify some standard Windows filepaths (you may use relative paths) for admin txt lists to poll. ## Specify some standard Windows filepaths (you may use relative paths) for admin txt lists to poll.
C:\SS13\config\admins.txt C:\SS13\config\admins.txt

View File

@@ -1,149 +1,149 @@
macro "macro" macro "macro"
elem elem
name = "North+REP" name = "North+REP"
command = ".north" command = ".north"
is-disabled = false is-disabled = false
elem elem
name = "South+REP" name = "South+REP"
command = ".south" command = ".south"
is-disabled = false is-disabled = false
elem elem
name = "East+REP" name = "East+REP"
command = ".east" command = ".east"
is-disabled = false is-disabled = false
elem elem
name = "West+REP" name = "West+REP"
command = ".west" command = ".west"
is-disabled = false is-disabled = false
elem elem
name = "Northeast+REP" name = "Northeast+REP"
command = ".northeast" command = ".northeast"
is-disabled = false is-disabled = false
elem elem
name = "Northwest+REP" name = "Northwest+REP"
command = ".northwest" command = ".northwest"
is-disabled = false is-disabled = false
elem elem
name = "Southeast+REP" name = "Southeast+REP"
command = ".southeast" command = ".southeast"
is-disabled = false is-disabled = false
elem elem
name = "Southwest+REP" name = "Southwest+REP"
command = ".southwest" command = ".southwest"
is-disabled = false is-disabled = false
elem elem
name = "Center+REP" name = "Center+REP"
command = ".center" command = ".center"
is-disabled = false is-disabled = false
menu "menu" menu "menu"
elem elem
name = "&Quit" name = "&Quit"
command = ".quit" command = ".quit"
category = "&File" category = "&File"
is-checked = false is-checked = false
can-check = false can-check = false
group = "" group = ""
is-disabled = false is-disabled = false
saved-params = "is-checked" saved-params = "is-checked"
window "window" window "window"
elem "window" elem "window"
type = MAIN type = MAIN
pos = 281,0 pos = 281,0
size = 594x231 size = 594x231
anchor1 = none anchor1 = none
anchor2 = none anchor2 = none
font-family = "" font-family = ""
font-size = 0 font-size = 0
font-style = "" font-style = ""
text-color = #000000 text-color = #000000
background-color = #000000 background-color = #000000
is-visible = false is-visible = false
is-disabled = false is-disabled = false
is-transparent = false is-transparent = false
is-default = true is-default = true
border = none border = none
drop-zone = false drop-zone = false
right-click = false right-click = false
saved-params = "pos;size;is-minimized;is-maximized" saved-params = "pos;size;is-minimized;is-maximized"
on-size = "" on-size = ""
title = "" title = ""
titlebar = true titlebar = true
statusbar = false statusbar = false
can-close = true can-close = true
can-minimize = true can-minimize = true
can-resize = true can-resize = true
is-pane = false is-pane = false
is-minimized = false is-minimized = false
is-maximized = false is-maximized = false
can-scroll = none can-scroll = none
icon = "" icon = ""
image = "" image = ""
image-mode = stretch image-mode = stretch
keep-aspect = false keep-aspect = false
transparent-color = none transparent-color = none
alpha = 255 alpha = 255
macro = "macro" macro = "macro"
menu = "" menu = ""
on-close = "" on-close = ""
elem "servers" elem "servers"
type = GRID type = GRID
pos = 8,8 pos = 8,8
size = 576x152 size = 576x152
anchor1 = none anchor1 = none
anchor2 = none anchor2 = none
font-family = "" font-family = ""
font-size = 0 font-size = 0
font-style = "" font-style = ""
text-color = #ffffff text-color = #ffffff
background-color = #000000 background-color = #000000
is-visible = true is-visible = true
is-disabled = false is-disabled = false
is-transparent = false is-transparent = false
is-default = false is-default = false
border = none border = none
drop-zone = true drop-zone = true
right-click = false right-click = false
saved-params = "" saved-params = ""
on-size = "" on-size = ""
cells = 1x1 cells = 1x1
current-cell = 1,1 current-cell = 1,1
show-lines = none show-lines = none
small-icons = true small-icons = true
show-names = true show-names = true
enable-http-images = false enable-http-images = false
link-color = #0000ff link-color = #0000ff
visited-color = #ff00ff visited-color = #ff00ff
line-color = #c0c0c0 line-color = #c0c0c0
style = "" style = ""
is-list = false is-list = false
elem "output1" elem "output1"
type = OUTPUT type = OUTPUT
pos = 8,168 pos = 8,168
size = 576x56 size = 576x56
anchor1 = none anchor1 = none
anchor2 = none anchor2 = none
font-family = "" font-family = ""
font-size = 0 font-size = 0
font-style = "" font-style = ""
text-color = #ffffff text-color = #ffffff
background-color = #000000 background-color = #000000
is-visible = true is-visible = true
is-disabled = false is-disabled = false
is-transparent = false is-transparent = false
is-default = true is-default = true
border = none border = none
drop-zone = false drop-zone = false
right-click = false right-click = false
saved-params = "max-lines" saved-params = "max-lines"
on-size = "" on-size = ""
link-color = #0000ff link-color = #0000ff
visited-color = #ff00ff visited-color = #ff00ff
style = "" style = ""
enable-http-images = false enable-http-images = false
max-lines = 1000 max-lines = 1000
image = "" image = ""

View File

@@ -1,150 +1,150 @@
/* /*
Written by contributor Doohl for the /tg/station Open Source project, hosted on Google Code. Written by contributor Doohl for the /tg/station Open Source project, hosted on Google Code.
(2012) (2012)
NOTE: The below functions are part of BYOND user Deadron's "TextHandling" library. NOTE: The below functions are part of BYOND user Deadron's "TextHandling" library.
[ http://www.byond.com/developer/Deadron/TextHandling ] [ http://www.byond.com/developer/Deadron/TextHandling ]
*/ */
proc proc
/////////////////// ///////////////////
// Reading files // // Reading files //
/////////////////// ///////////////////
dd_file2list(file_path, separator = "\n") dd_file2list(file_path, separator = "\n")
var/file var/file
if (isfile(file_path)) if (isfile(file_path))
file = file_path file = file_path
else else
file = file(file_path) file = file(file_path)
return dd_text2list(file2text(file), separator) return dd_text2list(file2text(file), separator)
//////////////////// ////////////////////
// Replacing text // // Replacing text //
//////////////////// ////////////////////
dd_replacetext(text, search_string, replacement_string) dd_replacetext(text, search_string, replacement_string)
// A nice way to do this is to split the text into an array based on the search_string, // A nice way to do this is to split the text into an array based on the search_string,
// then put it back together into text using replacement_string as the new separator. // then put it back together into text using replacement_string as the new separator.
var/list/textList = dd_text2list(text, search_string) var/list/textList = dd_text2list(text, search_string)
return dd_list2text(textList, replacement_string) return dd_list2text(textList, replacement_string)
dd_replaceText(text, search_string, replacement_string) dd_replaceText(text, search_string, replacement_string)
var/list/textList = dd_text2List(text, search_string) var/list/textList = dd_text2List(text, search_string)
return dd_list2text(textList, replacement_string) return dd_list2text(textList, replacement_string)
///////////////////// /////////////////////
// Prefix checking // // Prefix checking //
///////////////////// /////////////////////
dd_hasprefix(text, prefix) dd_hasprefix(text, prefix)
var/start = 1 var/start = 1
var/end = lentext(prefix) + 1 var/end = lentext(prefix) + 1
return findtext(text, prefix, start, end) return findtext(text, prefix, start, end)
dd_hasPrefix(text, prefix) dd_hasPrefix(text, prefix)
var/start = 1 var/start = 1
var/end = lentext(prefix) + 1 var/end = lentext(prefix) + 1
return findtextEx(text, prefix, start, end) return findtextEx(text, prefix, start, end)
///////////////////// /////////////////////
// Suffix checking // // Suffix checking //
///////////////////// /////////////////////
dd_hassuffix(text, suffix) dd_hassuffix(text, suffix)
var/start = length(text) - length(suffix) var/start = length(text) - length(suffix)
if (start) return findtext(text, suffix, start) if (start) return findtext(text, suffix, start)
dd_hasSuffix(text, suffix) dd_hasSuffix(text, suffix)
var/start = length(text) - length(suffix) var/start = length(text) - length(suffix)
if (start) return findtextEx(text, suffix, start) if (start) return findtextEx(text, suffix, start)
///////////////////////////// /////////////////////////////
// Turning text into lists // // Turning text into lists //
///////////////////////////// /////////////////////////////
dd_text2list(text, separator) dd_text2list(text, separator)
var/textlength = lentext(text) var/textlength = lentext(text)
var/separatorlength = lentext(separator) var/separatorlength = lentext(separator)
var/list/textList = new /list() var/list/textList = new /list()
var/searchPosition = 1 var/searchPosition = 1
var/findPosition = 1 var/findPosition = 1
var/buggyText var/buggyText
while (1) // Loop forever. while (1) // Loop forever.
findPosition = findtext(text, separator, searchPosition, 0) findPosition = findtext(text, separator, searchPosition, 0)
buggyText = copytext(text, searchPosition, findPosition) // Everything from searchPosition to findPosition goes into a list element. buggyText = copytext(text, searchPosition, findPosition) // Everything from searchPosition to findPosition goes into a list element.
textList += "[buggyText]" // Working around weird problem where "text" != "text" after this copytext(). textList += "[buggyText]" // Working around weird problem where "text" != "text" after this copytext().
searchPosition = findPosition + separatorlength // Skip over separator. searchPosition = findPosition + separatorlength // Skip over separator.
if (findPosition == 0) // Didn't find anything at end of string so stop here. if (findPosition == 0) // Didn't find anything at end of string so stop here.
return textList return textList
else else
if (searchPosition > textlength) // Found separator at very end of string. if (searchPosition > textlength) // Found separator at very end of string.
textList += "" // So add empty element. textList += "" // So add empty element.
return textList return textList
dd_text2List(text, separator) dd_text2List(text, separator)
var/textlength = lentext(text) var/textlength = lentext(text)
var/separatorlength = lentext(separator) var/separatorlength = lentext(separator)
var/list/textList = new /list() var/list/textList = new /list()
var/searchPosition = 1 var/searchPosition = 1
var/findPosition = 1 var/findPosition = 1
var/buggyText var/buggyText
while (1) // Loop forever. while (1) // Loop forever.
findPosition = findtextEx(text, separator, searchPosition, 0) findPosition = findtextEx(text, separator, searchPosition, 0)
buggyText = copytext(text, searchPosition, findPosition) // Everything from searchPosition to findPosition goes into a list element. buggyText = copytext(text, searchPosition, findPosition) // Everything from searchPosition to findPosition goes into a list element.
textList += "[buggyText]" // Working around weird problem where "text" != "text" after this copytext(). textList += "[buggyText]" // Working around weird problem where "text" != "text" after this copytext().
searchPosition = findPosition + separatorlength // Skip over separator. searchPosition = findPosition + separatorlength // Skip over separator.
if (findPosition == 0) // Didn't find anything at end of string so stop here. if (findPosition == 0) // Didn't find anything at end of string so stop here.
return textList return textList
else else
if (searchPosition > textlength) // Found separator at very end of string. if (searchPosition > textlength) // Found separator at very end of string.
textList += "" // So add empty element. textList += "" // So add empty element.
return textList return textList
dd_list2text(list/the_list, separator) dd_list2text(list/the_list, separator)
var/total = the_list.len var/total = the_list.len
if (total == 0) // Nothing to work with. if (total == 0) // Nothing to work with.
return return
var/newText = "[the_list[1]]" // Treats any object/number as text also. var/newText = "[the_list[1]]" // Treats any object/number as text also.
var/count var/count
for (count = 2, count <= total, count++) for (count = 2, count <= total, count++)
if (separator) newText += separator if (separator) newText += separator
newText += "[the_list[count]]" newText += "[the_list[count]]"
return newText return newText
dd_centertext(message, length) dd_centertext(message, length)
var/new_message = message var/new_message = message
var/size = length(message) var/size = length(message)
if (size == length) if (size == length)
return new_message return new_message
if (size > length) if (size > length)
return copytext(new_message, 1, length + 1) return copytext(new_message, 1, length + 1)
// Need to pad text to center it. // Need to pad text to center it.
var/delta = length - size var/delta = length - size
if (delta == 1) if (delta == 1)
// Add one space after it. // Add one space after it.
return new_message + " " return new_message + " "
// Is this an odd number? If so, add extra space to front. // Is this an odd number? If so, add extra space to front.
if (delta % 2) if (delta % 2)
new_message = " " + new_message new_message = " " + new_message
delta-- delta--
// Divide delta in 2, add those spaces to both ends. // Divide delta in 2, add those spaces to both ends.
delta = delta / 2 delta = delta / 2
var/spaces = "" var/spaces = ""
for (var/count = 1, count <= delta, count++) for (var/count = 1, count <= delta, count++)
spaces += " " spaces += " "
return spaces + new_message + spaces return spaces + new_message + spaces
dd_limittext(message, length) dd_limittext(message, length)
// Truncates text to limit if necessary. // Truncates text to limit if necessary.
var/size = length(message) var/size = length(message)
if (size <= length) if (size <= length)
return message return message
else else
return copytext(message, 1, length + 1) return copytext(message, 1, length + 1)

File diff suppressed because it is too large Load Diff

View File

@@ -1,314 +1,314 @@
/* Runtime Condenser by Nodrak /* Runtime Condenser by Nodrak
* This will sum up identical runtimes into one, giving a total of how many times it occured. The first occurance * This will sum up identical runtimes into one, giving a total of how many times it occured. The first occurance
* of the runtime will log the proc, source, usr and src, the rest will just add to the total. Infinite loops will * of the runtime will log the proc, source, usr and src, the rest will just add to the total. Infinite loops will
* also be caught and displayed (if any) above the list of runtimes. * also be caught and displayed (if any) above the list of runtimes.
* *
* How to use: * How to use:
* 1) Copy and paste your list of runtimes from Dream Daemon into input.exe * 1) Copy and paste your list of runtimes from Dream Daemon into input.exe
* 2) Run RuntimeCondenser.exe * 2) Run RuntimeCondenser.exe
* 3) Open output.txt for a condensed report of the runtimes * 3) Open output.txt for a condensed report of the runtimes
*/ */
#include <iostream> #include <iostream>
#include <fstream> #include <fstream>
#include <string> #include <string>
using namespace std; using namespace std;
//Make all of these global. It's bad yes, but it's a small program so it really doesn't affect anything. //Make all of these global. It's bad yes, but it's a small program so it really doesn't affect anything.
//Because hardcoded numbers are bad :( //Because hardcoded numbers are bad :(
const unsigned short maxStorage = 99; //100 - 1 const unsigned short maxStorage = 99; //100 - 1
//What we use to read input //What we use to read input
string currentLine = "Blank"; string currentLine = "Blank";
string nextLine = "Blank"; string nextLine = "Blank";
//Stores lines we want to keep to print out //Stores lines we want to keep to print out
string storedRuntime[maxStorage+1]; string storedRuntime[maxStorage+1];
string storedProc[maxStorage+1]; string storedProc[maxStorage+1];
string storedSource[maxStorage+1]; string storedSource[maxStorage+1];
string storedUsr[maxStorage+1]; string storedUsr[maxStorage+1];
string storedSrc[maxStorage+1]; string storedSrc[maxStorage+1];
//Stat tracking stuff for output //Stat tracking stuff for output
unsigned int totalRuntimes = 0; unsigned int totalRuntimes = 0;
unsigned int totalUniqueRuntimes = 0; unsigned int totalUniqueRuntimes = 0;
unsigned int totalInfiniteLoops = 0; unsigned int totalInfiniteLoops = 0;
unsigned int totalUniqueInfiniteLoops = 0; unsigned int totalUniqueInfiniteLoops = 0;
//Misc //Misc
unsigned int numRuntime[maxStorage+1]; //Number of times a specific runtime has occured unsigned int numRuntime[maxStorage+1]; //Number of times a specific runtime has occured
bool checkNextLines = false; //Used in case byond has condensed a large number of similar runtimes bool checkNextLines = false; //Used in case byond has condensed a large number of similar runtimes
int storedIterator = 0; //Used to remember where we stored the runtime int storedIterator = 0; //Used to remember where we stored the runtime
bool readFromFile() bool readFromFile()
{ {
//Open file to read //Open file to read
ifstream inputFile("input.txt"); ifstream inputFile("input.txt");
if(inputFile.is_open()) if(inputFile.is_open())
{ {
while(!inputFile.eof()) //Until end of file while(!inputFile.eof()) //Until end of file
{ {
//If we've run out of storage //If we've run out of storage
if(storedRuntime[maxStorage] != "Blank") break; if(storedRuntime[maxStorage] != "Blank") break;
//Update our lines //Update our lines
currentLine = nextLine; currentLine = nextLine;
getline(inputFile, nextLine); getline(inputFile, nextLine);
//After finding a new runtime, check to see if there are extra values to store //After finding a new runtime, check to see if there are extra values to store
if(checkNextLines) if(checkNextLines)
{ {
//Skip ahead //Skip ahead
currentLine = nextLine; currentLine = nextLine;
getline(inputFile, nextLine); getline(inputFile, nextLine);
//If we find this, we have new stuff to store //If we find this, we have new stuff to store
if(nextLine.find("usr:") != std::string::npos) if(nextLine.find("usr:") != std::string::npos)
{ {
//Store more info //Store more info
storedSource[storedIterator] = currentLine; storedSource[storedIterator] = currentLine;
storedUsr[storedIterator] = nextLine; storedUsr[storedIterator] = nextLine;
//Skip ahead again //Skip ahead again
currentLine = nextLine; currentLine = nextLine;
getline(inputFile, nextLine); getline(inputFile, nextLine);
//Store the last of the info //Store the last of the info
storedSrc[storedIterator] = nextLine; storedSrc[storedIterator] = nextLine;
} }
checkNextLines = false; checkNextLines = false;
} }
//Found an infinite loop! //Found an infinite loop!
if(currentLine.find("Infinite loop suspected") != std::string::npos || currentLine.find("Maximum recursion level reached") != std::string::npos) if(currentLine.find("Infinite loop suspected") != std::string::npos || currentLine.find("Maximum recursion level reached") != std::string::npos)
{ {
totalInfiniteLoops++; totalInfiniteLoops++;
for(int i=0; i <= maxStorage; i++) for(int i=0; i <= maxStorage; i++)
{ {
//We've already encountered this //We've already encountered this
if(currentLine == storedRuntime[i]) if(currentLine == storedRuntime[i])
{ {
numRuntime[i]++; numRuntime[i]++;
break; break;
} }
//We've never encoutnered this //We've never encoutnered this
if(storedRuntime[i] == "Blank") if(storedRuntime[i] == "Blank")
{ {
storedRuntime[i] = currentLine; storedRuntime[i] = currentLine;
currentLine = nextLine; currentLine = nextLine;
getline(inputFile, nextLine); //Skip the "if this is not an infinite loop" line getline(inputFile, nextLine); //Skip the "if this is not an infinite loop" line
storedProc[i] = nextLine; storedProc[i] = nextLine;
numRuntime[i] = 1; numRuntime[i] = 1;
checkNextLines = true; checkNextLines = true;
storedIterator = i; storedIterator = i;
totalUniqueInfiniteLoops++; totalUniqueInfiniteLoops++;
break; break;
} }
} }
} }
//Found a runtime! //Found a runtime!
else if(currentLine.find("runtime error:") != std::string::npos) else if(currentLine.find("runtime error:") != std::string::npos)
{ {
totalRuntimes++; totalRuntimes++;
for(int i=0; i <= maxStorage; i++) for(int i=0; i <= maxStorage; i++)
{ {
//We've already encountered this //We've already encountered this
if(currentLine == storedRuntime[i]) if(currentLine == storedRuntime[i])
{ {
numRuntime[i]++; numRuntime[i]++;
break; break;
} }
//We've never encoutnered this //We've never encoutnered this
if(storedRuntime[i] == "Blank") if(storedRuntime[i] == "Blank")
{ {
storedRuntime[i] = currentLine; storedRuntime[i] = currentLine;
storedProc[i] = nextLine; storedProc[i] = nextLine;
numRuntime[i] = 1; numRuntime[i] = 1;
checkNextLines = true; checkNextLines = true;
storedIterator = i; storedIterator = i;
totalUniqueRuntimes++; totalUniqueRuntimes++;
break; break;
} }
} }
} }
} }
} }
else else
{ {
return false; return false;
} }
return true; return true;
} }
bool writeToFile() bool writeToFile()
{ {
//Open and clear the file //Open and clear the file
ofstream outputFile("Output.txt", ios::trunc); ofstream outputFile("Output.txt", ios::trunc);
if(outputFile.is_open()) if(outputFile.is_open())
{ {
outputFile << "Note: The proc name, source file, src and usr are all from the FIRST of the identical runtimes. Everything else is cropped.\n\n"; outputFile << "Note: The proc name, source file, src and usr are all from the FIRST of the identical runtimes. Everything else is cropped.\n\n";
if(totalUniqueInfiniteLoops > 0) if(totalUniqueInfiniteLoops > 0)
{ {
outputFile << "Total unique infinite loops: " << totalUniqueInfiniteLoops << endl; outputFile << "Total unique infinite loops: " << totalUniqueInfiniteLoops << endl;
} }
if(totalInfiniteLoops > 0) if(totalInfiniteLoops > 0)
{ {
outputFile << "Total infinite loops: " << totalInfiniteLoops << endl; outputFile << "Total infinite loops: " << totalInfiniteLoops << endl;
} }
outputFile << "Total unique runtimes: " << totalUniqueRuntimes << endl; outputFile << "Total unique runtimes: " << totalUniqueRuntimes << endl;
outputFile << "Total runtimes: " << totalRuntimes << endl << endl; outputFile << "Total runtimes: " << totalRuntimes << endl << endl;
//Display a warning if we've hit the maximum space we've allocated for storage //Display a warning if we've hit the maximum space we've allocated for storage
if(totalUniqueRuntimes + totalUniqueInfiniteLoops >= maxStorage) if(totalUniqueRuntimes + totalUniqueInfiniteLoops >= maxStorage)
{ {
outputFile << "Warning: The maximum number of unique runtimes has been hit. If there were more, they have been cropped out.\n\n"; outputFile << "Warning: The maximum number of unique runtimes has been hit. If there were more, they have been cropped out.\n\n";
} }
//If we have infinite loops, display them first. //If we have infinite loops, display them first.
if(totalInfiniteLoops > 0) if(totalInfiniteLoops > 0)
{ {
outputFile << "** Infinite loops **"; outputFile << "** Infinite loops **";
for(int i=0; i <= maxStorage; i++) for(int i=0; i <= maxStorage; i++)
{ {
if(storedRuntime[i].find("Infinite loop suspected") != std::string::npos || storedRuntime[i].find("Maximum recursion level reached") != std::string::npos) if(storedRuntime[i].find("Infinite loop suspected") != std::string::npos || storedRuntime[i].find("Maximum recursion level reached") != std::string::npos)
{ {
if(numRuntime[i] != 0) outputFile << endl << endl << "The following infinite loop has occured " << numRuntime[i] << " time(s).\n"; if(numRuntime[i] != 0) outputFile << endl << endl << "The following infinite loop has occured " << numRuntime[i] << " time(s).\n";
if(storedRuntime[i] != "Blank") outputFile << storedRuntime[i] << endl; if(storedRuntime[i] != "Blank") outputFile << storedRuntime[i] << endl;
if(storedProc[i] != "Blank") outputFile << storedProc[i] << endl; if(storedProc[i] != "Blank") outputFile << storedProc[i] << endl;
if(storedSource[i] != "Blank") outputFile << storedSource[i] << endl; if(storedSource[i] != "Blank") outputFile << storedSource[i] << endl;
if(storedUsr[i] != "Blank") outputFile << storedUsr[i] << endl; if(storedUsr[i] != "Blank") outputFile << storedUsr[i] << endl;
if(storedSrc[i] != "Blank") outputFile << storedSrc[i] << endl; if(storedSrc[i] != "Blank") outputFile << storedSrc[i] << endl;
} }
} }
outputFile << endl << endl; //For spacing outputFile << endl << endl; //For spacing
} }
//Do runtimes next //Do runtimes next
outputFile << "** Runtimes **"; outputFile << "** Runtimes **";
for(int i=0; i <= maxStorage; i++) for(int i=0; i <= maxStorage; i++)
{ {
if(storedRuntime[i].find("Infinite loop suspected") != std::string::npos || storedRuntime[i].find("Maximum recursion level reached") != std::string::npos) continue; if(storedRuntime[i].find("Infinite loop suspected") != std::string::npos || storedRuntime[i].find("Maximum recursion level reached") != std::string::npos) continue;
if(numRuntime[i] != 0) outputFile << endl << endl << "The following runtime has occured " << numRuntime[i] << " time(s).\n"; if(numRuntime[i] != 0) outputFile << endl << endl << "The following runtime has occured " << numRuntime[i] << " time(s).\n";
if(storedRuntime[i] != "Blank") outputFile << storedRuntime[i] << endl; if(storedRuntime[i] != "Blank") outputFile << storedRuntime[i] << endl;
if(storedProc[i] != "Blank") outputFile << storedProc[i] << endl; if(storedProc[i] != "Blank") outputFile << storedProc[i] << endl;
if(storedSource[i] != "Blank") outputFile << storedSource[i] << endl; if(storedSource[i] != "Blank") outputFile << storedSource[i] << endl;
if(storedUsr[i] != "Blank") outputFile << storedUsr[i] << endl; if(storedUsr[i] != "Blank") outputFile << storedUsr[i] << endl;
if(storedSrc[i] != "Blank") outputFile << storedSrc[i] << endl; if(storedSrc[i] != "Blank") outputFile << storedSrc[i] << endl;
} }
outputFile.close(); outputFile.close();
} }
else else
{ {
return false; return false;
} }
return true; return true;
} }
void sortRuntimes() void sortRuntimes()
{ {
string tempRuntime[maxStorage+1]; string tempRuntime[maxStorage+1];
string tempProc[maxStorage+1]; string tempProc[maxStorage+1];
string tempSource[maxStorage+1]; string tempSource[maxStorage+1];
string tempUsr[maxStorage+1]; string tempUsr[maxStorage+1];
string tempSrc[maxStorage+1]; string tempSrc[maxStorage+1];
unsigned int tempNumRuntime[maxStorage+1]; unsigned int tempNumRuntime[maxStorage+1];
unsigned int highestCount = 0; //Used for descending order unsigned int highestCount = 0; //Used for descending order
// int keepLooping = 0; // int keepLooping = 0;
//Move all of our data into temporary arrays. Also clear the stored data (not necessary but.. just incase) //Move all of our data into temporary arrays. Also clear the stored data (not necessary but.. just incase)
for(int i=0; i <= maxStorage; i++) for(int i=0; i <= maxStorage; i++)
{ {
//Get the largest occurance of a single runtime //Get the largest occurance of a single runtime
if(highestCount < numRuntime[i]) if(highestCount < numRuntime[i])
{ {
highestCount = numRuntime[i]; highestCount = numRuntime[i];
} }
tempRuntime[i] = storedRuntime[i]; storedRuntime[i] = "Blank"; tempRuntime[i] = storedRuntime[i]; storedRuntime[i] = "Blank";
tempProc[i] = storedProc[i]; storedProc[i] = "Blank"; tempProc[i] = storedProc[i]; storedProc[i] = "Blank";
tempSource[i] = storedSource[i]; storedSource[i] = "Blank"; tempSource[i] = storedSource[i]; storedSource[i] = "Blank";
tempUsr[i] = storedUsr[i]; storedUsr[i] = "Blank"; tempUsr[i] = storedUsr[i]; storedUsr[i] = "Blank";
tempSrc[i] = storedSrc[i]; storedSrc[i] = "Blank"; tempSrc[i] = storedSrc[i]; storedSrc[i] = "Blank";
tempNumRuntime[i] = numRuntime[i]; numRuntime[i] = 0; tempNumRuntime[i] = numRuntime[i]; numRuntime[i] = 0;
} }
while(highestCount > 0) while(highestCount > 0)
{ {
for(int i=0; i <= maxStorage; i++) //For every runtime for(int i=0; i <= maxStorage; i++) //For every runtime
{ {
if(tempNumRuntime[i] == highestCount) //If the number of occurances of that runtime is equal to our current highest if(tempNumRuntime[i] == highestCount) //If the number of occurances of that runtime is equal to our current highest
{ {
for(int j=0; j <= maxStorage; j++) //Find the next available slot and store the info for(int j=0; j <= maxStorage; j++) //Find the next available slot and store the info
{ {
if(storedRuntime[j] == "Blank") //Found an empty spot if(storedRuntime[j] == "Blank") //Found an empty spot
{ {
storedRuntime[j] = tempRuntime[i]; storedRuntime[j] = tempRuntime[i];
storedProc[j] = tempProc[i]; storedProc[j] = tempProc[i];
storedSource[j] = tempSource[i]; storedSource[j] = tempSource[i];
storedUsr[j] = tempUsr[i]; storedUsr[j] = tempUsr[i];
storedSrc[j] = tempSrc[i]; storedSrc[j] = tempSrc[i];
numRuntime[j] = tempNumRuntime[i]; numRuntime[j] = tempNumRuntime[i];
break; break;
} }
} }
} }
} }
highestCount--; //Lower our 'highest' by one and continue highestCount--; //Lower our 'highest' by one and continue
} }
} }
int main() { int main() {
char exit; //Used to stop the program from immediatly exiting char exit; //Used to stop the program from immediatly exiting
//Start everything fresh. "Blank" should never occur in the runtime logs on its own. //Start everything fresh. "Blank" should never occur in the runtime logs on its own.
for(int i=0; i <= maxStorage; i++) for(int i=0; i <= maxStorage; i++)
{ {
storedRuntime[i] = "Blank"; storedRuntime[i] = "Blank";
storedProc[i] = "Blank"; storedProc[i] = "Blank";
storedSource[i] = "Blank"; storedSource[i] = "Blank";
storedUsr[i] = "Blank"; storedUsr[i] = "Blank";
storedSrc[i] = "Blank"; storedSrc[i] = "Blank";
numRuntime[i] = 0; numRuntime[i] = 0;
} }
if(readFromFile()) if(readFromFile())
{ {
cout << "Input read successfully!\n"; cout << "Input read successfully!\n";
} }
else else
{ {
cout << "Input failed to open, shutting down.\n"; cout << "Input failed to open, shutting down.\n";
cout << "\nEnter any letter to quit.\n"; cout << "\nEnter any letter to quit.\n";
cin >> exit; cin >> exit;
return 1; return 1;
} }
sortRuntimes(); sortRuntimes();
if(writeToFile()) if(writeToFile())
{ {
cout << "Output was successful!\n"; cout << "Output was successful!\n";
cout << "\nEnter any letter to quit.\n"; cout << "\nEnter any letter to quit.\n";
cin >> exit; cin >> exit;
return 0; return 0;
} }
else else
{ {
cout << "The output file could not be opened, shutting down.\n"; cout << "The output file could not be opened, shutting down.\n";
cout << "\nEnter any letter to quit.\n"; cout << "\nEnter any letter to quit.\n";
cin >> exit; cin >> exit;
return 0; return 0;
} }
return 0; return 0;
} }

View File

@@ -1,190 +1,190 @@
Note: The proc name, source file, src and usr are all from the FIRST of the identical runtimes. Everything else is cropped. Note: The proc name, source file, src and usr are all from the FIRST of the identical runtimes. Everything else is cropped.
Total unique runtimes: 25 Total unique runtimes: 25
Total runtimes: 767 Total runtimes: 767
** Runtimes ** ** Runtimes **
The following runtime has occured 269 time(s). The following runtime has occured 269 time(s).
runtime error: Cannot read null.viruses runtime error: Cannot read null.viruses
proc name: cure (/datum/disease/proc/cure) proc name: cure (/datum/disease/proc/cure)
source file: disease.dm,156 source file: disease.dm,156
usr: null usr: null
src: Space Retrovirus (/datum/disease/dnaspread) src: Space Retrovirus (/datum/disease/dnaspread)
The following runtime has occured 199 time(s). The following runtime has occured 199 time(s).
runtime error: Cannot read null.has_gravity runtime error: Cannot read null.has_gravity
proc name: throw at (/atom/movable/proc/throw_at) proc name: throw at (/atom/movable/proc/throw_at)
source file: throwing.dm,194 source file: throwing.dm,194
usr: Reese Marcotte (/mob/living/carbon/human) usr: Reese Marcotte (/mob/living/carbon/human)
src: Reese Marcotte (/mob/living/carbon/human) src: Reese Marcotte (/mob/living/carbon/human)
The following runtime has occured 165 time(s). The following runtime has occured 165 time(s).
runtime error: Cannot read null.slot_flags runtime error: Cannot read null.slot_flags
proc name: db click (/mob/living/carbon/human/db_click) proc name: db click (/mob/living/carbon/human/db_click)
source file: inventory.dm,1083 source file: inventory.dm,1083
usr: Puke Chunks (/mob/living/carbon/human) usr: Puke Chunks (/mob/living/carbon/human)
src: Puke Chunks (/mob/living/carbon/human) src: Puke Chunks (/mob/living/carbon/human)
The following runtime has occured 25 time(s). The following runtime has occured 25 time(s).
runtime error: Cannot read null.flags runtime error: Cannot read null.flags
proc name: relaymove (/obj/effect/dummy/spell_jaunt/relaymove) proc name: relaymove (/obj/effect/dummy/spell_jaunt/relaymove)
The following runtime has occured 24 time(s). The following runtime has occured 24 time(s).
runtime error: Cannot read null.len runtime error: Cannot read null.len
proc name: mergeRecordLists (/proc/mergeRecordLists) proc name: mergeRecordLists (/proc/mergeRecordLists)
source file: helpers.dm,260 source file: helpers.dm,260
usr: Wintermute (/mob/living/silicon/ai) usr: Wintermute (/mob/living/silicon/ai)
src: null src: null
The following runtime has occured 20 time(s). The following runtime has occured 20 time(s).
runtime error: Cannot read null.total_volume runtime error: Cannot read null.total_volume
proc name: attackby (/obj/machinery/reagentgrinder/attackby) proc name: attackby (/obj/machinery/reagentgrinder/attackby)
source file: Chemistry-Machinery.dm,751 source file: Chemistry-Machinery.dm,751
usr: Reese Marcotte (/mob/living/carbon/human) usr: Reese Marcotte (/mob/living/carbon/human)
src: All-In-One Grinder (/obj/machinery/reagentgrinder) src: All-In-One Grinder (/obj/machinery/reagentgrinder)
The following runtime has occured 16 time(s). The following runtime has occured 16 time(s).
runtime error: Cannot read null.broadcasting runtime error: Cannot read null.broadcasting
proc name: radio menu (/mob/living/silicon/robot/proc/radio_menu) proc name: radio menu (/mob/living/silicon/robot/proc/radio_menu)
source file: robot.dm,857 source file: robot.dm,857
usr: Engineering Cyborg -432 (/mob/living/silicon/robot) usr: Engineering Cyborg -432 (/mob/living/silicon/robot)
src: Engineering Cyborg -432 (/mob/living/silicon/robot) src: Engineering Cyborg -432 (/mob/living/silicon/robot)
The following runtime has occured 7 time(s). The following runtime has occured 7 time(s).
runtime error: unexpected stat runtime error: unexpected stat
proc name: Stat (/mob/living/silicon/robot/Stat) proc name: Stat (/mob/living/silicon/robot/Stat)
source file: robot.dm,227 source file: robot.dm,227
usr: Michigan Slim (/mob/living/carbon/human) usr: Michigan Slim (/mob/living/carbon/human)
src: Engineering Cyborg -133 (/mob/living/silicon/robot) src: Engineering Cyborg -133 (/mob/living/silicon/robot)
The following runtime has occured 7 time(s). The following runtime has occured 7 time(s).
runtime error: Cannot read null.current runtime error: Cannot read null.current
proc name: check completion (/datum/objective/download/check_completion) proc name: check completion (/datum/objective/download/check_completion)
source file: objective.dm,411 source file: objective.dm,411
usr: null usr: null
src: /datum/objective/download (/datum/objective/download) src: /datum/objective/download (/datum/objective/download)
The following runtime has occured 6 time(s). The following runtime has occured 6 time(s).
runtime error: Cannot create objects of type null. runtime error: Cannot create objects of type null.
proc name: Topic (/obj/machinery/computer/rdconsole/Topic) proc name: Topic (/obj/machinery/computer/rdconsole/Topic)
source file: rdconsole.dm,381 source file: rdconsole.dm,381
usr: Matthew Hoff (/mob/living/carbon/human) usr: Matthew Hoff (/mob/living/carbon/human)
src: Core R&D Console (/obj/machinery/computer/rdconsole/core) src: Core R&D Console (/obj/machinery/computer/rdconsole/core)
The following runtime has occured 6 time(s). The following runtime has occured 6 time(s).
runtime error: Cannot read null.fields runtime error: Cannot read null.fields
proc name: mergeRecordLists (/proc/mergeRecordLists) proc name: mergeRecordLists (/proc/mergeRecordLists)
source file: helpers.dm,263 source file: helpers.dm,263
usr: Wintermute (/mob/living/silicon/ai) usr: Wintermute (/mob/living/silicon/ai)
src: null src: null
The following runtime has occured 3 time(s). The following runtime has occured 3 time(s).
runtime error: undefined variable /client/var/loc runtime error: undefined variable /client/var/loc
proc name: get turf (/proc/get_turf) proc name: get turf (/proc/get_turf)
source file: helper_procs.dm,38 source file: helper_procs.dm,38
usr: the ghost (/mob/dead/observer) usr: the ghost (/mob/dead/observer)
src: null src: null
The following runtime has occured 3 time(s). The following runtime has occured 3 time(s).
runtime error: Cannot read null.nodes runtime error: Cannot read null.nodes
proc name: merge powernets (/datum/powernet/proc/merge_powernets) proc name: merge powernets (/datum/powernet/proc/merge_powernets)
source file: power.dm,401 source file: power.dm,401
usr: Darin Keppel (/mob/living/carbon/human) usr: Darin Keppel (/mob/living/carbon/human)
src: /datum/powernet (/datum/powernet) src: /datum/powernet (/datum/powernet)
The following runtime has occured 3 time(s). The following runtime has occured 3 time(s).
runtime error: Cannot read null.reagents runtime error: Cannot read null.reagents
proc name: fire syringe (/obj/item/weapon/gun/syringe/proc/fire_syringe) proc name: fire syringe (/obj/item/weapon/gun/syringe/proc/fire_syringe)
The following runtime has occured 2 time(s). The following runtime has occured 2 time(s).
runtime error: undefined proc or verb /obj/machinery/space_heater/attack(). runtime error: undefined proc or verb /obj/machinery/space_heater/attack().
The following runtime has occured 2 time(s). The following runtime has occured 2 time(s).
runtime error: list index out of bounds runtime error: list index out of bounds
proc name: mergeConnectedNetworksOnTurf (/obj/structure/cable/proc/mergeConnectedNetworksOnTurf) proc name: mergeConnectedNetworksOnTurf (/obj/structure/cable/proc/mergeConnectedNetworksOnTurf)
source file: cable.dm,520 source file: cable.dm,520
usr: Josue Sandford (/mob/living/carbon/human) usr: Josue Sandford (/mob/living/carbon/human)
src: the power cable (/obj/structure/cable) src: the power cable (/obj/structure/cable)
The following runtime has occured 2 time(s). The following runtime has occured 2 time(s).
runtime error: Cannot read null.loc runtime error: Cannot read null.loc
proc name: Life (/mob/living/simple_animal/corgi/Ian/Life) proc name: Life (/mob/living/simple_animal/corgi/Ian/Life)
source file: corgi.dm,304 source file: corgi.dm,304
usr: null usr: null
src: Captain Ian (/mob/living/simple_animal/corgi/Ian) src: Captain Ian (/mob/living/simple_animal/corgi/Ian)
The following runtime has occured 1 time(s). The following runtime has occured 1 time(s).
runtime error: undefined proc or verb /obj/machinery/portable_atmospherics/canister/toxins/attack(). runtime error: undefined proc or verb /obj/machinery/portable_atmospherics/canister/toxins/attack().
The following runtime has occured 1 time(s). The following runtime has occured 1 time(s).
runtime error: undefined variable /datum/preferences/var/fields runtime error: undefined variable /datum/preferences/var/fields
proc name: Topic (/obj/machinery/computer/cloning/Topic) proc name: Topic (/obj/machinery/computer/cloning/Topic)
source file: cloning.dm,370 source file: cloning.dm,370
usr: Logan Graves (/mob/living/carbon/human) usr: Logan Graves (/mob/living/carbon/human)
src: Cloning console (/obj/machinery/computer/cloning) src: Cloning console (/obj/machinery/computer/cloning)
The following runtime has occured 1 time(s). The following runtime has occured 1 time(s).
runtime error: undefined variable /turf/simulated/floor/plating/var/mineral runtime error: undefined variable /turf/simulated/floor/plating/var/mineral
proc name: attackby (/turf/simulated/wall/attackby) proc name: attackby (/turf/simulated/wall/attackby)
source file: turf.dm,600 source file: turf.dm,600
usr: Monte Smail (/mob/living/carbon/human) usr: Monte Smail (/mob/living/carbon/human)
src: the plating (176,172,5) (/turf/simulated/floor/plating) src: the plating (176,172,5) (/turf/simulated/floor/plating)
The following runtime has occured 1 time(s). The following runtime has occured 1 time(s).
runtime error: Cannot read null.blood_DNA runtime error: Cannot read null.blood_DNA
proc name: update inv w uniform (/mob/living/carbon/human/update_inv_w_uniform) proc name: update inv w uniform (/mob/living/carbon/human/update_inv_w_uniform)
source file: update_icons.dm,372 source file: update_icons.dm,372
usr: null usr: null
src: Chip Harshman (/mob/living/carbon/human) src: Chip Harshman (/mob/living/carbon/human)
The following runtime has occured 1 time(s). The following runtime has occured 1 time(s).
runtime error: Cannot execute null.dropped(). runtime error: Cannot execute null.dropped().
proc name: drop l hand (/mob/proc/drop_l_hand) proc name: drop l hand (/mob/proc/drop_l_hand)
source file: inventory.dm,104 source file: inventory.dm,104
usr: Jeb Stone (/mob/living/carbon/human) usr: Jeb Stone (/mob/living/carbon/human)
src: Jeb Stone (/mob/living/carbon/human) src: Jeb Stone (/mob/living/carbon/human)
The following runtime has occured 1 time(s). The following runtime has occured 1 time(s).
runtime error: Cannot read null.w_class runtime error: Cannot read null.w_class
proc name: attackby (/obj/item/weapon/storage/attackby) proc name: attackby (/obj/item/weapon/storage/attackby)
source file: storage.dm,187 source file: storage.dm,187
usr: Samuel York (/mob/living/carbon/human) usr: Samuel York (/mob/living/carbon/human)
src: the backpack (/obj/item/weapon/storage/backpack) src: the backpack (/obj/item/weapon/storage/backpack)
The following runtime has occured 1 time(s). The following runtime has occured 1 time(s).
runtime error: Cannot read null.amount runtime error: Cannot read null.amount
proc name: attackby (/obj/machinery/constructable_frame/machine_frame/attackby) proc name: attackby (/obj/machinery/constructable_frame/machine_frame/attackby)
source file: constructable_frame.dm,27 source file: constructable_frame.dm,27
usr: Quinton Bould (/mob/living/carbon/human) usr: Quinton Bould (/mob/living/carbon/human)
src: the machine frame (/obj/machinery/constructable_frame/machine_frame) src: the machine frame (/obj/machinery/constructable_frame/machine_frame)
The following runtime has occured 1 time(s). The following runtime has occured 1 time(s).
runtime error: Cannot modify null.status. runtime error: Cannot modify null.status.
proc name: death (/mob/living/silicon/robot/death) proc name: death (/mob/living/silicon/robot/death)

View File

@@ -1,90 +1,90 @@
#!/usr/bin/env python #!/usr/bin/env python
import re, os, sys, fnmatch import re, os, sys, fnmatch
# Regex pattern to extract the directory path in a #define FILE_DIR # Regex pattern to extract the directory path in a #define FILE_DIR
filedir_pattern = re.compile(r'^#define\s*FILE_DIR\s*"(.*?)"') filedir_pattern = re.compile(r'^#define\s*FILE_DIR\s*"(.*?)"')
# Regex pattern to extract any single quoted piece of text. This can also # Regex pattern to extract any single quoted piece of text. This can also
# match single quoted strings inside of double quotes, which is part of a # match single quoted strings inside of double quotes, which is part of a
# regular text string and should not be replaced. The replacement function # regular text string and should not be replaced. The replacement function
# however will any match that doesn't appear to be a filename so these # however will any match that doesn't appear to be a filename so these
# extra matches should not be a problem. # extra matches should not be a problem.
rename_pattern = re.compile(r"'(.+?)'") rename_pattern = re.compile(r"'(.+?)'")
# Only filenames matching this pattern will have their resources renamed # Only filenames matching this pattern will have their resources renamed
source_pattern = re.compile(r"^.*?\.(dm|dmm)$") source_pattern = re.compile(r"^.*?\.(dm|dmm)$")
# Open the .dme file and return a list of all FILE_DIR paths in it # Open the .dme file and return a list of all FILE_DIR paths in it
def read_filedirs(filename): def read_filedirs(filename):
result = [] result = []
with open(filename, "rt") as dme_file: with open(filename, "rt") as dme_file:
# Read each line from the file and check for regex pattern match # Read each line from the file and check for regex pattern match
for row in dme_file: for row in dme_file:
match = filedir_pattern.match(row) match = filedir_pattern.match(row)
if match: if match:
result.append(match.group(1)) result.append(match.group(1))
return result return result
# Search through a list of directories, and build a dictionary which # Search through a list of directories, and build a dictionary which
# maps every file to its full pathname (relative to the .dme file) # maps every file to its full pathname (relative to the .dme file)
# If the same filename appears in more than one directory, the earlier # If the same filename appears in more than one directory, the earlier
# directory in the list takes preference. # directory in the list takes preference.
def index_files(file_dirs): def index_files(file_dirs):
result = {} result = {}
# Reverse the directory list so the earlier directories take precedence # Reverse the directory list so the earlier directories take precedence
# by replacing the previously indexed file of the same name # by replacing the previously indexed file of the same name
for directory in reversed(file_dirs): for directory in reversed(file_dirs):
for name in os.listdir(directory): for name in os.listdir(directory):
# Replace backslash path separators on Windows with forward slash # Replace backslash path separators on Windows with forward slash
# Force "name" to lowercase when used as a key since BYOND resource # Force "name" to lowercase when used as a key since BYOND resource
# names are case insensitive, even on Linux. # names are case insensitive, even on Linux.
if name.find(".") == -1: if name.find(".") == -1:
continue continue
result[name.lower()] = directory.replace('\\', '/') + '/' + name result[name.lower()] = directory.replace('\\', '/') + '/' + name
return result return result
# Recursively search for every .dm/.dmm file in the .dme file directory. For # Recursively search for every .dm/.dmm file in the .dme file directory. For
# each file, search it for any resource names in single quotes, and replace # each file, search it for any resource names in single quotes, and replace
# them with the full path previously found by index_files() # them with the full path previously found by index_files()
def rewrite_sources(resources): def rewrite_sources(resources):
# Create a closure for the regex replacement function to capture the # Create a closure for the regex replacement function to capture the
# resources dictionary which can't be passed directly to this function # resources dictionary which can't be passed directly to this function
def replace_func(name): def replace_func(name):
key = name.group(1).lower() key = name.group(1).lower()
if key in resources: if key in resources:
replacement = resources[key] replacement = resources[key]
else: else:
replacement = name.group(1) replacement = name.group(1)
return "'" + replacement + "'" return "'" + replacement + "'"
# Search recursively for all .dm and .dmm files # Search recursively for all .dm and .dmm files
for (dirpath, dirs, files) in os.walk("."): for (dirpath, dirs, files) in os.walk("."):
for name in files: for name in files:
if source_pattern.match(name): if source_pattern.match(name):
path = dirpath + '/' + name path = dirpath + '/' + name
source_file = open(path, "rt") source_file = open(path, "rt")
output_file = open(path + ".tmp", "wt") output_file = open(path + ".tmp", "wt")
# Read file one line at a time and perform replacement of all # Read file one line at a time and perform replacement of all
# single quoted resource names with the fullpath to that resource # single quoted resource names with the fullpath to that resource
# file. Write the updated text back out to a temporary file. # file. Write the updated text back out to a temporary file.
for row in source_file: for row in source_file:
row = rename_pattern.sub(replace_func, row) row = rename_pattern.sub(replace_func, row)
output_file.write(row) output_file.write(row)
output_file.close() output_file.close()
source_file.close() source_file.close()
# Delete original source file and replace with the temporary # Delete original source file and replace with the temporary
# output. On Windows, an atomic rename() operation is not # output. On Windows, an atomic rename() operation is not
# possible like it is under POSIX. # possible like it is under POSIX.
os.remove(path) os.remove(path)
os.rename(path + ".tmp", path) os.rename(path + ".tmp", path)
dirs = read_filedirs("vgstation13.dme"); dirs = read_filedirs("vgstation13.dme");
resources = index_files(dirs) resources = index_files(dirs)
rewrite_sources(resources) rewrite_sources(resources)