From ba53e3c6c65955fd1490cdca21afe65d1dd89e1d Mon Sep 17 00:00:00 2001 From: "vageyenaman@gmail.com" Date: Sun, 1 Jul 2012 22:12:32 +0000 Subject: [PATCH] Committing my server autojoiner / traffic regulator code. It's a small BYOND application you can host that will automatically redirect players to the most desireable server (currently, it will only compare player quantities and select the least-populated server). It's not finished yet, but it works for the most part. This is meant to be hosted on the same machine as the servers are hosted on, otherwise the list of admins will not be able to be generated. Be sure to look at config.txt to under the Redirector directory. It's pre-configured but can be modified for other servers' usage. git-svn-id: http://tgstation13.googlecode.com/svn/trunk@3961 316c924e-a436-60f5-8080-3fe189b3f50e --- Redirector/Configurations.dm | 53 +++++++++++ Redirector/Redirect_Tgstation.dmb | Bin 0 -> 12541 bytes Redirector/Redirect_Tgstation.dme | 21 +++++ Redirector/Redirector.dm | 87 +++++++++++++++++ Redirector/config.txt | 12 +++ Redirector/skin.dmf | 149 +++++++++++++++++++++++++++++ Redirector/textprocs.dm | 150 ++++++++++++++++++++++++++++++ 7 files changed, 472 insertions(+) create mode 100644 Redirector/Configurations.dm create mode 100644 Redirector/Redirect_Tgstation.dmb create mode 100644 Redirector/Redirect_Tgstation.dme create mode 100644 Redirector/Redirector.dm create mode 100644 Redirector/config.txt create mode 100644 Redirector/skin.dmf create mode 100644 Redirector/textprocs.dm 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 0000000000000000000000000000000000000000..278e723b89670b64e94073aa8990be9df9cdc997 GIT binary patch literal 12541 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 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