diff --git a/code/game/socket_talk.dm b/code/game/socket_talk.dm
index b6024f3a191..8484b636b8d 100644
--- a/code/game/socket_talk.dm
+++ b/code/game/socket_talk.dm
@@ -23,4 +23,4 @@
return send_raw("type=keepalive")
-var/global/datum/socket_talk/socket_talk
\ No newline at end of file
+var/global/datum/socket_talk/socket_talk
diff --git a/code/modules/admin/player_notes.dm b/code/modules/admin/player_notes.dm
index dd0f69b8f3e..3a74da5fca6 100644
--- a/code/modules/admin/player_notes.dm
+++ b/code/modules/admin/player_notes.dm
@@ -152,3 +152,16 @@ datum/admins/proc/notes_gethtml(var/ckey)
log_admin("[key_name(usr)] deleted one of [key]'s notes.")
del info
+
+/proc/show_player_info_irc(var/key as text)
+ var/dat = " Info on [key]%0D%0A"
+ var/savefile/info = new("data/player_saves/[copytext(key, 1, 2)]/[key]/info.sav")
+ var/list/infos
+ info >> infos
+ if(!infos)
+ dat = "No information found on the given key."
+ else
+ for(var/datum/player_info/I in infos)
+ dat += "[I.content]%0D%0Aby [I.author] ([I.rank]) on [I.timestamp]%0D%0A%0D%0A"
+
+ return dat
diff --git a/code/modules/admin/verbs/adminpm.dm b/code/modules/admin/verbs/adminpm.dm
index 8e3f5e29bbc..12763c6a1b0 100644
--- a/code/modules/admin/verbs/adminpm.dm
+++ b/code/modules/admin/verbs/adminpm.dm
@@ -182,3 +182,28 @@
continue
if(X.key!=key && X.key!=C.key && (X.holder.rights & R_ADMIN) || (X.holder.rights & R_MOD) )
X << "PM: [key_name(src, X, 0)]->[key_name(C, X, 0)]: \blue [msg]" //inform X
+
+/client/proc/cmd_admin_irc_pm()
+ if(prefs.muted & MUTE_ADMINHELP)
+ src << "Error: Private-Message: You are unable to use PM-s (muted)."
+ return
+
+ var/msg = input(src,"Message:", "Private message to admins on IRC / 400 character limit") as text|null
+ sanitize(msg)
+
+ if(length(msg) > 400) // TODO: if message length is over 400, divide it up into seperate messages, the message length restriction is based on IRC limitations. Probably easier to do this on the bots ends.
+ src << "\red Your message was not sent because it was more then 400 characters find your message below for ease of copy/pasting"
+ src << "\blue [msg]"
+ return
+
+ send2adminirc("PlayerPM from [key_name(src)]: [html_decode(msg)]")
+
+ src << "IRC PM to-IRC-Admins: [msg]"
+
+ log_admin("PM: [key_name(src)]->IRC: [msg]")
+ for(var/client/X in admins)
+ if(X == src)
+ continue
+ if((X.holder.rights & R_ADMIN) || (X.holder.rights & R_MOD))
+ X << "PM: [key_name(src, X, 0)]->IRC-Admins: \blue [msg]"
+
diff --git a/code/modules/client/client defines.dm b/code/modules/client/client defines.dm
index c85ee0159c6..2a6ef51074b 100644
--- a/code/modules/client/client defines.dm
+++ b/code/modules/client/client defines.dm
@@ -32,6 +32,10 @@
// comment out the line below when debugging locally to enable the options & messages menu
//control_freak = 1
+ var/received_irc_pm = -99999
+ var/irc_admin //IRC admin that spoke with them last.
+ var/mute_irc = 0
+
////////////////////////////////////
//things that require the database//
diff --git a/code/modules/client/client procs.dm b/code/modules/client/client procs.dm
index 9f14378c0a2..7382f33ffef 100644
--- a/code/modules/client/client procs.dm
+++ b/code/modules/client/client procs.dm
@@ -45,6 +45,18 @@
cmd_admin_pm(C,null)
return
+ if(href_list["irc_msg"])
+ if(!holder && received_irc_pm < world.time - 6000) //Worse they can do is spam IRC for 10 minutes
+ usr << "You are no longer able to use this, it's been more then 10 minutes since an admin on IRC has responded to you"
+ return
+ if(mute_irc)
+ usr << ""
+ return
+ cmd_admin_irc_pm()
+ return
+
+
+
//Logs all hrefs
if(config && config.log_hrefs && href_logfile)
href_logfile << "[time2text(world.timeofday,"hh:mm")] [src] (usr:[usr]) || [hsrc ? "[hsrc] " : ""][href]
"
diff --git a/code/modules/ext_scripts/irc.dm b/code/modules/ext_scripts/irc.dm
index fc8910d79f6..e1456176903 100644
--- a/code/modules/ext_scripts/irc.dm
+++ b/code/modules/ext_scripts/irc.dm
@@ -26,3 +26,4 @@
/hook/startup/proc/ircNotify()
send2mainirc("Server starting up on [config.server? "byond://[config.server]" : "byond://[world.address]:[world.port]"]")
return 1
+
diff --git a/code/world.dm b/code/world.dm
index 4793e47c166..c79759843a5 100644
--- a/code/world.dm
+++ b/code/world.dm
@@ -66,9 +66,12 @@
// world << "End of Topic() call."
// ..()
+var/world_topic_spam_protect_ip = "0.0.0.0"
+var/world_topic_spam_protect_time = world.timeofday
+
/world/Topic(T, addr, master, key)
diary << "TOPIC: \"[T]\", from:[addr], master:[master], key:[key][log_end]"
-
+
if (T == "ping")
var/x = 1
for (var/client/C)
@@ -92,6 +95,7 @@
s["ai"] = config.allow_ai
s["host"] = host ? host : null
s["players"] = list()
+ s["stationtime"] = worldtime2text()
var/n = 0
var/admins = 0
@@ -109,6 +113,79 @@
return list2params(s)
+ else if(copytext(T,1,9) == "adminmsg")
+ /*
+ We got an adminmsg from IRC bot lets split the input then validate the input.
+ expected output:
+ 1. adminmsg = ckey of person the message is to
+ 2. msg = contents of message, parems2list requires
+ 3. validatationkey = the key the bot has, it should match the gameservers commspassword in it's configuration.
+ 4. sender = the ircnick that send the message.
+ */
+
+
+ var/input[] = params2list(T)
+ if(input["key"] != config.comms_password)
+ if(world_topic_spam_protect_ip == addr && abs(world_topic_spam_protect_time - world.time) < 50)
+
+ spawn(50)
+ world_topic_spam_protect_time = world.time
+ return "Bad Key (Throttled)"
+
+ world_topic_spam_protect_time = world.time
+ world_topic_spam_protect_ip = addr
+
+ return "Bad Key"
+
+ var/client/C
+
+ for(var/client/K in clients)
+ if(K.ckey == input["adminmsg"])
+ C = K
+ break
+ if(!C)
+ return "No client with that name on server"
+
+ var/message = "IRC-Admin PM from [C.holder ? "IRC-" + input["sender"] : "Administrator"]: [input["msg"]]"
+ var/amessage = "IRC-Admin PM from IRC-[input["sender"]] to [key_name(C)] : [input["msg"]]"
+
+ C.received_irc_pm = world.time
+ C.irc_admin = input["sender"]
+
+ C << 'sound/effects/adminhelp.ogg'
+ C << message
+
+
+ for(var/client/A in admins)
+ if(A != C)
+ A << amessage
+
+ return "Message Successful"
+
+ else if(copytext(T,1,6) == "notes")
+ /*
+ We got a request for notes from the IRC Bot
+ expected output:
+ 1. notes = ckey of person the notes lookup is for
+ 2. validationkey = the key the bot has, it should match the gameservers commspassword in it's configuration.
+ */
+ var/input[] = params2list(T)
+ if(input["key"] != config.comms_password)
+ if(world_topic_spam_protect_ip == addr && abs(world_topic_spam_protect_time - world.time) < 50)
+
+ spawn(50)
+ world_topic_spam_protect_time = world.time
+ return "Bad Key (Throttled)"
+
+ world_topic_spam_protect_time = world.time
+ world_topic_spam_protect_ip = addr
+ return "Bad Key"
+
+ return show_player_info_irc(input["notes"])
+
+
+
+
/world/Reboot(var/reason)
/*spawn(0)