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
This commit is contained in:
vageyenaman@gmail.com
2012-07-01 22:12:32 +00:00
parent eac2093f02
commit ba53e3c6c6
7 changed files with 472 additions and 0 deletions
+53
View File
@@ -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)
Binary file not shown.
+21
View File
@@ -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
+87
View File
@@ -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
+12
View File
@@ -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
+149
View File
@@ -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 = ""
+150
View File
@@ -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)