diff --git a/Redirector/Configurations.dm b/Redirector/Configurations.dm new file mode 100644 index 00000000000..6b89ace90d5 --- /dev/null +++ b/Redirector/Configurations.dm @@ -0,0 +1,53 @@ +/* + Written by contributor Doohl for the /tg/station Open Source project, hosted on Google Code. + (2012) + */ + +var/list/config_stream = list() +var/list/servers = list() +var/list/servernames = list() +var/list/adminfiles = list() +var/list/adminkeys = list() + +proc/gen_configs() + + config_stream = dd_file2list("config.txt") + + var/server_gen = 0 // if the stream is looking for servers + var/admin_gen = 0 // if the stream is looking for admins + for(var/line in config_stream) + + if(line == "\[SERVERS\]") + server_gen = 1 + if(admin_gen) + admin_gen = 0 + + else if(line == "\[ADMINS\]") + admin_gen = 1 + if(server_gen) + server_gen = 0 + + else + if(findtext(line, ".") && !findtext(line, "##")) + if(server_gen) + var/filterline = dd_replacetext(line, " ", "") + var/serverlink = copytext(filterline, findtext( filterline, ")") + 1) + servers.Add(serverlink) + servernames.Add( copytext(line, findtext(line, "("), findtext(line, ")") + 1)) + + else if(admin_gen) + adminfiles.Add(line) + world << line + + + // Generate the list of admins now + + for(var/file in adminfiles) + var/admin_config_stream = dd_file2list(file) + + for(var/line in admin_config_stream) + + var/akey = copytext(line, 1, findtext(line, " ")) + adminkeys.Add(akey) + + diff --git a/Redirector/Redirect_Tgstation.dmb b/Redirector/Redirect_Tgstation.dmb new file mode 100644 index 00000000000..278e723b896 Binary files /dev/null and b/Redirector/Redirect_Tgstation.dmb differ diff --git a/Redirector/Redirect_Tgstation.dme b/Redirector/Redirect_Tgstation.dme new file mode 100644 index 00000000000..5868a234d54 --- /dev/null +++ b/Redirector/Redirect_Tgstation.dme @@ -0,0 +1,21 @@ +// DM Environment file for Redirect_Tgstation.dme. +// 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. + +// BEGIN_INTERNALS +// END_INTERNALS + +// BEGIN_FILE_DIR +#define FILE_DIR . +// END_FILE_DIR + +// BEGIN_PREFERENCES +// END_PREFERENCES + +// BEGIN_INCLUDE +#include "Configurations.dm" +#include "Redirector.dm" +#include "textprocs.dm" +#include "skin.dmf" +// END_INCLUDE + diff --git a/Redirector/Redirector.dm b/Redirector/Redirector.dm new file mode 100644 index 00000000000..9ba2096e73c --- /dev/null +++ b/Redirector/Redirector.dm @@ -0,0 +1,87 @@ +/* + Written by contributor Doohl for the /tg/station Open Source project, hosted on Google Code. + (2012) + */ + +/* TODO: work on server selection for detected admins */ + + +#define ADMINS 1 +#define PLAYERS 0 + +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/player_substr = "players=" // search for this substring to locate # of players +var/admin_substr = "admins=" // search for this to locate # of admins + +world + name = "TGstation Redirector" + + New() + ..() + gen_configs() + +/datum/server + var/players = 0 + var/admins = 0 + var/weight = 0 // lower weight is good; highet weight is bad + + var/link = "" + +mob/Login() + ..() + + var/list/weights = list() + var/list/servers = list() + for(var/x in global.servers) + + world << "[x] [servernames[ global.servers.Find(x) ]]" + + var/info = world.Export("[x]?status") + var/datum/server/S = new() + S.players = extract(info, PLAYERS) + S.admins = extract(info, ADMINS) + + S.weight += player_weight * S.players + S.link = x + + world << S.players + world << S.admins + + weights.Add(S.weight) + servers.Add(S) + + var/lowest = min(weights) + var/serverlink + for(var/datum/server/S in servers) + if(S.weight == lowest) + serverlink = S.link + + src << link(serverlink) + +proc/extract(var/data, var/type = PLAYERS) + + var/nextpos = 0 + + if(type == PLAYERS) + + nextpos = findtextEx(data, player_substr) + nextpos += length(player_substr) + + else + + nextpos = findtextEx(data, admin_substr) + nextpos += length(admin_substr) + + var/returnval = "" + + for(var/i = 1, i <= 10, i++) + + var/interval = copytext(data, nextpos + (i-1), nextpos + i) + if(interval == "&") + break + else + returnval += interval + + return returnval diff --git a/Redirector/config.txt b/Redirector/config.txt new file mode 100644 index 00000000000..4b409f5036b --- /dev/null +++ b/Redirector/config.txt @@ -0,0 +1,12 @@ +[SERVERS] +## 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 #2) byond://game.nanotrasen.com:2337 + + +[ADMINS] +## Specify some standard Windows filepaths (you may use relative paths) for admin txt lists to poll. + +C:\SS13\config\admins.txt diff --git a/Redirector/skin.dmf b/Redirector/skin.dmf new file mode 100644 index 00000000000..ffb7b3ddf3c --- /dev/null +++ b/Redirector/skin.dmf @@ -0,0 +1,149 @@ +macro "macro" + elem + name = "North+REP" + command = ".north" + is-disabled = false + elem + name = "South+REP" + command = ".south" + is-disabled = false + elem + name = "East+REP" + command = ".east" + is-disabled = false + elem + name = "West+REP" + command = ".west" + is-disabled = false + elem + name = "Northeast+REP" + command = ".northeast" + is-disabled = false + elem + name = "Northwest+REP" + command = ".northwest" + is-disabled = false + elem + name = "Southeast+REP" + command = ".southeast" + is-disabled = false + elem + name = "Southwest+REP" + command = ".southwest" + is-disabled = false + elem + name = "Center+REP" + command = ".center" + is-disabled = false + + +menu "menu" + elem + name = "&Quit" + command = ".quit" + category = "&File" + is-checked = false + can-check = false + group = "" + is-disabled = false + saved-params = "is-checked" + + +window "window" + elem "window" + type = MAIN + pos = 281,0 + size = 594x231 + anchor1 = none + anchor2 = none + font-family = "" + font-size = 0 + font-style = "" + text-color = #000000 + background-color = #000000 + is-visible = false + is-disabled = false + is-transparent = false + is-default = true + border = none + drop-zone = false + right-click = false + saved-params = "pos;size;is-minimized;is-maximized" + on-size = "" + title = "" + titlebar = true + statusbar = false + can-close = true + can-minimize = true + can-resize = true + is-pane = false + is-minimized = false + is-maximized = false + can-scroll = none + icon = "" + image = "" + image-mode = stretch + keep-aspect = false + transparent-color = none + alpha = 255 + macro = "macro" + menu = "" + on-close = "" + elem "servers" + type = GRID + pos = 8,8 + size = 576x152 + anchor1 = none + anchor2 = none + font-family = "" + font-size = 0 + font-style = "" + text-color = #ffffff + background-color = #000000 + is-visible = true + is-disabled = false + is-transparent = false + is-default = false + border = none + drop-zone = true + right-click = false + saved-params = "" + on-size = "" + cells = 1x1 + current-cell = 1,1 + show-lines = none + small-icons = true + show-names = true + enable-http-images = false + link-color = #0000ff + visited-color = #ff00ff + line-color = #c0c0c0 + style = "" + is-list = false + elem "output1" + type = OUTPUT + pos = 8,168 + size = 576x56 + anchor1 = none + anchor2 = none + font-family = "" + font-size = 0 + font-style = "" + text-color = #ffffff + background-color = #000000 + is-visible = true + is-disabled = false + is-transparent = false + is-default = true + border = none + drop-zone = false + right-click = false + saved-params = "max-lines" + on-size = "" + link-color = #0000ff + visited-color = #ff00ff + style = "" + enable-http-images = false + max-lines = 1000 + image = "" + diff --git a/Redirector/textprocs.dm b/Redirector/textprocs.dm new file mode 100644 index 00000000000..b8d49ade72f --- /dev/null +++ b/Redirector/textprocs.dm @@ -0,0 +1,150 @@ +/* + Written by contributor Doohl for the /tg/station Open Source project, hosted on Google Code. + (2012) + + NOTE: The below functions are part of BYOND user Deadron's "TextHandling" library. + [ http://www.byond.com/developer/Deadron/TextHandling ] + */ + + +proc + /////////////////// + // Reading files // + /////////////////// + dd_file2list(file_path, separator = "\n") + var/file + if (isfile(file_path)) + file = file_path + else + file = file(file_path) + return dd_text2list(file2text(file), separator) + + + //////////////////// + // Replacing text // + //////////////////// + 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, + // then put it back together into text using replacement_string as the new separator. + var/list/textList = dd_text2list(text, search_string) + return dd_list2text(textList, replacement_string) + + + dd_replaceText(text, search_string, replacement_string) + var/list/textList = dd_text2List(text, search_string) + return dd_list2text(textList, replacement_string) + + + ///////////////////// + // Prefix checking // + ///////////////////// + dd_hasprefix(text, prefix) + var/start = 1 + var/end = lentext(prefix) + 1 + return findtext(text, prefix, start, end) + + dd_hasPrefix(text, prefix) + var/start = 1 + var/end = lentext(prefix) + 1 + return findtextEx(text, prefix, start, end) + + + ///////////////////// + // Suffix checking // + ///////////////////// + dd_hassuffix(text, suffix) + var/start = length(text) - length(suffix) + if (start) return findtext(text, suffix, start) + + dd_hasSuffix(text, suffix) + var/start = length(text) - length(suffix) + if (start) return findtextEx(text, suffix, start) + + ///////////////////////////// + // Turning text into lists // + ///////////////////////////// + dd_text2list(text, separator) + var/textlength = lentext(text) + var/separatorlength = lentext(separator) + var/list/textList = new /list() + var/searchPosition = 1 + var/findPosition = 1 + var/buggyText + while (1) // Loop forever. + findPosition = findtext(text, separator, searchPosition, 0) + 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(). + + searchPosition = findPosition + separatorlength // Skip over separator. + if (findPosition == 0) // Didn't find anything at end of string so stop here. + return textList + else + if (searchPosition > textlength) // Found separator at very end of string. + textList += "" // So add empty element. + return textList + + dd_text2List(text, separator) + var/textlength = lentext(text) + var/separatorlength = lentext(separator) + var/list/textList = new /list() + var/searchPosition = 1 + var/findPosition = 1 + var/buggyText + while (1) // Loop forever. + findPosition = findtextEx(text, separator, searchPosition, 0) + 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(). + + searchPosition = findPosition + separatorlength // Skip over separator. + if (findPosition == 0) // Didn't find anything at end of string so stop here. + return textList + else + if (searchPosition > textlength) // Found separator at very end of string. + textList += "" // So add empty element. + return textList + + dd_list2text(list/the_list, separator) + var/total = the_list.len + if (total == 0) // Nothing to work with. + return + + var/newText = "[the_list[1]]" // Treats any object/number as text also. + var/count + for (count = 2, count <= total, count++) + if (separator) newText += separator + newText += "[the_list[count]]" + return newText + + dd_centertext(message, length) + var/new_message = message + var/size = length(message) + if (size == length) + return new_message + if (size > length) + return copytext(new_message, 1, length + 1) + + // Need to pad text to center it. + var/delta = length - size + if (delta == 1) + // Add one space after it. + return new_message + " " + + // Is this an odd number? If so, add extra space to front. + if (delta % 2) + new_message = " " + new_message + delta-- + + // Divide delta in 2, add those spaces to both ends. + delta = delta / 2 + var/spaces = "" + for (var/count = 1, count <= delta, count++) + spaces += " " + return spaces + new_message + spaces + + dd_limittext(message, length) + // Truncates text to limit if necessary. + var/size = length(message) + if (size <= length) + return message + else + return copytext(message, 1, length + 1) \ No newline at end of file