diff --git a/baystation12.dme b/baystation12.dme
index 145b86d4f3f..57364305e02 100644
--- a/baystation12.dme
+++ b/baystation12.dme
@@ -690,6 +690,7 @@
#include "code\modules\admin\admin_memo.dm"
#include "code\modules\admin\admin_ranks.dm"
#include "code\modules\admin\admin_verbs.dm"
+#include "code\modules\admin\banappearance.dm"
#include "code\modules\admin\banjob.dm"
#include "code\modules\admin\create_mob.dm"
#include "code\modules\admin\create_object.dm"
diff --git a/code/modules/admin/DB ban/functions.dm b/code/modules/admin/DB ban/functions.dm
index f67191ebeed..fcf219db147 100644
--- a/code/modules/admin/DB ban/functions.dm
+++ b/code/modules/admin/DB ban/functions.dm
@@ -25,6 +25,11 @@ datum/admins/proc/DB_ban_record(var/bantype, var/mob/banned_mob, var/duration =
if(BANTYPE_JOB_TEMP)
bantype_str = "JOB_TEMPBAN"
bantype_pass = 1
+ if(BANTYPE_APPEARANCE)
+ bantype_str = "APPEARANCE_BAN"
+ duration = -1
+ bantype_pass = 1
+
if( !bantype_pass ) return
if( !istext(reason) ) return
if( !isnum(duration) ) return
@@ -104,6 +109,9 @@ datum/admins/proc/DB_ban_unban(var/ckey, var/bantype, var/job = "")
if(BANTYPE_JOB_TEMP)
bantype_str = "JOB_TEMPBAN"
bantype_pass = 1
+ if(BANTYPE_APPEARANCE)
+ bantype_str = "APPEARANCE_BAN"
+ bantype_pass = 1
if(BANTYPE_ANY_FULLBAN)
bantype_str = "ANY"
bantype_pass = 1
@@ -289,6 +297,7 @@ datum/admins/proc/DB_ban_unban_by_id(var/id)
output += ""
output += ""
output += ""
+ output += ""
output += ""
output += "
Ckey: | "
output += "| Duration: | "
@@ -403,6 +412,9 @@ datum/admins/proc/DB_ban_unban_by_id(var/id)
typedesc = "JOBBAN
([job])"
if("JOB_TEMPBAN")
typedesc = "TEMP JOBBAN
([job])
([duration] minutes
Expires [expiration]"
+ if("APPEARANCE_BAN")
+ typedesc = "APPEARANCE/NAME BAN"
+
output += ""
output += "| [typedesc] | "
diff --git a/code/modules/admin/admin.dm b/code/modules/admin/admin.dm
index 2fe9cb5c518..30ab8f0fcab 100644
--- a/code/modules/admin/admin.dm
+++ b/code/modules/admin/admin.dm
@@ -60,6 +60,7 @@ var/global/floorIsLava = 0
Warn |
Ban |
Jobban |
+ Appearance Ban |
Notes
"}
diff --git a/code/modules/admin/banappearance.dm b/code/modules/admin/banappearance.dm
new file mode 100644
index 00000000000..3262fb66219
--- /dev/null
+++ b/code/modules/admin/banappearance.dm
@@ -0,0 +1,109 @@
+//ban people from using custom names and appearances. that'll show 'em.
+
+var/appearanceban_runonce //Updates legacy bans with new info
+var/appearance_keylist[0] //to store the keys
+
+/proc/appearance_fullban(mob/M, reason)
+ if (!M || !M.key) return
+ appearance_keylist.Add(text("[M.ckey] ## [reason]"))
+ appearance_savebanfile()
+
+/proc/appearance_client_fullban(ckey)
+ if (!ckey) return
+ appearance_keylist.Add(text("[ckey]"))
+ appearance_savebanfile()
+
+//returns a reason if M is banned, returns 0 otherwise
+/proc/appearance_isbanned(mob/M)
+ if(M)
+ for(var/s in appearance_keylist)
+ if(findtext(s, "[M.ckey]") == 1)
+ var/startpos = findtext(s, "## ") + 3
+ if(startpos && startpos < length(s))
+ var/text = copytext(s, startpos, 0)
+ if(text)
+ return text
+ return "Reason Unspecified"
+ return 0
+
+/*
+DEBUG
+/mob/verb/list_all_appearances()
+ set name = "list all appearances"
+
+ for(var/s in appearance_keylist)
+ world << s
+
+/mob/verb/reload_appearances()
+ set name = "reload appearances"
+
+ appearance_loadbanfile()
+*/
+
+/proc/appearance_loadbanfile()
+ if(config.ban_legacy_system)
+ var/savefile/S=new("data/appearance_full.ban")
+ S["keys[0]"] >> appearance_keylist
+ log_admin("Loading appearance_rank")
+ S["runonce"] >> appearanceban_runonce
+
+ if (!length(appearance_keylist))
+ appearance_keylist=list()
+ log_admin("appearance_keylist was empty")
+ else
+ if(!establish_db_connection())
+ world.log << "Database connection failed. Reverting to the legacy ban system."
+ diary << "Database connection failed. Reverting to the legacy ban system."
+ config.ban_legacy_system = 1
+ appearance_loadbanfile()
+ return
+
+ //appearance bans
+ var/DBQuery/query = dbcon.NewQuery("SELECT ckey FROM erro_ban WHERE bantype = 'APPEARANCE_BAN' AND NOT unbanned = 1")
+ query.Execute()
+
+ while(query.NextRow())
+ var/ckey = query.item[1]
+
+ appearance_keylist.Add("[ckey]")
+
+/proc/appearance_savebanfile()
+ var/savefile/S=new("data/appearance_full.ban")
+ S["keys[0]"] << appearance_keylist
+
+/proc/appearance_unban(mob/M)
+ appearance_remove("[M.ckey]")
+ appearance_savebanfile()
+
+
+/proc/appearance_updatelegacybans()
+ if(!appearanceban_runonce)
+ log_admin("Updating appearancefile!")
+ // Updates bans.. Or fixes them. Either way.
+ for(var/T in appearance_keylist)
+ if(!T) continue
+ appearanceban_runonce++ //don't run this update again
+
+
+/proc/appearance_remove(X)
+ for (var/i = 1; i <= length(appearance_keylist); i++)
+ if( findtext(appearance_keylist[i], "[X]") )
+ appearance_keylist.Remove(appearance_keylist[i])
+ appearance_savebanfile()
+ return 1
+ return 0
+
+/*
+proc/DB_ban_isappearancebanned(var/playerckey)
+ establish_db_connection()
+ if(!dbcon.IsConnected())
+ return
+
+ var/sqlplayerckey = sql_sanitize_text(ckey(playerckey))
+
+ var/DBQuery/query = dbcon.NewQuery("SELECT id FROM erro_ban WHERE CKEY = '[sqlplayerckey]' AND ((bantype = 'APPEARANCE_BAN') OR (bantype = 'APPEARANCE_TEMPBAN' AND expiration_time > Now())) AND unbanned != 1")
+ query.Execute()
+ while(query.NextRow())
+ return 1
+ return 0
+*/
\ No newline at end of file
diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm
index 35d6dd0250c..be8a795664a 100644
--- a/code/modules/admin/topic.dm
+++ b/code/modules/admin/topic.dm
@@ -364,6 +364,55 @@
/////////////////////////////////////new ban stuff
+ else if(href_list["appearanceban"])
+ if(!check_rights(R_BAN))
+ return
+ var/mob/M = locate(href_list["appearanceban"])
+ if(!ismob(M))
+ usr << "This can only be used on instances of type /mob"
+ return
+ if(!M.ckey) //sanity
+ usr << "This mob has no ckey"
+ return
+
+ var/banreason = appearance_isbanned(M)
+ if(banreason)
+ /* if(!config.ban_legacy_system)
+ usr << "Unfortunately, database based unbanning cannot be done through this panel"
+ DB_ban_panel(M.ckey)
+ return */
+ switch(alert("Reason: '[banreason]' Remove appearance ban?","Please Confirm","Yes","No"))
+ if("Yes")
+ ban_unban_log_save("[key_name(usr)] removed [key_name(M)]'s appearance ban")
+ log_admin("[key_name(usr)] removed [key_name(M)]'s appearance ban")
+ feedback_inc("ban_appearance_unban", 1)
+ DB_ban_unban(M.ckey, BANTYPE_APPEARANCE)
+ appearance_unban(M)
+ message_admins("\blue [key_name_admin(usr)] removed [key_name_admin(M)]'s appearance ban", 1)
+ M << "\red[usr.client.ckey] has removed your appearance ban."
+
+ else switch(alert("Appearance ban [M.ckey]?",,"Yes","No", "Cancel"))
+ if("Yes")
+ var/reason = input(usr,"Reason?","reason","Metafriender") as text|null
+ if(!reason)
+ return
+ ban_unban_log_save("[key_name(usr)] appearance banned [key_name(M)]. reason: [reason]")
+ log_admin("[key_name(usr)] appearance banned [key_name(M)]. \nReason: [reason]")
+ feedback_inc("ban_appearance",1)
+ DB_ban_record(BANTYPE_APPEARANCE, M, -1, reason)
+ appearance_fullban(M, "[reason]; By [usr.ckey] on [time2text(world.realtime)]")
+ notes_add(M.ckey, "Appearance banned - [reason]")
+ message_admins("\blue [key_name_admin(usr)] appearance banned [key_name_admin(M)]", 1)
+ M << "\redYou have been appearance banned by [usr.client.ckey]."
+ M << "\red The reason is: [reason]"
+ M << "\red Appearance ban can be lifted only upon request."
+ if(config.banappeals)
+ M << "\red To try to resolve this matter head to [config.banappeals]"
+ else
+ M << "\red No ban appeals URL has been set."
+ if("No")
+ return
+
else if(href_list["jobban2"])
// if(!check_rights(R_BAN)) return
diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm
index a521d92a256..34dd34b5219 100644
--- a/code/modules/client/preferences.dm
+++ b/code/modules/client/preferences.dm
@@ -151,6 +151,8 @@ datum/preferences
dat += "Set Occupation Preferences
"
dat += "Identity
"
dat += ""
+ if(appearance_isbanned(user))
+ dat += "You are banned from using custom names and appearances. You can continue to adjust your characters, but you will be randomised once you join the game. "
dat += "Name: "
dat += "[real_name] "
dat += "(Random Name) "
diff --git a/code/modules/mob/new_player/new_player.dm b/code/modules/mob/new_player/new_player.dm
index c31383defa5..c27899d296d 100644
--- a/code/modules/mob/new_player/new_player.dm
+++ b/code/modules/mob/new_player/new_player.dm
@@ -396,7 +396,7 @@
if(is_alien_whitelisted(src, client.prefs.language) || !config.usealienwhitelist || !(chosen_language.flags & WHITELISTED))
new_character.add_language("[client.prefs.language]")
- if(ticker.random_players)
+ if(ticker.random_players || appearance_isbanned(new_character))
new_character.gender = pick(MALE, FEMALE)
client.prefs.real_name = random_name(new_character.gender)
client.prefs.randomize_appearance_for(new_character)
diff --git a/code/setup.dm b/code/setup.dm
index 189042a3611..924fe576538 100644
--- a/code/setup.dm
+++ b/code/setup.dm
@@ -519,6 +519,7 @@ var/list/liftable_structures = list(\
#define BANTYPE_JOB_PERMA 3
#define BANTYPE_JOB_TEMP 4
#define BANTYPE_ANY_FULLBAN 5 //used to locate stuff to unban.
+#define BANTYPE_APPEARANCE 6
#define SEE_INVISIBLE_MINIMUM 5
diff --git a/code/world.dm b/code/world.dm
index 6ec391d4d6f..0da38bdf2e8 100644
--- a/code/world.dm
+++ b/code/world.dm
@@ -35,6 +35,7 @@
if(config.usealienwhitelist)
load_alienwhitelist()
jobban_loadbanfile()
+ appearance_loadbanfile()
jobban_updatelegacybans()
LoadBans()
|