mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-08-30 15:37:36 +01:00
Async SQL + SSdbcore (#15007)
* Initial Commit - Async SQL * First batch of queries * More progress * Nukes DB Polls * More work * oops * One push * Notes work now * Ok these work * Watchlist done * Async Bans! * Async Permissions * Async client procs * I officially hate preference datums * Also these * Async Custom Items * Async Karma * Async Library * Async TOS * Cleans out the old SQL code * CI Sanity * Apparently MySQL doesnt support this * What about this * Maybe this * Review pass 1 * This too * Fixes job ban loading * Fix undeleted queries * Prevents sensitive queries being logged * Documentation + tweaks * Adds a verb to force reconnect the DB * More review tweaks * Farie tweaks * Fixes this
This commit is contained in:
@@ -1,12 +1,6 @@
|
||||
//Blocks an attempt to connect before even creating our client datum thing.
|
||||
/world/IsBanned(key, address, computer_id, type, check_ipintel = TRUE)
|
||||
|
||||
if(!config.ban_legacy_system)
|
||||
if(address)
|
||||
address = sanitizeSQL(address)
|
||||
if(computer_id)
|
||||
computer_id = sanitizeSQL(computer_id)
|
||||
|
||||
if(!key || !address || !computer_id)
|
||||
log_adminwarn("Failed Login (invalid data): [key] [address]-[computer_id]")
|
||||
return list("reason"="invalid login data", "desc"="Error: Could not check ban status, please try again. Error message: Your computer provided invalid or blank information to the server on connection (BYOND Username, IP, and Computer ID). Provided information for reference: Username: '[key]' IP: '[address]' Computer ID: '[computer_id]'. If you continue to get this error, please restart byond or contact byond support.")
|
||||
@@ -59,21 +53,33 @@
|
||||
else
|
||||
var/ckeytext = ckey(key)
|
||||
|
||||
if(!establish_db_connection())
|
||||
if(!SSdbcore.IsConnected())
|
||||
log_world("Ban database connection failure. Key [ckeytext] not checked")
|
||||
return
|
||||
|
||||
var/list/sql_query_params = list(
|
||||
"ckeytext" = ckeytext
|
||||
)
|
||||
|
||||
var/ipquery = ""
|
||||
var/cidquery = ""
|
||||
if(address)
|
||||
ipquery = " OR ip = '[address]' "
|
||||
ipquery = " OR ip=:ip "
|
||||
sql_query_params["ip"] = address
|
||||
|
||||
if(computer_id)
|
||||
cidquery = " OR computerid = '[computer_id]' "
|
||||
cidquery = " OR computerid=:cid "
|
||||
sql_query_params["cid"] = computer_id
|
||||
|
||||
var/DBQuery/query = GLOB.dbcon.NewQuery("SELECT ckey, ip, computerid, a_ckey, reason, expiration_time, duration, bantime, bantype FROM [format_table_name("ban")] WHERE (ckey = '[ckeytext]' [ipquery] [cidquery]) AND (bantype = 'PERMABAN' OR bantype = 'ADMIN_PERMABAN' OR ((bantype = 'TEMPBAN' OR bantype = 'ADMIN_TEMPBAN') AND expiration_time > Now())) AND isnull(unbanned)")
|
||||
var/datum/db_query/query = SSdbcore.NewQuery({"
|
||||
SELECT ckey, ip, computerid, a_ckey, reason, expiration_time, duration, bantime, bantype FROM [format_table_name("ban")]
|
||||
WHERE (ckey=:ckeytext [ipquery] [cidquery]) AND (bantype = 'PERMABAN' OR bantype = 'ADMIN_PERMABAN'
|
||||
OR ((bantype = 'TEMPBAN' OR bantype = 'ADMIN_TEMPBAN') AND expiration_time > Now())) AND isnull(unbanned)"}, sql_query_params)
|
||||
|
||||
query.Execute()
|
||||
if(!query.warn_execute())
|
||||
message_admins("Failed to do a DB ban check for [ckeytext]. You have been warned.")
|
||||
qdel(query)
|
||||
return
|
||||
|
||||
while(query.NextRow())
|
||||
var/pckey = query.item[1]
|
||||
@@ -113,7 +119,9 @@
|
||||
. = list("reason"="[bantype]", "desc"="[desc]")
|
||||
|
||||
log_adminwarn("Failed Login: [key] [computer_id] [address] - Banned [.["reason"]]")
|
||||
qdel(query)
|
||||
return .
|
||||
qdel(query)
|
||||
|
||||
. = ..() //default pager ban stuff
|
||||
if(.)
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
set category = "Server"
|
||||
if(!check_rights(R_SERVER))
|
||||
return
|
||||
if(!GLOB.dbcon.IsConnected())
|
||||
if(!SSdbcore.IsConnected())
|
||||
to_chat(src, "<span class='danger'>Failed to establish database connection.</span>")
|
||||
return
|
||||
var/memotask = input(usr,"Choose task.","Memo") in list("Show","Write","Edit","Remove")
|
||||
@@ -16,78 +16,113 @@
|
||||
return
|
||||
if(!task)
|
||||
return
|
||||
if(!GLOB.dbcon.IsConnected())
|
||||
if(!SSdbcore.IsConnected())
|
||||
to_chat(src, "<span class='danger'>Failed to establish database connection.</span>")
|
||||
return
|
||||
var/sql_ckey = sanitizeSQL(src.ckey)
|
||||
switch(task)
|
||||
if("Write")
|
||||
var/DBQuery/query_memocheck = GLOB.dbcon.NewQuery("SELECT ckey FROM [format_table_name("memo")] WHERE ckey = '[sql_ckey]'")
|
||||
if(!query_memocheck.Execute())
|
||||
var/err = query_memocheck.ErrorMsg()
|
||||
log_game("SQL ERROR obtaining ckey from memo table. Error : \[[err]\]\n")
|
||||
var/datum/db_query/query_memocheck = SSdbcore.NewQuery(
|
||||
"SELECT ckey FROM [format_table_name("memo")] WHERE ckey=:ckey",
|
||||
list("ckey" = ckey)
|
||||
)
|
||||
|
||||
if(!query_memocheck.warn_execute())
|
||||
qdel(query_memocheck)
|
||||
return
|
||||
|
||||
if(query_memocheck.NextRow())
|
||||
to_chat(src, "You already have set a memo.")
|
||||
qdel(query_memocheck)
|
||||
return
|
||||
var/memotext = input(src,"Write your Memo","Memo") as message
|
||||
|
||||
qdel(query_memocheck)
|
||||
var/memotext = input(src, "Write your Memo", "Memo") as message
|
||||
if(!memotext)
|
||||
return
|
||||
memotext = sanitizeSQL(memotext)
|
||||
var/timestamp = SQLtime()
|
||||
var/DBQuery/query_memoadd = GLOB.dbcon.NewQuery("INSERT INTO [format_table_name("memo")] (ckey, memotext, timestamp) VALUES ('[sql_ckey]', '[memotext]', '[timestamp]')")
|
||||
if(!query_memoadd.Execute())
|
||||
var/err = query_memoadd.ErrorMsg()
|
||||
log_game("SQL ERROR adding new memo. Error : \[[err]\]\n")
|
||||
|
||||
var/datum/db_query/query_memoadd = SSdbcore.NewQuery(
|
||||
"INSERT INTO [format_table_name("memo")] (ckey, memotext, timestamp) VALUES (:ckey, :memotext, NOW())",
|
||||
list(
|
||||
"ckey" = ckey,
|
||||
"memotext" = memotext
|
||||
)
|
||||
)
|
||||
|
||||
if(!query_memoadd.warn_execute())
|
||||
qdel(query_memoadd)
|
||||
return
|
||||
|
||||
log_admin("[key_name(src)] has set a memo: [memotext]")
|
||||
message_admins("[key_name_admin(src)] has set a memo:<br>[memotext]")
|
||||
qdel(query_memoadd)
|
||||
|
||||
if("Edit")
|
||||
var/DBQuery/query_memolist = GLOB.dbcon.NewQuery("SELECT ckey FROM [format_table_name("memo")]")
|
||||
if(!query_memolist.Execute())
|
||||
var/err = query_memolist.ErrorMsg()
|
||||
log_game("SQL ERROR obtaining ckey from memo table. Error : \[[err]\]\n")
|
||||
var/datum/db_query/query_memolist = SSdbcore.NewQuery("SELECT ckey FROM [format_table_name("memo")]")
|
||||
|
||||
if(!query_memolist.warn_execute())
|
||||
qdel(query_memolist)
|
||||
return
|
||||
|
||||
var/list/memolist = list()
|
||||
while(query_memolist.NextRow())
|
||||
var/lkey = query_memolist.item[1]
|
||||
memolist += "[lkey]"
|
||||
if(!memolist.len)
|
||||
|
||||
qdel(query_memolist)
|
||||
if(!length(memolist))
|
||||
to_chat(src, "No memos found in database.")
|
||||
return
|
||||
|
||||
var/target_ckey = input(src, "Select whose memo to edit", "Select memo") as null|anything in memolist
|
||||
if(!target_ckey)
|
||||
return
|
||||
var/target_sql_ckey = sanitizeSQL(target_ckey)
|
||||
var/DBQuery/query_memofind = GLOB.dbcon.NewQuery("SELECT memotext FROM [format_table_name("memo")] WHERE ckey = '[target_sql_ckey]'")
|
||||
if(!query_memofind.Execute())
|
||||
var/err = query_memofind.ErrorMsg()
|
||||
log_game("SQL ERROR obtaining memotext from memo table. Error : \[[err]\]\n")
|
||||
|
||||
var/datum/db_query/query_memofind = SSdbcore.NewQuery(
|
||||
"SELECT memotext FROM [format_table_name("memo")] WHERE ckey=:ckey",
|
||||
list("ckey" = target_ckey)
|
||||
)
|
||||
|
||||
if(!query_memofind.warn_execute())
|
||||
qdel(query_memofind)
|
||||
return
|
||||
|
||||
if(query_memofind.NextRow())
|
||||
var/old_memo = query_memofind.item[1]
|
||||
var/new_memo = input("Input new memo", "New Memo", "[old_memo]", null) as message
|
||||
if(!new_memo)
|
||||
qdel(query_memofind)
|
||||
return
|
||||
new_memo = sanitizeSQL(new_memo)
|
||||
var/edit_text = "Edited by [sql_ckey] on [SQLtime()] from<br>[old_memo]<br>to<br>[new_memo]<hr>"
|
||||
edit_text = sanitizeSQL(edit_text)
|
||||
var/DBQuery/update_query = GLOB.dbcon.NewQuery("UPDATE [format_table_name("memo")] SET memotext = '[new_memo]', last_editor = '[sql_ckey]', edits = CONCAT(IFNULL(edits,''),'[edit_text]') WHERE ckey = '[target_sql_ckey]'")
|
||||
if(!update_query.Execute())
|
||||
var/err = update_query.ErrorMsg()
|
||||
log_game("SQL ERROR editing memo. Error : \[[err]\]\n")
|
||||
|
||||
var/edit_text = "Edited by [target_ckey] on [SQLtime()] from<br>[old_memo]<br>to<br>[new_memo]<hr>"
|
||||
|
||||
var/datum/db_query/update_query = SSdbcore.NewQuery(
|
||||
"UPDATE [format_table_name("memo")] SET memotext=:newmemo, last_editor=:lasteditor, edits=CONCAT(IFNULL(edits,''),:edittext) WHERE ckey=:targetckey",
|
||||
list(
|
||||
"newmemo" = new_memo,
|
||||
"lasteditor" = ckey,
|
||||
"edittext" = edit_text,
|
||||
"targetckey" = target_ckey
|
||||
)
|
||||
)
|
||||
|
||||
if(!update_query.warn_execute())
|
||||
qdel(update_query)
|
||||
qdel(query_memofind)
|
||||
return
|
||||
if(target_sql_ckey == sql_ckey)
|
||||
|
||||
if(target_ckey == ckey)
|
||||
log_admin("[key_name(src)] has edited their memo from \"[old_memo]\" to \"[new_memo]\"")
|
||||
message_admins("[key_name_admin(src)] has edited their memo from \"[old_memo]]\" to \"[new_memo]\"")
|
||||
else
|
||||
log_admin("[key_name(src)] has edited [target_sql_ckey]'s memo from \"[old_memo]\" to \"[new_memo]\"")
|
||||
message_admins("[key_name_admin(src)] has edited [target_sql_ckey]'s memo from \"[old_memo]\" to \"[new_memo]\"")
|
||||
log_admin("[key_name(src)] has edited [target_ckey]'s memo from \"[old_memo]\" to \"[new_memo]\"")
|
||||
message_admins("[key_name_admin(src)] has edited [target_ckey]'s memo from \"[old_memo]\" to \"[new_memo]\"")
|
||||
qdel(update_query)
|
||||
qdel(query_memofind)
|
||||
|
||||
if("Show")
|
||||
var/DBQuery/query_memoshow = GLOB.dbcon.NewQuery("SELECT ckey, memotext, timestamp, last_editor FROM [format_table_name("memo")]")
|
||||
if(!query_memoshow.Execute())
|
||||
var/err = query_memoshow.ErrorMsg()
|
||||
log_game("SQL ERROR obtaining ckey, memotext, timestamp, last_editor from memo table. Error : \[[err]\]\n")
|
||||
var/datum/db_query/query_memoshow = SSdbcore.NewQuery("SELECT ckey, memotext, timestamp, last_editor FROM [format_table_name("memo")]")
|
||||
if(!query_memoshow.warn_execute())
|
||||
qdel(query_memoshow)
|
||||
return
|
||||
var/output = null
|
||||
while(query_memoshow.NextRow())
|
||||
@@ -103,31 +138,41 @@
|
||||
to_chat(src, output)
|
||||
else if(!silent)
|
||||
to_chat(src, "No memos found in database.")
|
||||
qdel(query_memoshow)
|
||||
|
||||
if("Remove")
|
||||
var/DBQuery/query_memodellist = GLOB.dbcon.NewQuery("SELECT ckey FROM [format_table_name("memo")]")
|
||||
if(!query_memodellist.Execute())
|
||||
var/err = query_memodellist.ErrorMsg()
|
||||
log_game("SQL ERROR obtaining ckey from memo table. Error : \[[err]\]\n")
|
||||
var/datum/db_query/query_memodellist = SSdbcore.NewQuery("SELECT ckey FROM [format_table_name("memo")]")
|
||||
if(!query_memodellist.warn_execute())
|
||||
qdel(query_memodellist)
|
||||
return
|
||||
|
||||
var/list/memolist = list()
|
||||
while(query_memodellist.NextRow())
|
||||
var/ckey = query_memodellist.item[1]
|
||||
memolist += "[ckey]"
|
||||
|
||||
qdel(query_memodellist)
|
||||
if(!memolist.len)
|
||||
to_chat(src, "No memos found in database.")
|
||||
return
|
||||
|
||||
var/target_ckey = input(src, "Select whose memo to delete", "Select memo") as null|anything in memolist
|
||||
if(!target_ckey)
|
||||
return
|
||||
var/target_sql_ckey = sanitizeSQL(target_ckey)
|
||||
var/DBQuery/query_memodel = GLOB.dbcon.NewQuery("DELETE FROM [format_table_name("memo")] WHERE ckey = '[target_sql_ckey]'")
|
||||
if(!query_memodel.Execute())
|
||||
var/err = query_memodel.ErrorMsg()
|
||||
log_game("SQL ERROR removing memo. Error : \[[err]\]\n")
|
||||
|
||||
var/datum/db_query/query_memodel = SSdbcore.NewQuery(
|
||||
"DELETE FROM [format_table_name("memo")] WHERE ckey=:ckey",
|
||||
list("ckey" = target_ckey)
|
||||
)
|
||||
|
||||
if(!query_memodel.warn_execute())
|
||||
qdel(query_memodel)
|
||||
return
|
||||
if(target_sql_ckey == sql_ckey)
|
||||
|
||||
qdel(query_memodel)
|
||||
if(target_ckey == ckey)
|
||||
log_admin("[key_name(src)] has removed their memo.")
|
||||
message_admins("[key_name_admin(src)] has removed their memo.")
|
||||
else
|
||||
log_admin("[key_name(src)] has removed [target_sql_ckey]'s memo.")
|
||||
message_admins("[key_name_admin(src)] has removed [target_sql_ckey]'s memo.")
|
||||
log_admin("[key_name(src)] has removed [target_ckey]'s memo.")
|
||||
message_admins("[key_name_admin(src)] has removed [target_ckey]'s memo.")
|
||||
|
||||
@@ -111,16 +111,17 @@ GLOBAL_PROTECT(admin_ranks) // this shit is being protected for obvious reasons
|
||||
|
||||
else
|
||||
//The current admin system uses SQL
|
||||
|
||||
establish_db_connection()
|
||||
if(!GLOB.dbcon.IsConnected())
|
||||
if(!SSdbcore.IsConnected())
|
||||
log_world("Failed to connect to database in load_admins(). Reverting to legacy system.")
|
||||
config.admin_legacy_system = 1
|
||||
load_admins()
|
||||
return
|
||||
|
||||
var/DBQuery/query = GLOB.dbcon.NewQuery("SELECT ckey, rank, level, flags FROM [format_table_name("admin")]")
|
||||
query.Execute()
|
||||
var/datum/db_query/query = SSdbcore.NewQuery("SELECT ckey, rank, level, flags FROM [format_table_name("admin")]")
|
||||
if(!query.warn_execute())
|
||||
qdel(query)
|
||||
return
|
||||
|
||||
while(query.NextRow())
|
||||
var/ckey = query.item[1]
|
||||
var/rank = query.item[2]
|
||||
@@ -135,6 +136,9 @@ GLOBAL_PROTECT(admin_ranks) // this shit is being protected for obvious reasons
|
||||
|
||||
//find the client for a ckey if they are connected and associate them with the new admin datum
|
||||
D.associate(GLOB.directory[ckey])
|
||||
|
||||
qdel(query)
|
||||
|
||||
if(!GLOB.admin_datums)
|
||||
log_world("The database query in load_admins() resulted in no admins being added to the list. Reverting to legacy system.")
|
||||
config.admin_legacy_system = 1
|
||||
|
||||
@@ -168,7 +168,8 @@ GLOBAL_LIST_INIT(admin_verbs_debug, list(
|
||||
/client/proc/jump_to_ruin,
|
||||
/client/proc/toggle_medal_disable,
|
||||
/client/proc/uid_log,
|
||||
/client/proc/visualise_active_turfs
|
||||
/client/proc/visualise_active_turfs,
|
||||
/client/proc/reestablish_db_connection
|
||||
))
|
||||
GLOBAL_LIST_INIT(admin_verbs_possess, list(
|
||||
/proc/possess,
|
||||
@@ -176,7 +177,6 @@ GLOBAL_LIST_INIT(admin_verbs_possess, list(
|
||||
))
|
||||
GLOBAL_LIST_INIT(admin_verbs_permissions, list(
|
||||
/client/proc/edit_admin_permissions,
|
||||
/client/proc/create_poll,
|
||||
/client/proc/big_brother
|
||||
))
|
||||
GLOBAL_LIST_INIT(admin_verbs_rejuv, list(
|
||||
@@ -691,15 +691,23 @@ GLOBAL_LIST_INIT(admin_verbs_ticket, list(
|
||||
continue
|
||||
|
||||
else
|
||||
if(!GLOB.dbcon.IsConnected())
|
||||
message_admins("Warning, MySQL database is not connected.")
|
||||
if(!SSdbcore.IsConnected())
|
||||
to_chat(src, "Warning, MYSQL database is not connected.")
|
||||
return
|
||||
var/sql_ckey = sanitizeSQL(ckey)
|
||||
var/DBQuery/query = GLOB.dbcon.NewQuery("SELECT rank FROM [format_table_name("admin")] WHERE ckey = '[sql_ckey]'")
|
||||
query.Execute()
|
||||
while(query.NextRow())
|
||||
rank = ckeyEx(query.item[1])
|
||||
|
||||
var/datum/db_query/rank_read = SSdbcore.NewQuery(
|
||||
"SELECT rank FROM [format_table_name("admin")] WHERE ckey=:ckey",
|
||||
list("ckey" = ckey)
|
||||
)
|
||||
|
||||
if(!rank_read.warn_execute())
|
||||
qdel(rank_read)
|
||||
return FALSE
|
||||
|
||||
while(rank_read.NextRow())
|
||||
rank = ckeyEx(rank_read.item[1])
|
||||
|
||||
qdel(rank_read)
|
||||
if(!D)
|
||||
if(config.admin_legacy_system)
|
||||
if(GLOB.admin_ranks[rank] == null)
|
||||
@@ -709,24 +717,38 @@ GLOBAL_LIST_INIT(admin_verbs_ticket, list(
|
||||
|
||||
D = new(rank, GLOB.admin_ranks[rank], ckey)
|
||||
else
|
||||
var/sql_ckey = sanitizeSQL(ckey)
|
||||
var/DBQuery/query = GLOB.dbcon.NewQuery("SELECT ckey, rank, flags FROM [format_table_name("admin")] WHERE ckey = '[sql_ckey]'")
|
||||
query.Execute()
|
||||
while(query.NextRow())
|
||||
var/admin_ckey = query.item[1]
|
||||
var/admin_rank = query.item[2]
|
||||
var/flags = query.item[3]
|
||||
if(!SSdbcore.IsConnected())
|
||||
to_chat(src, "Warning, MYSQL database is not connected.")
|
||||
return
|
||||
|
||||
var/datum/db_query/admin_read = SSdbcore.NewQuery(
|
||||
"SELECT ckey, rank, flags FROM [format_table_name("admin")] WHERE ckey=:ckey",
|
||||
list("ckey" = ckey)
|
||||
)
|
||||
|
||||
if(!admin_read.warn_execute())
|
||||
qdel(admin_read)
|
||||
return FALSE
|
||||
|
||||
while(admin_read.NextRow())
|
||||
var/admin_ckey = admin_read.item[1]
|
||||
var/admin_rank = admin_read.item[2]
|
||||
var/flags = admin_read.item[3]
|
||||
if(!admin_ckey)
|
||||
to_chat(src, "Error while re-adminning, ckey [admin_ckey] was not found in the admin database.")
|
||||
qdel(admin_read)
|
||||
return
|
||||
if(admin_rank == "Removed") //This person was de-adminned. They are only in the admin list for archive purposes.
|
||||
to_chat(src, "Error while re-adminning, ckey [admin_ckey] is not an admin.")
|
||||
qdel(admin_read)
|
||||
return
|
||||
|
||||
if(istext(flags))
|
||||
flags = text2num(flags)
|
||||
D = new(admin_rank, flags, ckey)
|
||||
|
||||
qdel(admin_read)
|
||||
|
||||
var/client/C = GLOB.directory[ckey]
|
||||
D.associate(C)
|
||||
message_admins("[key_name_admin(usr)] re-adminned themselves.")
|
||||
|
||||
@@ -39,7 +39,7 @@ DEBUG
|
||||
|
||||
appearance_loadbanfile()
|
||||
*/
|
||||
|
||||
// AA 2020-11-25: This entire proc isnt even called. What the actual fuck.
|
||||
/proc/appearance_loadbanfile()
|
||||
if(config.ban_legacy_system)
|
||||
var/savefile/S=new("data/appearance_full.ban")
|
||||
@@ -51,21 +51,26 @@ DEBUG
|
||||
GLOB.appearance_keylist=list()
|
||||
log_admin("appearance_keylist was empty")
|
||||
else
|
||||
if(!establish_db_connection())
|
||||
if(!SSdbcore.IsConnected())
|
||||
log_world("Database connection failed. Reverting to the legacy ban system.")
|
||||
config.ban_legacy_system = 1
|
||||
appearance_loadbanfile()
|
||||
return
|
||||
|
||||
//appearance bans
|
||||
var/DBQuery/query = GLOB.dbcon.NewQuery("SELECT ckey FROM [format_table_name("ban")] WHERE bantype = 'APPEARANCE_BAN' AND NOT unbanned = 1")
|
||||
query.Execute()
|
||||
var/datum/db_query/appearanceban_query = SSdbcore.NewQuery("SELECT ckey FROM [format_table_name("ban")] WHERE bantype = 'APPEARANCE_BAN' AND NOT unbanned = 1")
|
||||
|
||||
while(query.NextRow())
|
||||
var/ckey = query.item[1]
|
||||
if(!appearanceban_query.warn_execute())
|
||||
qdel(appearanceban_query)
|
||||
return FALSE
|
||||
|
||||
while(appearanceban_query.NextRow())
|
||||
var/ckey = appearanceban_query.item[1]
|
||||
|
||||
GLOB.appearance_keylist.Add("[ckey]")
|
||||
|
||||
qdel(appearanceban_query)
|
||||
|
||||
/proc/appearance_savebanfile()
|
||||
var/savefile/S=new("data/appearance_full.ban")
|
||||
to_chat(S["keys[0]"], GLOB.appearance_keylist)
|
||||
|
||||
@@ -59,34 +59,42 @@ GLOBAL_DATUM_INIT(jobban_regex, /regex, regex("(\[\\S]+) - (\[^#]+\[^# ])(?: ##
|
||||
else
|
||||
log_runtime(EXCEPTION("Skipping malformed job ban: [s]"))
|
||||
else
|
||||
if(!establish_db_connection())
|
||||
if(!SSdbcore.IsConnected())
|
||||
log_world("Database connection failed. Reverting to the legacy ban system.")
|
||||
config.ban_legacy_system = 1
|
||||
jobban_loadbanfile()
|
||||
return
|
||||
|
||||
//Job permabans
|
||||
var/DBQuery/permabans = GLOB.dbcon.NewQuery("SELECT ckey, job FROM [format_table_name("ban")] WHERE bantype = 'JOB_PERMABAN' AND isnull(unbanned)")
|
||||
permabans.Execute()
|
||||
// Job tempbans
|
||||
var/DBQuery/tempbans = GLOB.dbcon.NewQuery("SELECT ckey, job FROM [format_table_name("ban")] WHERE bantype = 'JOB_TEMPBAN' AND isnull(unbanned) AND expiration_time > Now()")
|
||||
tempbans.Execute()
|
||||
var/datum/db_query/permabans = SSdbcore.NewQuery("SELECT ckey, job FROM [format_table_name("ban")] WHERE bantype = 'JOB_PERMABAN' AND isnull(unbanned)")
|
||||
|
||||
while(TRUE)
|
||||
var/ckey
|
||||
var/job
|
||||
if(permabans.NextRow())
|
||||
ckey = permabans.item[1]
|
||||
job = permabans.item[2]
|
||||
else if(tempbans.NextRow())
|
||||
ckey = tempbans.item[1]
|
||||
job = tempbans.item[2]
|
||||
else
|
||||
break
|
||||
if(!permabans.warn_execute())
|
||||
qdel(permabans)
|
||||
return FALSE
|
||||
|
||||
while(permabans.NextRow())
|
||||
var/ckey = permabans.item[1]
|
||||
var/job = permabans.item[2]
|
||||
GLOB.jobban_keylist.Add("[ckey] - [job]")
|
||||
jobban_assoc_insert(ckey, job)
|
||||
|
||||
qdel(permabans)
|
||||
|
||||
// Job tempbans
|
||||
var/datum/db_query/tempbans = SSdbcore.NewQuery("SELECT ckey, job FROM [format_table_name("ban")] WHERE bantype = 'JOB_TEMPBAN' AND isnull(unbanned) AND expiration_time > Now()")
|
||||
|
||||
if(!tempbans.warn_execute())
|
||||
qdel(tempbans)
|
||||
return FALSE
|
||||
|
||||
while(tempbans.NextRow())
|
||||
var/ckey = tempbans.item[1]
|
||||
var/job = tempbans.item[2]
|
||||
GLOB.jobban_keylist.Add("[ckey] - [job]")
|
||||
jobban_assoc_insert(ckey, job)
|
||||
|
||||
qdel(tempbans)
|
||||
|
||||
/proc/jobban_savebanfile()
|
||||
var/savefile/S=new("data/job_full.ban")
|
||||
S["keys[0]"] << GLOB.jobban_keylist
|
||||
@@ -134,8 +142,16 @@ GLOBAL_DATUM_INIT(jobban_regex, /regex, regex("(\[\\S]+) - (\[^#]+\[^# ])(?: ##
|
||||
else
|
||||
//using the SQL ban system
|
||||
var/is_actually_banned = FALSE
|
||||
var/DBQuery/select_query = GLOB.dbcon.NewQuery("SELECT bantime, bantype, reason, job, duration, expiration_time, a_ckey FROM [format_table_name("ban")] WHERE ckey like '[ckey]' AND ((bantype like 'JOB_TEMPBAN' AND expiration_time > Now()) OR (bantype like 'JOB_PERMABAN')) AND isnull(unbanned) ORDER BY bantime DESC LIMIT 100")
|
||||
select_query.Execute()
|
||||
var/datum/db_query/select_query = SSdbcore.NewQuery({"
|
||||
SELECT bantime, bantype, reason, job, duration, expiration_time, a_ckey FROM [format_table_name("ban")]
|
||||
WHERE ckey LIKE :ckey AND ((bantype like 'JOB_TEMPBAN' AND expiration_time > Now()) OR (bantype like 'JOB_PERMABAN')) AND isnull(unbanned)
|
||||
ORDER BY bantime DESC LIMIT 100"},
|
||||
list("ckey" = ckey)
|
||||
)
|
||||
|
||||
if(!select_query.warn_execute())
|
||||
qdel(select_query)
|
||||
return FALSE
|
||||
|
||||
while(select_query.NextRow())
|
||||
|
||||
@@ -154,6 +170,8 @@ GLOBAL_DATUM_INIT(jobban_regex, /regex, regex("(\[\\S]+) - (\[^#]+\[^# ])(?: ##
|
||||
|
||||
is_actually_banned = TRUE
|
||||
|
||||
qdel(select_query)
|
||||
|
||||
if(is_actually_banned)
|
||||
if(config.banappeals)
|
||||
to_chat(src, "<span class='warning'>You can appeal the bans at: [config.banappeals]</span>")
|
||||
|
||||
@@ -1,202 +0,0 @@
|
||||
/client/proc/create_poll()
|
||||
set name = "Create Server Poll"
|
||||
set category = "Server"
|
||||
if(!check_rights(R_SERVER))
|
||||
return
|
||||
if(!GLOB.dbcon.IsConnected())
|
||||
to_chat(src, "<span class='danger'>Failed to establish database connection.</span>")
|
||||
return
|
||||
create_poll_window()
|
||||
|
||||
/client/proc/create_poll_window(var/errormessage = "")
|
||||
if(!check_rights(R_SERVER))
|
||||
return
|
||||
var/output={"<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<script>
|
||||
var numoptions = 0;
|
||||
function update_vis() {
|
||||
var polloptions = document.getElementById("polloptions");
|
||||
var polltype = document.getElementById("polltype").value;
|
||||
if(polltype == "[POLLTYPE_TEXT]") {
|
||||
polloptions.style.display = "none";
|
||||
} else {
|
||||
polloptions.style.display = "block";
|
||||
}
|
||||
if(polltype == "[POLLTYPE_RATING]") {
|
||||
for(var i = 0; i < numoptions; i++) {
|
||||
document.getElementById("ratingoption" + i).style.display = "block";
|
||||
}
|
||||
} else {
|
||||
for(var i = 0; i < numoptions; i++) {
|
||||
document.getElementById("ratingoption" + i).style.display = "none";
|
||||
}
|
||||
}
|
||||
if(polltype == "[POLLTYPE_MULTI]") {
|
||||
document.getElementById("choiceamount").style.display = "block";
|
||||
} else {
|
||||
document.getElementById("choiceamount").style.display = "none";
|
||||
}
|
||||
}
|
||||
function add_option() {
|
||||
document.getElementById("polloptionsinner").innerHTML += "<div id='polloption"+numoptions+"' style='border:1px solid black;padding:10px'>"+
|
||||
"Option name: <input type='text' name='createpolloption"+numoptions+"option' value='' style='width:300px'></input><br>"+
|
||||
"<label><input type='checkbox' name='createpolloption"+numoptions+"percentagecalc' value='1' checked>Calculate options results as percentage?</label><br>"+
|
||||
"<div id='ratingoption"+numoptions+"'>"+
|
||||
"Minimum rating value: <input type='text' name='createpolloption"+numoptions+"minval' value='1'></input><br>"+
|
||||
"Maximum rating value: <input type='text' name='createpolloption"+numoptions+"maxval' value='5'></input><br>"+
|
||||
"Minimum rating description: <input type='text' name='createpolloption"+numoptions+"descmin' value='Terrible'></input><br>"+
|
||||
"Median rating description: <input type='text' name='createpolloption"+numoptions+"descmid' value=''></input><br>"+
|
||||
"Maximum rating description: <input type='text' name='createpolloption"+numoptions+"descmax' value='Great'></input>"+
|
||||
"</div>";
|
||||
numoptions++;
|
||||
document.getElementById("createpollnumoptions").value = numoptions+"";
|
||||
update_vis();
|
||||
}
|
||||
function del_option() {
|
||||
if(numoptions <= 1) {
|
||||
return;
|
||||
}
|
||||
numoptions--;
|
||||
document.getElementById("polloptionsinner").removeChild(document.getElementById("polloption"+numoptions));
|
||||
document.getElementById("createpollnumoptions").value = numoptions+"";
|
||||
update_vis();
|
||||
}
|
||||
function onload() {
|
||||
update_vis();
|
||||
add_option();
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body onload="onload()">
|
||||
<div style='text-align:center'><b>Create Player Poll</b></div><hr>
|
||||
<div style='text-align:center'>[errormessage]</div>
|
||||
<form name='createpoll' action='byond://' method='post' style='padding-left:30px;padding-right:30px;padding-top:10px'>
|
||||
<input type='hidden' name='createpollnumoptions' id='createpollnumoptions' value='0'>
|
||||
<table><tr><td style='width:50%' style="vertical-align:top"><div id='polloptions'><div id='polloptionsinner'>
|
||||
|
||||
</div>
|
||||
<input type='button' onclick='add_option()' value="Add Option"></input>
|
||||
<input type='button' onclick='del_option()' value="Delete Option"></input>
|
||||
</div></td><td style="vertical-align:top">
|
||||
Select a poll type: <select name='createpoll' id='polltype' onchange="update_vis()">
|
||||
<option value='[POLLTYPE_OPTION]'>POLLTYPE_OPTION</option>
|
||||
<option value='[POLLTYPE_TEXT]'>POLLTYPE_TEXT</option>
|
||||
<option value='[POLLTYPE_RATING]'>POLLTYPE_RATING</option>
|
||||
<option value='[POLLTYPE_MULTI]'>POLLTYPE_MULTI</option>
|
||||
</select><br>
|
||||
For how many days should this poll run? <input type='text' name='createpollduration' value='7' style='width:50px'></input><br>
|
||||
Enter your question: <input type='text' name='createpollquestion' value='' style='width:300px'></input><br>
|
||||
<div id='choiceamount'>Up to how many options should be chosen? <input name='choiceamount' value='2' style='width:30px'></div>
|
||||
<label><input type='checkbox' name='createpolladminonly' value='1'>Admin only?</label><br>
|
||||
</td></tr><tr><td colspan=2 style='text-align:center'>
|
||||
<input type='submit' value='Create poll'>
|
||||
</td></tr></table>
|
||||
</form>
|
||||
</body>
|
||||
</html>"}
|
||||
src << browse(output, "window=createplayerpoll;size=950x500")
|
||||
|
||||
/client/proc/create_poll_function(href_list)
|
||||
if(!check_rights(R_SERVER))
|
||||
return
|
||||
var/polltype = href_list["createpoll"]
|
||||
if(polltype != POLLTYPE_OPTION && polltype != POLLTYPE_TEXT && polltype != POLLTYPE_RATING && polltype != POLLTYPE_MULTI)
|
||||
create_poll_window("<font color='red'>Invalid poll type</font>")
|
||||
return
|
||||
var/choice_amount = 0
|
||||
if(polltype == POLLTYPE_MULTI)
|
||||
choice_amount = text2num(href_list["choiceamount"])
|
||||
if(!isnum(choice_amount) || choice_amount < 1)
|
||||
create_poll_window("<font color='red'>Invalid choice amount. Must be at least 1.</font>")
|
||||
return
|
||||
var/poll_len = text2num(href_list["createpollduration"])
|
||||
if(!isnum(poll_len) || poll_len < 1)
|
||||
create_poll_window("<font color='red'>Invalid poll duration. Must be at least 1.</font>")
|
||||
return
|
||||
var/adminonly = text2num(href_list["createpolladminonly"]) ? 1 : 0
|
||||
var/sql_ckey = sanitizeSQL(ckey)
|
||||
var/question = href_list["createpollquestion"]
|
||||
if(!question)
|
||||
create_poll_window("<font color='red'>Question cannot be blank.</font>")
|
||||
return
|
||||
question = sanitizeSQL(question)
|
||||
|
||||
var/starttime
|
||||
var/endtime
|
||||
var/DBQuery/query = GLOB.dbcon.NewQuery("SELECT Now() AS starttime, ADDDATE(Now(), INTERVAL [poll_len] DAY) AS endtime")
|
||||
query.Execute()
|
||||
while(query.NextRow())
|
||||
starttime = query.item[1]
|
||||
endtime = query.item[2]
|
||||
|
||||
var/pollquery = "INSERT INTO [format_table_name("poll_question")] (polltype, starttime, endtime, question, adminonly, multiplechoiceoptions, createdby_ckey, createdby_ip) VALUES ('[polltype]', '[starttime]', '[endtime]', '[question]', '[adminonly]', '[choice_amount]', '[sql_ckey]', '[address]')"
|
||||
var/idquery = "SELECT id FROM [format_table_name("poll_question")] WHERE question = '[question]' AND starttime = '[starttime]' AND endtime = '[endtime]' AND createdby_ckey = '[sql_ckey]' AND createdby_ip = '[address]'"
|
||||
var/list/option_queries = list()
|
||||
if(polltype == POLLTYPE_MULTI || polltype == POLLTYPE_RATING || polltype == POLLTYPE_OPTION)
|
||||
var/numoptions = text2num(href_list["createpollnumoptions"])
|
||||
if(!numoptions)
|
||||
create_poll_window("<font color='red'>Invalid number of options</font>")
|
||||
return
|
||||
for(var/I in 1 to numoptions)
|
||||
var/option = href_list["createpolloption[I]option"]
|
||||
if(!option)
|
||||
create_poll_window("<font color='red'>Invalid option name for option [I]</font>")
|
||||
return
|
||||
option = sanitizeSQL(option)
|
||||
var/percentagecalc = 0
|
||||
if(text2num(href_list["createpolloption[I]percentagecalc"]))
|
||||
percentagecalc = 1
|
||||
var/minval = 0
|
||||
var/maxval = 0
|
||||
var/descmin = ""
|
||||
var/descmid = ""
|
||||
var/descmax = ""
|
||||
if(polltype == POLLTYPE_RATING)
|
||||
minval = text2num(href_list["createpolloption[I]minval"])
|
||||
if(!minval)
|
||||
create_poll_window("<font color='red'>Invalid minimum value for option [I]</font>")
|
||||
return
|
||||
maxval = text2num(href_list["createpolloption[I]maxval"])
|
||||
if(!maxval)
|
||||
create_poll_window("<font color='red'>Invalid maximum value for option [I]</font>")
|
||||
return
|
||||
if(minval >= maxval)
|
||||
create_poll_window("<font color='red'>Minimum rating value can't be more than maximum rating value</font>")
|
||||
return
|
||||
descmin = href_list["createpolloption[I]descmin"]
|
||||
if(descmin)
|
||||
descmin = sanitizeSQL(descmin)
|
||||
descmid = href_list["createpolloption[I]descmid"]
|
||||
if(descmid)
|
||||
descmid = sanitizeSQL(descmid)
|
||||
descmax = href_list["createpolloption[I]descmax"]
|
||||
if(descmax)
|
||||
descmax = sanitizeSQL(descmax)
|
||||
option_queries += "INSERT INTO [format_table_name("poll_option")] (pollid, text, percentagecalc, minval, maxval, descmin, descmid, descmax) VALUES ('{POLLID}', '[option]', '[percentagecalc]', '[minval]', '[maxval]', '[descmin]', '[descmid]', '[descmax]')"
|
||||
|
||||
query = GLOB.dbcon.NewQuery(pollquery)
|
||||
if(!query.Execute())
|
||||
var/err = query.ErrorMsg()
|
||||
create_poll_window("<font color='red'>An SQL error has occured while creating your poll</font>")
|
||||
log_game("SQL ERROR adding new poll question to table. Error : \[[err]\]\n")
|
||||
return
|
||||
var/pollid = 0
|
||||
query = GLOB.dbcon.NewQuery(idquery)
|
||||
if(!query.Execute())
|
||||
var/err = query.ErrorMsg()
|
||||
create_poll_window("<font color='red'>An SQL error has occured while creating your poll</font>")
|
||||
log_game("SQL ERROR obtaining id from poll_question table. Error : \[[err]\]\n")
|
||||
return
|
||||
if(query.NextRow())
|
||||
pollid = text2num(query.item[1])
|
||||
for(var/querytext in option_queries)
|
||||
query = GLOB.dbcon.NewQuery(replacetext(idquery, "{POLLID}", pollid))
|
||||
if(!query.Execute())
|
||||
var/err = query.ErrorMsg()
|
||||
create_poll_window("<font color='red'>An SQL error has occured while creating your poll</font>")
|
||||
log_game("SQL ERROR obtaining id from poll_question table. Error : \[[err]\]\n")
|
||||
return
|
||||
create_poll_window("<font color='#008800'>Your poll has been successfully created</font>")
|
||||
return pollid
|
||||
@@ -4,8 +4,8 @@
|
||||
|
||||
if(!check_rights(R_BAN)) return
|
||||
|
||||
establish_db_connection()
|
||||
if(!GLOB.dbcon.IsConnected())
|
||||
if(!SSdbcore.IsConnected())
|
||||
to_chat(usr, "<span class='boldannounce'>Database connection failure when attempting to make DB ban. Please freeze them and write their ckey in notepad, so they can be banned when the DB returns.</span>")
|
||||
return
|
||||
|
||||
var/serverip = "[world.internet_address]:[world.port]"
|
||||
@@ -86,16 +86,22 @@
|
||||
message_admins("<font color='red'>[key_name_admin(usr)] attempted to add a ban based on a non-existent mob, with no ckey provided. Report this bug.",1)
|
||||
return
|
||||
|
||||
var/DBQuery/query = GLOB.dbcon.NewQuery("SELECT id FROM [format_table_name("player")] WHERE ckey = '[ckey]'")
|
||||
query.Execute()
|
||||
var/validckey = 0
|
||||
var/datum/db_query/query = SSdbcore.NewQuery("SELECT id FROM [format_table_name("player")] WHERE ckey=:ckey", list(
|
||||
"ckey" = ckey
|
||||
))
|
||||
if(!query.warn_execute())
|
||||
qdel(query)
|
||||
return
|
||||
var/validckey = FALSE
|
||||
if(query.NextRow())
|
||||
validckey = 1
|
||||
validckey = TRUE
|
||||
if(!validckey)
|
||||
if(!banned_mob || (banned_mob && !IsGuestKey(banned_mob.key)))
|
||||
message_admins("<font color='red'>[key_name_admin(usr)] attempted to ban [ckey], but [ckey] does not exist in the player database. Please only ban actual players.</font>",1)
|
||||
qdel(query)
|
||||
return
|
||||
|
||||
qdel(query)
|
||||
var/a_ckey
|
||||
var/a_computerid
|
||||
var/a_ip
|
||||
@@ -124,25 +130,51 @@
|
||||
else
|
||||
adminwho += ", [C]"
|
||||
|
||||
reason = sanitizeSQL(reason)
|
||||
|
||||
if(maxadminbancheck)
|
||||
var/DBQuery/adm_query = GLOB.dbcon.NewQuery("SELECT count(id) AS num FROM [format_table_name("ban")] WHERE (a_ckey = '[a_ckey]') AND (bantype = 'ADMIN_PERMABAN' OR (bantype = 'ADMIN_TEMPBAN' AND expiration_time > Now())) AND isnull(unbanned)")
|
||||
adm_query.Execute()
|
||||
var/datum/db_query/adm_query = SSdbcore.NewQuery("SELECT count(id) AS num FROM [format_table_name("ban")] WHERE (a_ckey=:a_ckey) AND (bantype = 'ADMIN_PERMABAN' OR (bantype = 'ADMIN_TEMPBAN' AND expiration_time > Now())) AND isnull(unbanned)", list(
|
||||
"a_ckey" = a_ckey
|
||||
))
|
||||
if(!adm_query.warn_execute())
|
||||
qdel(adm_query)
|
||||
return
|
||||
if(adm_query.NextRow())
|
||||
var/adm_bans = text2num(adm_query.item[1])
|
||||
if(adm_bans >= MAX_ADMIN_BANS_PER_ADMIN)
|
||||
to_chat(usr, "<span class='danger'>You already logged [MAX_ADMIN_BANS_PER_ADMIN] admin ban(s) or more. Do not abuse this function!</span>")
|
||||
qdel(adm_query)
|
||||
return
|
||||
qdel(adm_query)
|
||||
|
||||
var/sql = "INSERT INTO [format_table_name("ban")] (`id`,`bantime`,`serverip`,`bantype`,`reason`,`job`,`duration`,`rounds`,`expiration_time`,`ckey`,`computerid`,`ip`,`a_ckey`,`a_computerid`,`a_ip`,`who`,`adminwho`,`edits`,`unbanned`,`unbanned_datetime`,`unbanned_ckey`,`unbanned_computerid`,`unbanned_ip`) VALUES (null, Now(), '[serverip]', '[bantype_str]', '[reason]', '[job]', [(duration)?"[duration]":"0"], [(rounds)?"[rounds]":"0"], Now() + INTERVAL [(duration>0) ? duration : 0] MINUTE, '[ckey]', '[computerid]', '[ip]', '[a_ckey]', '[a_computerid]', '[a_ip]', '[who]', '[adminwho]', '', null, null, null, null, null)"
|
||||
var/DBQuery/query_insert = GLOB.dbcon.NewQuery(sql)
|
||||
query_insert.Execute()
|
||||
var/datum/db_query/query_insert = SSdbcore.NewQuery({"
|
||||
INSERT INTO [format_table_name("ban")] (`id`,`bantime`,`serverip`,`bantype`,`reason`,`job`,`duration`,`rounds`,`expiration_time`,`ckey`,`computerid`,`ip`,`a_ckey`,`a_computerid`,`a_ip`,`who`,`adminwho`,`edits`,`unbanned`,`unbanned_datetime`,`unbanned_ckey`,`unbanned_computerid`,`unbanned_ip`)
|
||||
VALUES (null, Now(), :serverip, :bantype_str, :reason, :job, :duration, :rounds, Now() + INTERVAL :duration MINUTE, :ckey, :computerid, :ip, :a_ckey, :a_computerid, :a_ip, :who, :adminwho, '', null, null, null, null, null)
|
||||
"}, list(
|
||||
// Get ready for parameters
|
||||
"serverip" = serverip,
|
||||
"bantype_str" = bantype_str,
|
||||
"reason" = reason,
|
||||
"job" = job,
|
||||
"duration" = (duration ? "[duration]" : "0"), // Strings are important here
|
||||
"rounds" = (rounds ? "[rounds]" : "0"), // And here
|
||||
"ckey" = ckey,
|
||||
"computerid" = computerid,
|
||||
"ip" = ip,
|
||||
"a_ckey" = a_ckey,
|
||||
"a_computerid" = a_computerid,
|
||||
"a_ip" = a_ip,
|
||||
"who" = who,
|
||||
"adminwho" = adminwho
|
||||
))
|
||||
if(!query_insert.warn_execute())
|
||||
qdel(query_insert)
|
||||
return
|
||||
|
||||
qdel(query_insert)
|
||||
to_chat(usr, "<span class='notice'>Ban saved to database.</span>")
|
||||
message_admins("[key_name_admin(usr)] has added a [bantype_str] for [ckey] [(job)?"([job])":""] [(duration > 0)?"([duration] minutes)":""] with the reason: \"[reason]\" to the ban database.",1)
|
||||
|
||||
if(announce_in_discord)
|
||||
SSdiscord.send2discord_simple(DISCORD_WEBHOOK_ADMIN, "**BAN ALERT** [a_ckey] applied a [bantype_str] on [ckey]")
|
||||
SSdiscord.send2discord_simple(DISCORD_WEBHOOK_ADMIN, "**\[Ban]** [a_ckey] applied a [bantype_str] on [ckey]")
|
||||
|
||||
if(kickbannedckey)
|
||||
if(banned_mob && banned_mob.client && banned_mob.client.ckey == banckey)
|
||||
@@ -157,6 +189,10 @@
|
||||
|
||||
if(!check_rights(R_BAN)) return
|
||||
|
||||
if(!SSdbcore.IsConnected())
|
||||
to_chat(usr, "<span class='boldannounce'>Database connection failure when attempting to remove DB ban. Please remember to unban them at a later date!.</span>")
|
||||
return
|
||||
|
||||
var/bantype_str
|
||||
var/isjobban // For job bans, which need to be removed from the job ban lists
|
||||
if(bantype)
|
||||
@@ -196,23 +232,28 @@
|
||||
else
|
||||
bantype_sql = "bantype = '[bantype_str]'"
|
||||
|
||||
var/sql = "SELECT id FROM [format_table_name("ban")] WHERE ckey = '[ckey]' AND [bantype_sql] AND (unbanned is null OR unbanned = false)"
|
||||
var/sql = "SELECT id FROM [format_table_name("ban")] WHERE ckey=:ckey AND [bantype_sql] AND (unbanned is null OR unbanned = false)"
|
||||
var/list/sql_params = list(
|
||||
"ckey" = ckey
|
||||
)
|
||||
if(job)
|
||||
sql += " AND job = '[job]'"
|
||||
|
||||
establish_db_connection()
|
||||
if(!GLOB.dbcon.IsConnected())
|
||||
return
|
||||
sql += " AND job=:job"
|
||||
sql_params["job"] = job
|
||||
|
||||
var/ban_id
|
||||
var/ban_number = 0 //failsafe
|
||||
|
||||
var/DBQuery/query = GLOB.dbcon.NewQuery(sql)
|
||||
query.Execute()
|
||||
var/datum/db_query/query = SSdbcore.NewQuery(sql, sql_params)
|
||||
if(!query.warn_execute())
|
||||
qdel(query)
|
||||
return
|
||||
|
||||
while(query.NextRow())
|
||||
ban_id = query.item[1]
|
||||
ban_number++
|
||||
|
||||
qdel(query)
|
||||
|
||||
if(ban_number == 0)
|
||||
to_chat(usr, "<span class='warning'>Database update failed due to no bans fitting the search criteria. If this is not a legacy ban you should contact the database admin.</span>")
|
||||
return
|
||||
@@ -241,8 +282,12 @@
|
||||
to_chat(usr, "Cancelled")
|
||||
return
|
||||
|
||||
var/DBQuery/query = GLOB.dbcon.NewQuery("SELECT ckey, duration, reason, job FROM [format_table_name("ban")] WHERE id = [banid]")
|
||||
query.Execute()
|
||||
var/datum/db_query/query = SSdbcore.NewQuery("SELECT ckey, duration, reason, job FROM [format_table_name("ban")] WHERE id=:banid", list(
|
||||
"banid" = banid
|
||||
))
|
||||
if(!query.warn_execute())
|
||||
qdel(query)
|
||||
return
|
||||
|
||||
var/eckey = usr.ckey //Editing admin ckey
|
||||
var/pckey //(banned) Player ckey
|
||||
@@ -257,22 +302,31 @@
|
||||
job = query.item[4]
|
||||
else
|
||||
to_chat(usr, "Invalid ban id. Contact the database admin")
|
||||
qdel(query)
|
||||
return
|
||||
|
||||
reason = sanitizeSQL(reason)
|
||||
qdel(query)
|
||||
var/value
|
||||
|
||||
switch(param)
|
||||
if("reason")
|
||||
if(!value)
|
||||
value = input("Insert the new reason for [pckey]'s ban", "New Reason", "[reason]", null) as null|text
|
||||
value = sanitizeSQL(value)
|
||||
if(!value)
|
||||
to_chat(usr, "Cancelled")
|
||||
return
|
||||
|
||||
var/DBQuery/update_query = GLOB.dbcon.NewQuery("UPDATE [format_table_name("ban")] SET reason = '[value]', edits = CONCAT(edits,'- [eckey] changed ban reason from <cite><b>\\\"[reason]\\\"</b></cite> to <cite><b>\\\"[value]\\\"</b></cite><BR>') WHERE id = [banid]")
|
||||
update_query.Execute()
|
||||
var/edit_reason = "- [eckey] changed ban reason from <cite><b>\\\"[reason]\\\"</b></cite> to <cite><b>\\\"[value]\\\"</b></cite><BR>"
|
||||
var/datum/db_query/update_query = SSdbcore.NewQuery("UPDATE [format_table_name("ban")] SET reason=:value, edits = CONCAT(IFNULL(edits,''), :edittext) WHERE id=:banid", list(
|
||||
"edittext" = edit_reason,
|
||||
"banid" = banid,
|
||||
"value" = value
|
||||
))
|
||||
|
||||
if(!update_query.warn_execute())
|
||||
qdel(update_query)
|
||||
return
|
||||
qdel(update_query)
|
||||
message_admins("[key_name_admin(usr)] has edited a ban for [pckey]'s reason from [reason] to [value]",1)
|
||||
if("duration")
|
||||
if(!value)
|
||||
@@ -281,9 +335,18 @@
|
||||
to_chat(usr, "Cancelled")
|
||||
return
|
||||
|
||||
var/DBQuery/update_query = GLOB.dbcon.NewQuery("UPDATE [format_table_name("ban")] SET duration = [value], edits = CONCAT(edits,'- [eckey] changed ban duration from [duration] to [value]<br>'), expiration_time = DATE_ADD(bantime, INTERVAL [value] MINUTE) WHERE id = [banid]")
|
||||
var/edittext = "- [eckey] changed ban duration from [duration] to [value]<br>"
|
||||
var/datum/db_query/update_query = SSdbcore.NewQuery("UPDATE [format_table_name("ban")] SET duration=:value, edits = CONCAT(IFNULL(edits, ''), :edittext), expiration_time = DATE_ADD(bantime, INTERVAL :value MINUTE) WHERE id=:banid", list(
|
||||
"edittext" = edittext,
|
||||
"banid" = banid,
|
||||
"value" = value
|
||||
))
|
||||
if(!update_query.warn_execute())
|
||||
qdel(update_query)
|
||||
return
|
||||
|
||||
qdel(update_query)
|
||||
message_admins("[key_name_admin(usr)] has edited a ban for [pckey]'s duration from [duration] to [value]",1)
|
||||
update_query.Execute()
|
||||
if("unban")
|
||||
if(alert("Unban [pckey]?", "Unban?", "Yes", "No") == "Yes")
|
||||
DB_ban_unban_by_id(banid)
|
||||
@@ -302,21 +365,25 @@
|
||||
if(!check_rights(R_BAN))
|
||||
return
|
||||
|
||||
var/sql = "SELECT ckey FROM [format_table_name("ban")] WHERE id = [id]"
|
||||
|
||||
establish_db_connection()
|
||||
if(!GLOB.dbcon.IsConnected())
|
||||
if(!SSdbcore.IsConnected())
|
||||
to_chat(usr, "<span class='boldannounce'>Database connection failure when attempting to remove DB ban. Please remember to unban them at a later date!.</span>")
|
||||
return
|
||||
|
||||
var/ban_number = 0 //failsafe
|
||||
|
||||
var/pckey
|
||||
var/DBQuery/query = GLOB.dbcon.NewQuery(sql)
|
||||
query.Execute()
|
||||
var/datum/db_query/query = SSdbcore.NewQuery("SELECT ckey FROM [format_table_name("ban")] WHERE id=:banid", list(
|
||||
"banid" = id
|
||||
))
|
||||
if(!query.warn_execute())
|
||||
qdel(query)
|
||||
return
|
||||
while(query.NextRow())
|
||||
pckey = query.item[1]
|
||||
ban_number++
|
||||
|
||||
qdel(query)
|
||||
|
||||
if(ban_number == 0)
|
||||
to_chat(usr, "<span class='warning'>Database update failed due to a ban id not being present in the database.</span>")
|
||||
return
|
||||
@@ -332,12 +399,19 @@
|
||||
var/unban_computerid = src.owner:computer_id
|
||||
var/unban_ip = src.owner:address
|
||||
|
||||
var/sql_update = "UPDATE [format_table_name("ban")] SET unbanned = 1, unbanned_datetime = Now(), unbanned_ckey = '[unban_ckey]', unbanned_computerid = '[unban_computerid]', unbanned_ip = '[unban_ip]' WHERE id = [id]"
|
||||
message_admins("[key_name_admin(usr)] has lifted [pckey]'s ban.",1)
|
||||
var/datum/db_query/query_update = SSdbcore.NewQuery("UPDATE [format_table_name("ban")] SET unbanned = 1, unbanned_datetime = Now(), unbanned_ckey=:unban_ckey, unbanned_computerid=:unban_computerid, unbanned_ip=:unban_ip WHERE id=:id", list(
|
||||
"unban_ckey" = unban_ckey,
|
||||
"unban_computerid" = unban_computerid,
|
||||
"unban_ip" = unban_ip,
|
||||
"id" = id
|
||||
))
|
||||
if(!query_update.warn_execute())
|
||||
qdel(query_update)
|
||||
return
|
||||
|
||||
var/DBQuery/query_update = GLOB.dbcon.NewQuery(sql_update)
|
||||
query_update.Execute()
|
||||
qdel(query_update)
|
||||
|
||||
message_admins("[key_name_admin(usr)] has lifted [pckey]'s ban.")
|
||||
flag_account_for_forum_sync(pckey)
|
||||
|
||||
|
||||
@@ -360,8 +434,7 @@
|
||||
if(!check_rights(R_BAN))
|
||||
return
|
||||
|
||||
establish_db_connection()
|
||||
if(!GLOB.dbcon.IsConnected())
|
||||
if(!SSdbcore.IsConnected())
|
||||
to_chat(usr, "<span class='warning'>Failed to establish database connection</span>")
|
||||
return
|
||||
|
||||
@@ -436,8 +509,6 @@
|
||||
|
||||
adminckey = ckey(adminckey)
|
||||
playerckey = ckey(playerckey)
|
||||
playerip = sanitizeSQL(playerip)
|
||||
playercid = sanitizeSQL(playercid)
|
||||
|
||||
if(adminckey || playerckey || playerip || playercid || dbbantype)
|
||||
|
||||
@@ -461,24 +532,34 @@
|
||||
var/cidsearch = ""
|
||||
var/bantypesearch = ""
|
||||
|
||||
var/list/sql_params = list()
|
||||
|
||||
if(!match)
|
||||
if(adminckey)
|
||||
adminsearch = "AND a_ckey = '[adminckey]' "
|
||||
adminsearch = "AND a_ckey=:adminckey "
|
||||
sql_params["adminckey"] = adminckey
|
||||
if(playerckey)
|
||||
playersearch = "AND ckey = '[playerckey]' "
|
||||
playersearch = "AND ckey=:playerckey "
|
||||
sql_params["playerckey"] = playerckey
|
||||
if(playerip)
|
||||
ipsearch = "AND ip = '[playerip]' "
|
||||
ipsearch = "AND ip=:playerip "
|
||||
sql_params["playerip"] = playerip
|
||||
if(playercid)
|
||||
cidsearch = "AND computerid = '[playercid]' "
|
||||
cidsearch = "AND computerid=:playercid "
|
||||
sql_params["playercid"] = playercid
|
||||
else
|
||||
if(adminckey && length(adminckey) >= 3)
|
||||
adminsearch = "AND a_ckey LIKE '[adminckey]%' "
|
||||
adminsearch = "AND a_ckey LIKE :adminckey "
|
||||
sql_params["adminckey"] = "[adminckey]%"
|
||||
if(playerckey && length(playerckey) >= 3)
|
||||
playersearch = "AND ckey LIKE '[playerckey]%' "
|
||||
playersearch = "AND ckey LIKE :playerckey "
|
||||
sql_params["playerckey"] = "[playerckey]%"
|
||||
if(playerip && length(playerip) >= 3)
|
||||
ipsearch = "AND ip LIKE '[playerip]%' "
|
||||
ipsearch = "AND ip LIKE :playerip "
|
||||
sql_params["playerip"] = "[playerip]%"
|
||||
if(playercid && length(playercid) >= 7)
|
||||
cidsearch = "AND computerid LIKE '[playercid]%' "
|
||||
cidsearch = "AND computerid LIKE :playercid "
|
||||
sql_params["playercid"] = "[playercid]%"
|
||||
|
||||
if(dbbantype)
|
||||
bantypesearch = "AND bantype = "
|
||||
@@ -500,8 +581,13 @@
|
||||
bantypesearch += "'PERMABAN' "
|
||||
|
||||
|
||||
var/DBQuery/select_query = GLOB.dbcon.NewQuery("SELECT id, bantime, bantype, reason, job, duration, expiration_time, ckey, a_ckey, unbanned, unbanned_ckey, unbanned_datetime, edits, ip, computerid FROM [format_table_name("ban")] WHERE 1 [playersearch] [adminsearch] [ipsearch] [cidsearch] [bantypesearch] ORDER BY bantime DESC LIMIT 100")
|
||||
select_query.Execute()
|
||||
var/datum/db_query/select_query = SSdbcore.NewQuery({"
|
||||
SELECT id, bantime, bantype, reason, job, duration, expiration_time, ckey, a_ckey, unbanned, unbanned_ckey, unbanned_datetime, edits, ip, computerid
|
||||
FROM [format_table_name("ban")] WHERE 1 [playersearch] [adminsearch] [ipsearch] [cidsearch] [bantypesearch] ORDER BY bantime DESC LIMIT 100"}, sql_params)
|
||||
|
||||
if(!select_query.warn_execute())
|
||||
qdel(select_query)
|
||||
return
|
||||
|
||||
while(select_query.NextRow())
|
||||
var/banid = select_query.item[1]
|
||||
@@ -552,7 +638,7 @@
|
||||
output += "</tr>"
|
||||
output += "<tr bgcolor='[dcolor]'>"
|
||||
output += "<td align='center' colspan='2' bgcolor=''><b>IP:</b> [ip]</td>"
|
||||
output += "<td align='center' colspan='3' bgcolor=''><b>CIP:</b> [cid]</td>"
|
||||
output += "<td align='center' colspan='3' bgcolor=''><b>CID:</b> [cid]</td>"
|
||||
output += "</tr>"
|
||||
output += "<tr bgcolor='[lcolor]'>"
|
||||
output += "<td align='center' colspan='5'><b>Reason: [(unbanned) ? "" : "(<a href=\"byond://?src=[UID()];dbbanedit=reason;dbbanid=[banid]\">Edit</a>)"]</b> <cite>\"[reason]\"</cite></td>"
|
||||
@@ -574,12 +660,17 @@
|
||||
|
||||
output += "</table></div>"
|
||||
|
||||
qdel(select_query)
|
||||
|
||||
usr << browse(output,"window=lookupbans;size=900x700")
|
||||
|
||||
/proc/flag_account_for_forum_sync(ckey)
|
||||
if(!GLOB.dbcon)
|
||||
if(!SSdbcore.IsConnected())
|
||||
return
|
||||
var/skey = sanitizeSQL(ckey)
|
||||
var/sql = "UPDATE [format_table_name("player")] SET fupdate = 1 WHERE ckey = '[skey]'"
|
||||
var/DBQuery/adm_query = GLOB.dbcon.NewQuery(sql)
|
||||
adm_query.Execute()
|
||||
var/datum/db_query/adm_query = SSdbcore.NewQuery("UPDATE [format_table_name("player")] SET fupdate = 1 WHERE ckey=:ckey", list(
|
||||
"ckey" = ckey
|
||||
))
|
||||
// We do nothing with output here so we dont need to wrap the warn_execute() inside an if statement
|
||||
adm_query.warn_execute()
|
||||
qdel(adm_query)
|
||||
|
||||
|
||||
@@ -23,7 +23,6 @@
|
||||
|
||||
/proc/get_ip_intel(ip, bypasscache = FALSE, updatecache = TRUE)
|
||||
var/datum/ipintel/res = new()
|
||||
ip = sanitizeSQL(ip)
|
||||
res.ip = ip
|
||||
. = res
|
||||
if(!ip || !config.ipintel_email || !SSipintel.enabled)
|
||||
@@ -34,24 +33,28 @@
|
||||
cachedintel.cache = TRUE
|
||||
return cachedintel
|
||||
|
||||
if(GLOB.dbcon.IsConnected())
|
||||
var/rating_bad = config.ipintel_rating_bad
|
||||
var/DBQuery/query_get_ip_intel = GLOB.dbcon.NewQuery({"
|
||||
if(SSdbcore.IsConnected())
|
||||
var/datum/db_query/query_get_ip_intel = SSdbcore.NewQuery({"
|
||||
SELECT date, intel, TIMESTAMPDIFF(MINUTE,date,NOW())
|
||||
FROM [format_table_name("ipintel")]
|
||||
WHERE
|
||||
ip = INET_ATON('[ip]')
|
||||
ip = INET_ATON(:ip)
|
||||
AND ((
|
||||
intel < [rating_bad]
|
||||
intel < :rating_bad
|
||||
AND
|
||||
date + INTERVAL [config.ipintel_save_good] HOUR > NOW()
|
||||
date + INTERVAL :save_good HOUR > NOW()
|
||||
) OR (
|
||||
intel >= [rating_bad]
|
||||
intel >= :rating_bad
|
||||
AND
|
||||
date + INTERVAL [config.ipintel_save_bad] HOUR > NOW()
|
||||
date + INTERVAL :save_bad HOUR > NOW()
|
||||
))
|
||||
"})
|
||||
if(!query_get_ip_intel.Execute())
|
||||
"}, list(
|
||||
"ip" = ip,
|
||||
"rating_bad" = config.ipintel_rating_bad,
|
||||
"save_good" = config.ipintel_save_good,
|
||||
"save_bad" = config.ipintel_save_bad,
|
||||
))
|
||||
if(!query_get_ip_intel.warn_execute())
|
||||
qdel(query_get_ip_intel)
|
||||
return
|
||||
if(query_get_ip_intel.NextRow())
|
||||
@@ -67,9 +70,16 @@
|
||||
res.intel = ip_intel_query(ip)
|
||||
if(updatecache && res.intel >= 0)
|
||||
SSipintel.cache[ip] = res
|
||||
if(GLOB.dbcon.IsConnected())
|
||||
var/DBQuery/query_add_ip_intel = GLOB.dbcon.NewQuery("INSERT INTO [format_table_name("ipintel")] (ip, intel) VALUES (INET_ATON('[ip]'), [res.intel]) ON DUPLICATE KEY UPDATE intel = VALUES(intel), date = NOW()")
|
||||
query_add_ip_intel.Execute()
|
||||
if(SSdbcore.IsConnected())
|
||||
var/datum/db_query/query_add_ip_intel = SSdbcore.NewQuery({"
|
||||
INSERT INTO [format_table_name("ipintel")] (ip, intel) VALUES (INET_ATON(:ip), :intel)
|
||||
ON DUPLICATE KEY UPDATE intel = VALUES(intel), date = NOW()"},
|
||||
list(
|
||||
"ip" = ip,
|
||||
"intel" = res.intel
|
||||
)
|
||||
)
|
||||
query_add_ip_intel.warn_execute()
|
||||
qdel(query_add_ip_intel)
|
||||
|
||||
|
||||
@@ -140,7 +150,7 @@
|
||||
return FALSE
|
||||
if(!config.ipintel_whitelist)
|
||||
return FALSE
|
||||
if(!GLOB.dbcon.IsConnected())
|
||||
if(!SSdbcore.IsConnected())
|
||||
return FALSE
|
||||
if(!ipintel_badip_check(t_ip))
|
||||
return FALSE
|
||||
@@ -157,12 +167,16 @@
|
||||
if(!valid_hours)
|
||||
log_debug("ipintel_badip_check reports misconfigured ipintel_save_bad directive")
|
||||
return FALSE
|
||||
target_ip = sanitizeSQL(target_ip)
|
||||
rating_bad = sanitizeSQL(rating_bad)
|
||||
valid_hours = sanitizeSQL(valid_hours)
|
||||
var/check_sql = {"SELECT * FROM [format_table_name("ipintel")] WHERE ip = INET_ATON('[target_ip]') AND intel >= [rating_bad] AND (date + INTERVAL [valid_hours] HOUR) > NOW()"}
|
||||
var/DBQuery/query_get_ip_intel = GLOB.dbcon.NewQuery(check_sql)
|
||||
if(!query_get_ip_intel.Execute())
|
||||
var/datum/db_query/query_get_ip_intel = SSdbcore.NewQuery({"
|
||||
SELECT * FROM [format_table_name("ipintel")] WHERE ip = INET_ATON(:target_ip)
|
||||
AND intel >= :rating_bad AND (date + INTERVAL :valid_hours HOUR) > NOW()"},
|
||||
list(
|
||||
"target_ip" = target_ip,
|
||||
"rating_bad" = rating_bad,
|
||||
"valid_hours" = valid_hours
|
||||
)
|
||||
)
|
||||
if(!query_get_ip_intel.warn_execute())
|
||||
log_debug("ipintel_badip_check reports failed query execution")
|
||||
qdel(query_get_ip_intel)
|
||||
return FALSE
|
||||
@@ -175,36 +189,40 @@
|
||||
/proc/vpn_whitelist_check(target_ckey)
|
||||
if(!config.ipintel_whitelist)
|
||||
return FALSE
|
||||
var/target_sql_ckey = ckey(target_ckey)
|
||||
var/DBQuery/query_whitelist_check = GLOB.dbcon.NewQuery("SELECT * FROM [format_table_name("vpn_whitelist")] WHERE ckey = '[target_sql_ckey]'")
|
||||
if(!query_whitelist_check.Execute())
|
||||
var/err = query_whitelist_check.ErrorMsg()
|
||||
log_debug("SQL ERROR on proc/vpn_whitelist_check for ckey '[target_sql_ckey]'. Error : \[[err]\]\n")
|
||||
var/datum/db_query/query_whitelist_check = SSdbcore.NewQuery("SELECT * FROM [format_table_name("vpn_whitelist")] WHERE ckey=:ckey", list(
|
||||
"ckey" = target_ckey
|
||||
))
|
||||
if(!query_whitelist_check.warn_execute())
|
||||
qdel(query_whitelist_check)
|
||||
return FALSE
|
||||
if(query_whitelist_check.NextRow())
|
||||
qdel(query_whitelist_check)
|
||||
return TRUE // At least one row in the whitelist names their ckey. That means they are whitelisted.
|
||||
qdel(query_whitelist_check)
|
||||
return FALSE
|
||||
|
||||
/proc/vpn_whitelist_add(target_ckey)
|
||||
var/target_sql_ckey = ckey(target_ckey)
|
||||
var/reason_string = input(usr, "Enter link to the URL of their whitelist request on the forum.","Reason required") as message|null
|
||||
if(!reason_string)
|
||||
return FALSE
|
||||
reason_string = sanitizeSQL(reason_string)
|
||||
var/DBQuery/query_whitelist_add = GLOB.dbcon.NewQuery("INSERT INTO [format_table_name("vpn_whitelist")] (ckey,reason) VALUES ('[target_sql_ckey]','[reason_string]')")
|
||||
if(!query_whitelist_add.Execute())
|
||||
var/err = query_whitelist_add.ErrorMsg()
|
||||
log_debug("SQL ERROR on proc/vpn_whitelist_add for ckey '[target_sql_ckey]'. Error : \[[err]\]\n")
|
||||
var/datum/db_query/query_whitelist_add = SSdbcore.NewQuery("INSERT INTO [format_table_name("vpn_whitelist")] (ckey,reason) VALUES (:targetckey, :reason)", list(
|
||||
"targetckey" = target_ckey,
|
||||
"reason" = reason_string
|
||||
))
|
||||
if(!query_whitelist_add.warn_execute())
|
||||
qdel(query_whitelist_add)
|
||||
return FALSE
|
||||
qdel(query_whitelist_add)
|
||||
return TRUE
|
||||
|
||||
/proc/vpn_whitelist_remove(target_ckey)
|
||||
var/target_sql_ckey = ckey(target_ckey)
|
||||
var/DBQuery/query_whitelist_remove = GLOB.dbcon.NewQuery("DELETE FROM [format_table_name("vpn_whitelist")] WHERE ckey = '[target_sql_ckey]'")
|
||||
if(!query_whitelist_remove.Execute())
|
||||
var/err = query_whitelist_remove.ErrorMsg()
|
||||
log_debug("SQL ERROR on proc/vpn_whitelist_remove for ckey '[target_sql_ckey]'. Error : \[[err]\]\n")
|
||||
var/datum/db_query/query_whitelist_remove = SSdbcore.NewQuery("DELETE FROM [format_table_name("vpn_whitelist")] WHERE ckey=:targetckey", list(
|
||||
"targetckey" = target_ckey
|
||||
))
|
||||
if(!query_whitelist_remove.warn_execute())
|
||||
qdel(query_whitelist_remove)
|
||||
return FALSE
|
||||
qdel(query_whitelist_remove)
|
||||
return TRUE
|
||||
|
||||
/proc/vpn_whitelist_panel(target_ckey as text)
|
||||
|
||||
@@ -60,9 +60,7 @@
|
||||
if(!check_rights(R_PERMISSIONS))
|
||||
return
|
||||
|
||||
establish_db_connection()
|
||||
|
||||
if(!GLOB.dbcon.IsConnected())
|
||||
if(!SSdbcore.IsConnected())
|
||||
to_chat(usr, "<span class='warning'>Failed to establish database connection</span>")
|
||||
return
|
||||
|
||||
@@ -77,28 +75,63 @@
|
||||
if(!istext(adm_ckey) || !istext(new_rank))
|
||||
return
|
||||
|
||||
var/DBQuery/select_query = GLOB.dbcon.NewQuery("SELECT id FROM [format_table_name("admin")] WHERE ckey = '[adm_ckey]'")
|
||||
select_query.Execute()
|
||||
var/datum/db_query/select_query = SSdbcore.NewQuery("SELECT id FROM [format_table_name("admin")] WHERE ckey=:adm_ckey", list(
|
||||
"adm_ckey" = adm_ckey
|
||||
))
|
||||
if(!select_query.warn_execute())
|
||||
qdel(select_query)
|
||||
return
|
||||
|
||||
var/new_admin = 1
|
||||
var/new_admin = TRUE
|
||||
var/admin_id
|
||||
while(select_query.NextRow())
|
||||
new_admin = 0
|
||||
new_admin = FALSE
|
||||
admin_id = text2num(select_query.item[1])
|
||||
|
||||
qdel(select_query)
|
||||
flag_account_for_forum_sync(adm_ckey)
|
||||
if(new_admin)
|
||||
var/DBQuery/insert_query = GLOB.dbcon.NewQuery("INSERT INTO [format_table_name("admin")] (`id`, `ckey`, `rank`, `level`, `flags`) VALUES (null, '[adm_ckey]', '[new_rank]', -1, 0)")
|
||||
insert_query.Execute()
|
||||
var/DBQuery/log_query = GLOB.dbcon.NewQuery("INSERT INTO [format_table_name("admin_log")] (`datetime` ,`adminckey` ,`adminip` ,`log` ) VALUES (Now() , '[usr.ckey]', '[usr.client.address]', 'Added new admin [adm_ckey] to rank [new_rank]');")
|
||||
log_query.Execute()
|
||||
var/datum/db_query/insert_query = SSdbcore.NewQuery("INSERT INTO [format_table_name("admin")] (`id`, `ckey`, `rank`, `level`, `flags`) VALUES (null, :adm_ckey, :new_rank, -1, 0)", list(
|
||||
"adm_ckey" = adm_ckey,
|
||||
"new_rank" = new_rank
|
||||
))
|
||||
if(!insert_query.warn_execute())
|
||||
qdel(insert_query)
|
||||
return
|
||||
qdel(insert_query)
|
||||
|
||||
var/logtxt = "Added new admin [adm_ckey] to rank [new_rank]"
|
||||
var/datum/db_query/log_query = SSdbcore.NewQuery("INSERT INTO [format_table_name("admin_log")] (`datetime` ,`adminckey` ,`adminip` ,`log` ) VALUES (Now() , :uckey, :uip, :logtxt)", list(
|
||||
"uckey" = usr.ckey,
|
||||
"uip" = usr.client.address,
|
||||
"logtxt" = logtxt
|
||||
))
|
||||
if(!log_query.warn_execute())
|
||||
qdel(log_query)
|
||||
return
|
||||
qdel(log_query)
|
||||
|
||||
to_chat(usr, "<span class='notice'>New admin added.</span>")
|
||||
else
|
||||
if(!isnull(admin_id) && isnum(admin_id))
|
||||
var/DBQuery/insert_query = GLOB.dbcon.NewQuery("UPDATE [format_table_name("admin")] SET rank = '[new_rank]' WHERE id = [admin_id]")
|
||||
insert_query.Execute()
|
||||
var/DBQuery/log_query = GLOB.dbcon.NewQuery("INSERT INTO [format_table_name("admin_log")] (`datetime` ,`adminckey` ,`adminip` ,`log` ) VALUES (Now() , '[usr.ckey]', '[usr.client.address]', 'Edited the rank of [adm_ckey] to [new_rank]');")
|
||||
log_query.Execute()
|
||||
var/datum/db_query/insert_query = SSdbcore.NewQuery("UPDATE [format_table_name("admin")] SET rank=:new_rank WHERE id=:admin_id", list(
|
||||
"new_rank" = new_rank,
|
||||
"admin_id" = admin_id,
|
||||
))
|
||||
if(!insert_query.warn_execute())
|
||||
qdel(insert_query)
|
||||
return
|
||||
qdel(insert_query)
|
||||
|
||||
var/logtxt = "Edited the rank of [adm_ckey] to [new_rank]"
|
||||
var/datum/db_query/log_query = SSdbcore.NewQuery("INSERT INTO [format_table_name("admin_log")] (`datetime` ,`adminckey` ,`adminip` ,`log` ) VALUES (Now() , :uckey, :uip, :logtxt)", list(
|
||||
"uckey" = usr.ckey,
|
||||
"uip" = usr.client.address,
|
||||
"logtxt" = logtxt,
|
||||
))
|
||||
if(!log_query.warn_execute())
|
||||
qdel(log_query)
|
||||
return
|
||||
qdel(log_query)
|
||||
to_chat(usr, "<span class='notice'>Admin rank changed.</span>")
|
||||
|
||||
/datum/admins/proc/log_admin_permission_modification(var/adm_ckey, var/new_permission)
|
||||
@@ -116,8 +149,7 @@
|
||||
if(!check_rights(R_PERMISSIONS))
|
||||
return
|
||||
|
||||
establish_db_connection()
|
||||
if(!GLOB.dbcon.IsConnected())
|
||||
if(!SSdbcore.IsConnected())
|
||||
to_chat(usr, "<span class='warning'>Failed to establish database connection</span>")
|
||||
return
|
||||
|
||||
@@ -135,8 +167,12 @@
|
||||
if(!istext(adm_ckey) || !isnum(new_permission))
|
||||
return
|
||||
|
||||
var/DBQuery/select_query = GLOB.dbcon.NewQuery("SELECT id, flags FROM [format_table_name("admin")] WHERE ckey = '[adm_ckey]'")
|
||||
select_query.Execute()
|
||||
var/datum/db_query/select_query = SSdbcore.NewQuery("SELECT id, flags FROM [format_table_name("admin")] WHERE ckey=:adm_ckey", list(
|
||||
"adm_ckey" = adm_ckey
|
||||
))
|
||||
if(!select_query.warn_execute())
|
||||
qdel(select_query)
|
||||
return
|
||||
|
||||
var/admin_id
|
||||
var/admin_rights
|
||||
@@ -144,32 +180,72 @@
|
||||
admin_id = text2num(select_query.item[1])
|
||||
admin_rights = text2num(select_query.item[2])
|
||||
|
||||
qdel(select_query)
|
||||
if(!admin_id)
|
||||
return
|
||||
|
||||
flag_account_for_forum_sync(adm_ckey)
|
||||
if(admin_rights & new_permission) //This admin already has this permission, so we are removing it.
|
||||
var/DBQuery/insert_query = GLOB.dbcon.NewQuery("UPDATE [format_table_name("admin")] SET flags = [admin_rights & ~new_permission] WHERE id = [admin_id]")
|
||||
insert_query.Execute()
|
||||
var/DBQuery/log_query = GLOB.dbcon.NewQuery("INSERT INTO [format_table_name("admin_log")] (`datetime` ,`adminckey` ,`adminip` ,`log` ) VALUES (Now() , '[usr.ckey]', '[usr.client.address]', 'Removed permission [rights2text(new_permission)] (flag = [new_permission]) to admin [adm_ckey]');")
|
||||
log_query.Execute()
|
||||
var/datum/db_query/insert_query = SSdbcore.NewQuery("UPDATE [format_table_name("admin")] SET flags=:newflags WHERE id=:admin_id", list(
|
||||
"newflags" = (admin_rights & ~new_permission),
|
||||
"admin_id" = admin_id
|
||||
))
|
||||
if(!insert_query.warn_execute())
|
||||
qdel(insert_query)
|
||||
return
|
||||
qdel(insert_query)
|
||||
|
||||
var/logtxt = "Removed permission [rights2text(new_permission)] (flag = [new_permission]) to admin [adm_ckey]"
|
||||
var/datum/db_query/log_query = SSdbcore.NewQuery({"
|
||||
INSERT INTO [format_table_name("admin_log")] (`datetime` ,`adminckey` ,`adminip` ,`log`)
|
||||
VALUES (Now() , :uckey, :uip, :logtxt)"}, list(
|
||||
"uckey" = usr.ckey,
|
||||
"uip" = usr.client.address,
|
||||
"logtxt" = logtxt
|
||||
))
|
||||
if(!log_query.warn_execute())
|
||||
qdel(log_query)
|
||||
return
|
||||
qdel(log_query)
|
||||
to_chat(usr, "<span class='notice'>Permission removed.</span>")
|
||||
else //This admin doesn't have this permission, so we are adding it.
|
||||
var/DBQuery/insert_query = GLOB.dbcon.NewQuery("UPDATE [format_table_name("admin")] SET flags = '[admin_rights | new_permission]' WHERE id = [admin_id]")
|
||||
insert_query.Execute()
|
||||
var/DBQuery/log_query = GLOB.dbcon.NewQuery("INSERT INTO [format_table_name("admin_log")] (`datetime` ,`adminckey` ,`adminip` ,`log` ) VALUES (Now() , '[usr.ckey]', '[usr.client.address]', 'Added permission [rights2text(new_permission)] (flag = [new_permission]) to admin [adm_ckey]')")
|
||||
log_query.Execute()
|
||||
var/datum/db_query/insert_query = SSdbcore.NewQuery("UPDATE [format_table_name("admin")] SET flags=:newflags WHERE id=:admin_id", list(
|
||||
"newflags" = (admin_rights | new_permission),
|
||||
"admin_id" = admin_id
|
||||
))
|
||||
if(!insert_query.warn_execute())
|
||||
qdel(insert_query)
|
||||
return
|
||||
qdel(insert_query)
|
||||
|
||||
var/logtxt = "Added permission [rights2text(new_permission)] (flag = [new_permission]) to admin [adm_ckey]"
|
||||
var/datum/db_query/log_query = SSdbcore.NewQuery({"
|
||||
INSERT INTO [format_table_name("admin_log")] (`datetime` ,`adminckey` ,`adminip` ,`log`)
|
||||
VALUES (Now() , :uckey, :uip, :logtxt)"}, list(
|
||||
"uckey" = usr.ckey,
|
||||
"uip" = usr.client.address,
|
||||
"logtxt" = logtxt
|
||||
))
|
||||
|
||||
if(!log_query.warn_execute())
|
||||
qdel(log_query)
|
||||
return
|
||||
qdel(log_query)
|
||||
to_chat(usr, "<span class='notice'>Permission added.</span>")
|
||||
|
||||
/datum/admins/proc/updateranktodb(ckey,newrank)
|
||||
establish_db_connection()
|
||||
if(!GLOB.dbcon.IsConnected())
|
||||
if(!SSdbcore.IsConnected())
|
||||
return
|
||||
if(!check_rights(R_PERMISSIONS))
|
||||
return
|
||||
var/sql_ckey = sanitizeSQL(ckey)
|
||||
var/sql_admin_rank = sanitizeSQL(newrank)
|
||||
|
||||
var/DBQuery/query_update = GLOB.dbcon.NewQuery("UPDATE [format_table_name("player")] SET lastadminrank = '[sql_admin_rank]' WHERE ckey = '[sql_ckey]'")
|
||||
query_update.Execute()
|
||||
flag_account_for_forum_sync(sql_ckey)
|
||||
var/datum/db_query/query_update = SSdbcore.NewQuery("UPDATE [format_table_name("player")] SET lastadminrank=:admin_rank WHERE ckey=:ckey", list(
|
||||
"admin_rank" = newrank,
|
||||
"ckey" = ckey
|
||||
))
|
||||
if(!query_update.warn_execute())
|
||||
qdel(query_update)
|
||||
return
|
||||
|
||||
qdel(query_update)
|
||||
flag_account_for_forum_sync(ckey)
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
/proc/add_note(target_ckey, notetext, timestamp, adminckey, logged = 1, server, checkrights = 1)
|
||||
// Do not attemtp to remove the blank string from the server arg. It will break DB saving.
|
||||
/proc/add_note(target_ckey, notetext, timestamp, adminckey, logged = 1, server = "", checkrights = 1)
|
||||
if(checkrights && !check_rights(R_ADMIN|R_MOD))
|
||||
return
|
||||
if(!GLOB.dbcon.IsConnected())
|
||||
if(!SSdbcore.IsConnected())
|
||||
if(usr)
|
||||
to_chat(usr, "<span class='danger'>Failed to establish database connection.</span>")
|
||||
return
|
||||
@@ -14,17 +15,27 @@
|
||||
else
|
||||
target_ckey = ckey(target_ckey)
|
||||
|
||||
var/DBQuery/query_find_ckey = GLOB.dbcon.NewQuery("SELECT ckey, exp FROM [format_table_name("player")] WHERE ckey = '[target_ckey]'")
|
||||
if(!query_find_ckey.Execute())
|
||||
var/err = query_find_ckey.ErrorMsg()
|
||||
log_game("SQL ERROR obtaining ckey from player table. Error : \[[err]\]\n")
|
||||
var/datum/db_query/query_find_ckey = SSdbcore.NewQuery("SELECT ckey, exp FROM [format_table_name("player")] WHERE ckey=:ckey", list(
|
||||
"ckey" = target_ckey
|
||||
))
|
||||
|
||||
if(!query_find_ckey.warn_execute())
|
||||
qdel(query_find_ckey)
|
||||
return
|
||||
if(!query_find_ckey.NextRow())
|
||||
|
||||
var/ckey_found = FALSE
|
||||
var/exp_data
|
||||
while(query_find_ckey.NextRow())
|
||||
exp_data = query_find_ckey.item[2]
|
||||
ckey_found = TRUE
|
||||
|
||||
qdel(query_find_ckey)
|
||||
|
||||
if(!ckey_found)
|
||||
if(usr)
|
||||
to_chat(usr, "<span class='redtext'>[target_ckey] has not been seen before, you can only add notes to known players.</span>")
|
||||
return
|
||||
|
||||
var/exp_data = query_find_ckey.item[2]
|
||||
var/crew_number = 0
|
||||
if(exp_data)
|
||||
var/list/play_records = params2list(exp_data)
|
||||
@@ -34,25 +45,32 @@
|
||||
notetext = input(usr,"Write your note","Add Note") as message|null
|
||||
if(!notetext)
|
||||
return
|
||||
notetext = sanitizeSQL(notetext)
|
||||
if(!timestamp)
|
||||
timestamp = SQLtime()
|
||||
|
||||
if(!adminckey)
|
||||
adminckey = usr.ckey
|
||||
if(!adminckey)
|
||||
return
|
||||
else if(usr && (usr.ckey == ckey(adminckey))) // Don't ckeyize special note sources
|
||||
adminckey = ckey(adminckey)
|
||||
var/admin_sql_ckey = sanitizeSQL(adminckey)
|
||||
|
||||
if(!server)
|
||||
if(config && config.server_name)
|
||||
server = config.server_name
|
||||
server = sanitizeSQL(server)
|
||||
var/DBQuery/query_noteadd = GLOB.dbcon.NewQuery("INSERT INTO [format_table_name("notes")] (ckey, timestamp, notetext, adminckey, server, crew_playtime) VALUES ('[target_ckey]', '[timestamp]', '[notetext]', '[admin_sql_ckey]', '[server]', '[crew_number]')")
|
||||
if(!query_noteadd.Execute())
|
||||
var/err = query_noteadd.ErrorMsg()
|
||||
log_game("SQL ERROR adding new note to table. Error : \[[err]\]\n")
|
||||
|
||||
var/datum/db_query/query_noteadd = SSdbcore.NewQuery({"
|
||||
INSERT INTO [format_table_name("notes")] (ckey, timestamp, notetext, adminckey, server, crew_playtime)
|
||||
VALUES (:targetckey, NOW(), :notetext, :adminkey, :server, :crewnum)
|
||||
"}, list(
|
||||
"targetckey" = target_ckey,
|
||||
"notetext" = notetext,
|
||||
"adminkey" = adminckey,
|
||||
"server" = server,
|
||||
"crewnum" = crew_number
|
||||
))
|
||||
if(!query_noteadd.warn_execute())
|
||||
qdel(query_noteadd)
|
||||
return
|
||||
qdel(query_noteadd)
|
||||
if(logged)
|
||||
log_admin("[usr ? key_name(usr) : adminckey] has added a note to [target_ckey]: [notetext]")
|
||||
message_admins("[usr ? key_name_admin(usr) : adminckey] has added a note to [target_ckey]:<br>[notetext]")
|
||||
@@ -64,27 +82,33 @@
|
||||
var/ckey
|
||||
var/notetext
|
||||
var/adminckey
|
||||
if(!GLOB.dbcon.IsConnected())
|
||||
if(!SSdbcore.IsConnected())
|
||||
if(usr)
|
||||
to_chat(usr, "<span class='danger'>Failed to establish database connection.</span>")
|
||||
return
|
||||
if(!note_id)
|
||||
return
|
||||
note_id = text2num(note_id)
|
||||
var/DBQuery/query_find_note_del = GLOB.dbcon.NewQuery("SELECT ckey, notetext, adminckey FROM [format_table_name("notes")] WHERE id = [note_id]")
|
||||
if(!query_find_note_del.Execute())
|
||||
var/err = query_find_note_del.ErrorMsg()
|
||||
log_game("SQL ERROR obtaining ckey, notetext, adminckey from player table. Error : \[[err]\]\n")
|
||||
var/datum/db_query/query_find_note_del = SSdbcore.NewQuery("SELECT ckey, notetext, adminckey FROM [format_table_name("notes")] WHERE id=:note_id", list(
|
||||
"note_id" = note_id
|
||||
))
|
||||
if(!query_find_note_del.warn_execute())
|
||||
qdel(query_find_note_del)
|
||||
return
|
||||
if(query_find_note_del.NextRow())
|
||||
ckey = query_find_note_del.item[1]
|
||||
notetext = query_find_note_del.item[2]
|
||||
adminckey = query_find_note_del.item[3]
|
||||
var/DBQuery/query_del_note = GLOB.dbcon.NewQuery("DELETE FROM [format_table_name("notes")] WHERE id = [note_id]")
|
||||
if(!query_del_note.Execute())
|
||||
var/err = query_del_note.ErrorMsg()
|
||||
log_game("SQL ERROR removing note from table. Error : \[[err]\]\n")
|
||||
qdel(query_find_note_del)
|
||||
|
||||
var/datum/db_query/query_del_note = SSdbcore.NewQuery("DELETE FROM [format_table_name("notes")] WHERE id=:note_id", list(
|
||||
"note_id" = note_id
|
||||
))
|
||||
if(!query_del_note.warn_execute())
|
||||
qdel(query_del_note)
|
||||
return
|
||||
qdel(query_del_note)
|
||||
|
||||
log_admin("[usr ? key_name(usr) : "Bot"] has removed a note made by [adminckey] from [ckey]: [notetext]")
|
||||
message_admins("[usr ? key_name_admin(usr) : "Bot"] has removed a note made by [adminckey] from [ckey]:<br>[notetext]")
|
||||
show_note(ckey)
|
||||
@@ -92,7 +116,7 @@
|
||||
/proc/edit_note(note_id)
|
||||
if(!check_rights(R_ADMIN|R_MOD))
|
||||
return
|
||||
if(!GLOB.dbcon.IsConnected())
|
||||
if(!SSdbcore.IsConnected())
|
||||
if(usr)
|
||||
to_chat(usr, "<span class='danger'>Failed to establish database connection.</span>")
|
||||
return
|
||||
@@ -100,11 +124,11 @@
|
||||
return
|
||||
note_id = text2num(note_id)
|
||||
var/target_ckey
|
||||
var/sql_ckey = usr.ckey
|
||||
var/DBQuery/query_find_note_edit = GLOB.dbcon.NewQuery("SELECT ckey, notetext, adminckey FROM [format_table_name("notes")] WHERE id = [note_id]")
|
||||
if(!query_find_note_edit.Execute())
|
||||
var/err = query_find_note_edit.ErrorMsg()
|
||||
log_game("SQL ERROR obtaining notetext from notes table. Error : \[[err]\]\n")
|
||||
var/datum/db_query/query_find_note_edit = SSdbcore.NewQuery("SELECT ckey, notetext, adminckey FROM [format_table_name("notes")] WHERE id=:note_id", list(
|
||||
"note_id" = note_id
|
||||
))
|
||||
if(!query_find_note_edit.warn_execute())
|
||||
qdel(query_find_note_edit)
|
||||
return
|
||||
if(query_find_note_edit.NextRow())
|
||||
target_ckey = query_find_note_edit.item[1]
|
||||
@@ -113,17 +137,20 @@
|
||||
var/new_note = input("Input new note", "New Note", "[old_note]") as message|null
|
||||
if(!new_note)
|
||||
return
|
||||
new_note = sanitizeSQL(new_note)
|
||||
var/edit_text = "Edited by [sql_ckey] on [SQLtime()] from \"[old_note]\" to \"[new_note]\"<hr>"
|
||||
edit_text = sanitizeSQL(edit_text)
|
||||
var/DBQuery/query_update_note = GLOB.dbcon.NewQuery("UPDATE [format_table_name("notes")] SET notetext = '[new_note]', last_editor = '[sql_ckey]', edits = CONCAT(IFNULL(edits,''),'[edit_text]') WHERE id = [note_id]")
|
||||
if(!query_update_note.Execute())
|
||||
var/err = query_update_note.ErrorMsg()
|
||||
log_game("SQL ERROR editing note. Error : \[[err]\]\n")
|
||||
var/edit_text = "Edited by [usr.ckey] on [SQLtime()] from \"[old_note]\" to \"[new_note]\"<hr>"
|
||||
var/datum/db_query/query_update_note = SSdbcore.NewQuery("UPDATE [format_table_name("notes")] SET notetext=:new_note, last_editor=:akey, edits = CONCAT(IFNULL(edits,''),:edit_text) WHERE id=:note_id", list(
|
||||
"new_note" = new_note,
|
||||
"akey" = usr.ckey,
|
||||
"edit_text" = edit_text,
|
||||
"note_id" = note_id
|
||||
))
|
||||
if(!query_update_note.warn_execute())
|
||||
qdel(query_update_note)
|
||||
return
|
||||
log_admin("[usr ? key_name(usr) : "Bot"] has edited [target_ckey]'s note made by [adminckey] from \"[old_note]\" to \"[new_note]\"")
|
||||
message_admins("[usr ? key_name_admin(usr) : "Bot"] has edited [target_ckey]'s note made by [adminckey] from \"[old_note]\" to \"[new_note]\"")
|
||||
show_note(target_ckey)
|
||||
qdel(query_update_note)
|
||||
|
||||
/proc/show_note(target_ckey, index, linkless = 0)
|
||||
if(!check_rights(R_ADMIN|R_MOD))
|
||||
@@ -143,10 +170,13 @@
|
||||
output = navbar
|
||||
if(target_ckey)
|
||||
var/target_sql_ckey = ckey(target_ckey)
|
||||
var/DBQuery/query_get_notes = GLOB.dbcon.NewQuery("SELECT id, timestamp, notetext, adminckey, last_editor, server, crew_playtime FROM [format_table_name("notes")] WHERE ckey = '[target_sql_ckey]' ORDER BY timestamp")
|
||||
if(!query_get_notes.Execute())
|
||||
var/err = query_get_notes.ErrorMsg()
|
||||
log_game("SQL ERROR obtaining ckey, notetext, adminckey, last_editor, server, crew_playtime from notes table. Error : \[[err]\]\n")
|
||||
var/datum/db_query/query_get_notes = SSdbcore.NewQuery({"
|
||||
SELECT id, timestamp, notetext, adminckey, last_editor, server, crew_playtime
|
||||
FROM [format_table_name("notes")] WHERE ckey=:targetkey ORDER BY timestamp"}, list(
|
||||
"targetkey" = target_sql_ckey
|
||||
))
|
||||
if(!query_get_notes.warn_execute())
|
||||
qdel(query_get_notes)
|
||||
return
|
||||
output += "<h2><center>Notes of [target_ckey]</center></h2>"
|
||||
if(!linkless)
|
||||
@@ -171,13 +201,12 @@
|
||||
if(last_editor)
|
||||
output += " <font size='2'>Last edit by [last_editor] <a href='?_src_=holder;noteedits=[id]'>(Click here to see edit log)</a></font>"
|
||||
output += "<br>[notetext]<hr style='background:#000000; border:0; height:1px'>"
|
||||
qdel(query_get_notes)
|
||||
else if(index)
|
||||
var/index_ckey
|
||||
var/search
|
||||
output += "<center><a href='?_src_=holder;addnoteempty=1'>\[Add Note\]</a></center>"
|
||||
output += ruler
|
||||
if(!isnum(index))
|
||||
index = sanitizeSQL(index)
|
||||
switch(index)
|
||||
if(1)
|
||||
search = "^."
|
||||
@@ -185,10 +214,11 @@
|
||||
search = "^\[^\[:alpha:\]\]"
|
||||
else
|
||||
search = "^[index]"
|
||||
var/DBQuery/query_list_notes = GLOB.dbcon.NewQuery("SELECT DISTINCT ckey FROM [format_table_name("notes")] WHERE ckey REGEXP '[search]' ORDER BY ckey")
|
||||
if(!query_list_notes.Execute())
|
||||
var/err = query_list_notes.ErrorMsg()
|
||||
log_game("SQL ERROR obtaining ckey from notes table. Error : \[[err]\]\n")
|
||||
var/datum/db_query/query_list_notes = SSdbcore.NewQuery("SELECT DISTINCT ckey FROM [format_table_name("notes")] WHERE ckey REGEXP :search ORDER BY ckey", list(
|
||||
"search" = search
|
||||
))
|
||||
if(!query_list_notes.warn_execute())
|
||||
qdel(query_list_notes)
|
||||
return
|
||||
to_chat(usr, "<span class='notice'>Started regex note search for [search]. Please wait for results...</span>")
|
||||
message_admins("[usr.ckey] has started a note search with the following regex: [search] | CPU usage may be higher.")
|
||||
@@ -196,6 +226,7 @@
|
||||
index_ckey = query_list_notes.item[1]
|
||||
output += "<a href='?_src_=holder;shownoteckey=[index_ckey]'>[index_ckey]</a><br>"
|
||||
CHECK_TICK
|
||||
qdel(query_list_notes)
|
||||
message_admins("The note search started by [usr.ckey] has complete. CPU should return to normal.")
|
||||
else
|
||||
output += "<center><a href='?_src_=holder;addnoteempty=1'>\[Add Note\]</a></center>"
|
||||
|
||||
+53
-28
@@ -962,15 +962,17 @@
|
||||
show_note(index = target)
|
||||
|
||||
else if(href_list["noteedits"])
|
||||
var/note_id = sanitizeSQL("[href_list["noteedits"]]")
|
||||
var/DBQuery/query_noteedits = GLOB.dbcon.NewQuery("SELECT edits FROM [format_table_name("notes")] WHERE id = '[note_id]'")
|
||||
if(!query_noteedits.Execute())
|
||||
var/err = query_noteedits.ErrorMsg()
|
||||
log_game("SQL ERROR obtaining edits from notes table. Error : \[[err]\]\n")
|
||||
var/note_id = text2num(href_list["noteedits"])
|
||||
var/datum/db_query/query_noteedits = SSdbcore.NewQuery("SELECT edits FROM [format_table_name("notes")] WHERE id=:note_id", list(
|
||||
"note_id" = note_id
|
||||
))
|
||||
if(!query_noteedits.warn_execute())
|
||||
qdel(query_noteedits)
|
||||
return
|
||||
if(query_noteedits.NextRow())
|
||||
var/edit_log = query_noteedits.item[1]
|
||||
usr << browse(edit_log,"window=noteedits")
|
||||
qdel(query_noteedits)
|
||||
|
||||
else if(href_list["removejobban"])
|
||||
if(!check_rights(R_BAN)) return
|
||||
@@ -1080,15 +1082,17 @@
|
||||
usr.client.watchlist_show()
|
||||
|
||||
else if(href_list["watcheditlog"])
|
||||
var/target_ckey = sanitizeSQL("[href_list["watcheditlog"]]")
|
||||
var/DBQuery/query_watchedits = GLOB.dbcon.NewQuery("SELECT edits FROM [format_table_name("watch")] WHERE ckey = '[target_ckey]'")
|
||||
if(!query_watchedits.Execute())
|
||||
var/err = query_watchedits.ErrorMsg()
|
||||
log_game("SQL ERROR obtaining edits from watch table. Error : \[[err]\]\n")
|
||||
var/target_ckey = href_list["watcheditlog"]
|
||||
var/datum/db_query/query_watchedits = SSdbcore.NewQuery("SELECT edits FROM [format_table_name("watch")] WHERE ckey=:targetkey", list(
|
||||
"targetkey" = target_ckey
|
||||
))
|
||||
if(!query_watchedits.warn_execute())
|
||||
qdel(query_watchedits)
|
||||
return
|
||||
if(query_watchedits.NextRow())
|
||||
var/edit_log = query_watchedits.item[1]
|
||||
usr << browse(edit_log,"window=watchedits")
|
||||
qdel(query_watchedits)
|
||||
|
||||
else if(href_list["mute"])
|
||||
if(!check_rights(R_ADMIN|R_MOD))
|
||||
@@ -2784,15 +2788,17 @@
|
||||
|
||||
else if(href_list["memoeditlist"])
|
||||
if(!check_rights(R_SERVER)) return
|
||||
var/sql_key = sanitizeSQL("[href_list["memoeditlist"]]")
|
||||
var/DBQuery/query_memoedits = GLOB.dbcon.NewQuery("SELECT edits FROM [format_table_name("memo")] WHERE (ckey = '[sql_key]')")
|
||||
if(!query_memoedits.Execute())
|
||||
var/err = query_memoedits.ErrorMsg()
|
||||
log_game("SQL ERROR obtaining edits from memo table. Error : \[[err]\]\n")
|
||||
var/sql_key = href_list["memoeditlist"]
|
||||
var/datum/db_query/query_memoedits = SSdbcore.NewQuery("SELECT edits FROM [format_table_name("memo")] WHERE (ckey=:sql_key)", list(
|
||||
"sql_key" = sql_key
|
||||
))
|
||||
if(!query_memoedits.warn_execute())
|
||||
qdel(query_memoedits)
|
||||
return
|
||||
if(query_memoedits.NextRow())
|
||||
var/edit_log = query_memoedits.item[1]
|
||||
usr << browse(edit_log,"window=memoeditlist")
|
||||
qdel(query_memoedits)
|
||||
|
||||
else if(href_list["secretsfun"])
|
||||
if(!check_rights(R_SERVER|R_EVENT)) return
|
||||
@@ -3370,13 +3376,14 @@
|
||||
|
||||
// Library stuff
|
||||
else if(href_list["library_book_id"])
|
||||
var/isbn = sanitizeSQL(href_list["library_book_id"])
|
||||
var/isbn = text2num(href_list["library_book_id"])
|
||||
|
||||
if(href_list["view_library_book"])
|
||||
var/DBQuery/query_view_book = GLOB.dbcon.NewQuery("SELECT content, title FROM [format_table_name("library")] WHERE id=[isbn]")
|
||||
if(!query_view_book.Execute())
|
||||
var/err = query_view_book.ErrorMsg()
|
||||
log_game("SQL ERROR viewing book. Error : \[[err]\]\n")
|
||||
var/datum/db_query/query_view_book = SSdbcore.NewQuery("SELECT content, title FROM [format_table_name("library")] WHERE id=:isbn", list(
|
||||
"isbn" = isbn
|
||||
))
|
||||
if(!query_view_book.warn_execute())
|
||||
qdel(query_view_book)
|
||||
return
|
||||
|
||||
var/content = ""
|
||||
@@ -3393,27 +3400,32 @@
|
||||
popup.set_content(dat)
|
||||
popup.open(0)
|
||||
|
||||
qdel(query_view_book)
|
||||
log_admin("[key_name(usr)] has viewed the book [isbn].")
|
||||
message_admins("[key_name_admin(usr)] has viewed the book [isbn].")
|
||||
return
|
||||
|
||||
else if(href_list["unflag_library_book"])
|
||||
var/DBQuery/query_unflag_book = GLOB.dbcon.NewQuery("UPDATE [format_table_name("library")] SET flagged = 0 WHERE id=[isbn]")
|
||||
if(!query_unflag_book.Execute())
|
||||
var/err = query_unflag_book.ErrorMsg()
|
||||
log_game("SQL ERROR unflagging book. Error : \[[err]\]\n")
|
||||
var/datum/db_query/query_unflag_book = SSdbcore.NewQuery("UPDATE [format_table_name("library")] SET flagged = 0 WHERE id=:isbn", list(
|
||||
"isbn" = isbn
|
||||
))
|
||||
if(!query_unflag_book.warn_execute())
|
||||
qdel(query_unflag_book)
|
||||
return
|
||||
|
||||
qdel(query_unflag_book)
|
||||
log_admin("[key_name(usr)] has unflagged the book [isbn].")
|
||||
message_admins("[key_name_admin(usr)] has unflagged the book [isbn].")
|
||||
|
||||
else if(href_list["delete_library_book"])
|
||||
var/DBQuery/query_delbook = GLOB.dbcon.NewQuery("DELETE FROM [format_table_name("library")] WHERE id=[isbn]")
|
||||
if(!query_delbook.Execute())
|
||||
var/err = query_delbook.ErrorMsg()
|
||||
log_game("SQL ERROR deleting book. Error : \[[err]\]\n")
|
||||
var/datum/db_query/query_delbook = SSdbcore.NewQuery("DELETE FROM [format_table_name("library")] WHERE id=:isbn", list(
|
||||
"isbn" = isbn
|
||||
))
|
||||
if(!query_delbook.warn_execute())
|
||||
qdel(query_delbook)
|
||||
return
|
||||
|
||||
qdel(query_delbook)
|
||||
log_admin("[key_name(usr)] has deleted the book [isbn].")
|
||||
message_admins("[key_name_admin(usr)] has deleted the book [isbn].")
|
||||
|
||||
@@ -3446,6 +3458,19 @@
|
||||
if(!check_rights(R_ADMIN))
|
||||
return
|
||||
create_ccbdb_lookup(href_list["open_ccbdb"])
|
||||
else if(href_list["slowquery"])
|
||||
if(!check_rights(R_ADMIN))
|
||||
return
|
||||
message_admins("[key_name_admin(usr)] started responding to a query hang report") // So multiple admins dont try file the same report
|
||||
var/answer = href_list["slowquery"]
|
||||
if(answer == "yes")
|
||||
log_sql("[usr.key] | Reported a server hang")
|
||||
if(alert(usr, "Had you just pressed any admin buttons which could lag the server?", "Query server hang report", "Yes", "No") == "Yes")
|
||||
var/response = input(usr,"What were you just doing?","Query server hang report") as null|text
|
||||
if(response)
|
||||
log_sql("[usr.key] | [response]")
|
||||
else if(answer == "no")
|
||||
log_sql("[usr.key] | Reported no server hang. Please investigate")
|
||||
|
||||
|
||||
/client/proc/create_eventmob_for(var/mob/living/carbon/human/H, var/killthem = 0)
|
||||
|
||||
@@ -5,31 +5,36 @@
|
||||
var/new_ckey = ckey(clean_input("Who would you like to add to the watchlist?","Enter a ckey",null))
|
||||
if(!new_ckey)
|
||||
return
|
||||
new_ckey = sanitizeSQL(new_ckey)
|
||||
var/DBQuery/query_watchfind = GLOB.dbcon.NewQuery("SELECT ckey FROM [format_table_name("player")] WHERE ckey = '[new_ckey]'")
|
||||
if(!query_watchfind.Execute())
|
||||
var/err = query_watchfind.ErrorMsg()
|
||||
log_game("SQL ERROR obtaining ckey from player table. Error : \[[err]\]\n")
|
||||
var/datum/db_query/query_watchfind = SSdbcore.NewQuery("SELECT ckey FROM [format_table_name("player")] WHERE ckey=:new_ckey", list(
|
||||
"new_ckey" = new_ckey
|
||||
))
|
||||
if(!query_watchfind.warn_execute())
|
||||
qdel(query_watchfind)
|
||||
return
|
||||
if(!query_watchfind.NextRow())
|
||||
to_chat(usr, "<span class='redtext'>[new_ckey] has not been seen before, you can only add known players.</span>")
|
||||
qdel(query_watchfind)
|
||||
return
|
||||
else
|
||||
target_ckey = new_ckey
|
||||
var/target_sql_ckey = sanitizeSQL(target_ckey)
|
||||
if(check_watchlist(target_sql_ckey))
|
||||
to_chat(usr, "<span class='redtext'>[target_sql_ckey] is already on the watchlist.</span>")
|
||||
if(check_watchlist(target_ckey))
|
||||
to_chat(usr, "<span class='redtext'>[target_ckey] is already on the watchlist.</span>")
|
||||
return
|
||||
var/reason = input(usr,"Please state the reason","Reason") as message|null
|
||||
if(!reason)
|
||||
return
|
||||
reason = sanitizeSQL(reason)
|
||||
var/timestamp = SQLtime()
|
||||
var/adminckey = usr.ckey
|
||||
if(!adminckey)
|
||||
return
|
||||
var/admin_sql_ckey = sanitizeSQL(adminckey)
|
||||
var/DBQuery/query_watchadd = GLOB.dbcon.NewQuery("INSERT INTO [format_table_name("watch")] (ckey, reason, adminckey, timestamp) VALUES ('[target_sql_ckey]', '[reason]', '[admin_sql_ckey]', '[timestamp]')")
|
||||
var/datum/db_query/query_watchadd = SSdbcore.NewQuery({"
|
||||
INSERT INTO [format_table_name("watch")] (ckey, reason, adminckey, timestamp)
|
||||
VALUES (:targetkey, :reason, :adminkey, NOW())"},
|
||||
list(
|
||||
"targetkey" = target_ckey,
|
||||
"reason" = reason,
|
||||
"adminkey" = adminckey
|
||||
)
|
||||
)
|
||||
if(!query_watchadd.Execute())
|
||||
var/err = query_watchadd.ErrorMsg()
|
||||
log_game("SQL ERROR during adding new watch entry. Error : \[[err]\]\n")
|
||||
@@ -37,17 +42,18 @@
|
||||
log_admin("[key_name(usr)] has added [target_ckey] to the watchlist - Reason: [reason]")
|
||||
message_admins("[key_name_admin(usr)] has added [target_ckey] to the watchlist - Reason: [reason]", 1)
|
||||
if(browse)
|
||||
watchlist_show(target_sql_ckey)
|
||||
watchlist_show(target_ckey)
|
||||
|
||||
/client/proc/watchlist_remove(target_ckey, browse = 0)
|
||||
if(!check_rights(R_ADMIN))
|
||||
return
|
||||
var/target_sql_ckey = sanitizeSQL(target_ckey)
|
||||
var/DBQuery/query_watchdel = GLOB.dbcon.NewQuery("DELETE FROM [format_table_name("watch")] WHERE ckey = '[target_sql_ckey]'")
|
||||
if(!query_watchdel.Execute())
|
||||
var/err = query_watchdel.ErrorMsg()
|
||||
log_game("SQL ERROR during removing watch entry. Error : \[[err]\]\n")
|
||||
var/datum/db_query/query_watchdel = SSdbcore.NewQuery("DELETE FROM [format_table_name("watch")] WHERE ckey=:target_ckey", list(
|
||||
"target_ckey" = target_ckey
|
||||
))
|
||||
if(!query_watchdel.warn_execute())
|
||||
qdel(query_watchdel)
|
||||
return
|
||||
qdel(query_watchdel)
|
||||
log_admin("[key_name(usr)] has removed [target_ckey] from the watchlist")
|
||||
message_admins("[key_name_admin(usr)] has removed [target_ckey] from the watchlist", 1)
|
||||
if(browse)
|
||||
@@ -56,30 +62,36 @@
|
||||
/client/proc/watchlist_edit(target_ckey, browse = 0)
|
||||
if(!check_rights(R_ADMIN))
|
||||
return
|
||||
var/target_sql_ckey = sanitizeSQL(target_ckey)
|
||||
var/DBQuery/query_watchreason = GLOB.dbcon.NewQuery("SELECT reason FROM [format_table_name("watch")] WHERE ckey = '[target_sql_ckey]'")
|
||||
if(!query_watchreason.Execute())
|
||||
var/err = query_watchreason.ErrorMsg()
|
||||
log_game("SQL ERROR obtaining reason from watch table. Error : \[[err]\]\n")
|
||||
var/datum/db_query/query_watchreason = SSdbcore.NewQuery("SELECT reason FROM [format_table_name("watch")] WHERE ckey=:target_ckey", list(
|
||||
"target_ckey" = target_ckey
|
||||
))
|
||||
if(!query_watchreason.warn_execute())
|
||||
qdel(query_watchreason)
|
||||
return
|
||||
if(query_watchreason.NextRow())
|
||||
var/watch_reason = query_watchreason.item[1]
|
||||
var/new_reason = input("Input the new reason", "New Reason", "[watch_reason]") as message|null
|
||||
new_reason = sanitizeSQL(new_reason)
|
||||
if(!new_reason || new_reason == watch_reason)
|
||||
return
|
||||
var/sql_ckey = sanitizeSQL(usr.ckey)
|
||||
var/sql_ckey = usr.ckey
|
||||
var/edit_text = "Edited by [sql_ckey] on [SQLtime()] from \"[watch_reason]\" to \"[new_reason]\""
|
||||
edit_text = sanitizeSQL(edit_text)
|
||||
var/DBQuery/query_watchupdate = GLOB.dbcon.NewQuery("UPDATE [format_table_name("watch")] SET reason = '[new_reason]', last_editor = '[sql_ckey]', edits = CONCAT(IFNULL(edits,''),'[edit_text]') WHERE ckey = '[target_sql_ckey]'")
|
||||
if(!query_watchupdate.Execute())
|
||||
var/err = query_watchupdate.ErrorMsg()
|
||||
log_game("SQL ERROR editing watchlist reason. Error : \[[err]\]\n")
|
||||
|
||||
var/datum/db_query/query_watchupdate = SSdbcore.NewQuery("UPDATE [format_table_name("watch")] SET reason=:new_reason, last_editor=:sql_ckey, edits = CONCAT(IFNULL(edits,''), :edit_text) WHERE ckey=:target_ckey", list(
|
||||
"new_reason" = new_reason,
|
||||
"sql_ckey" = sql_ckey,
|
||||
"edit_text" = edit_text,
|
||||
"target_ckey" = target_ckey
|
||||
))
|
||||
if(!query_watchupdate.warn_execute())
|
||||
qdel(query_watchupdate)
|
||||
qdel(query_watchreason)
|
||||
return
|
||||
qdel(query_watchupdate)
|
||||
log_admin("[key_name(usr)] has edited [target_ckey]'s watchlist reason from \"[watch_reason]\" to \"[new_reason]\"")
|
||||
message_admins("[key_name_admin(usr)] has edited [target_ckey]'s watchlist reason from \"[watch_reason]\" to \"[new_reason]\"")
|
||||
if(browse)
|
||||
watchlist_show(target_sql_ckey)
|
||||
watchlist_show(target_ckey)
|
||||
qdel(query_watchreason)
|
||||
|
||||
/client/proc/watchlist_show(search)
|
||||
if(!check_rights(R_ADMIN))
|
||||
@@ -95,11 +107,12 @@
|
||||
search = "^[search]"
|
||||
else
|
||||
search = "^."
|
||||
search = sanitizeSQL(search)
|
||||
var/DBQuery/query_watchlist = GLOB.dbcon.NewQuery("SELECT ckey, reason, adminckey, timestamp, last_editor FROM [format_table_name("watch")] WHERE ckey REGEXP '[search]' ORDER BY ckey")
|
||||
if(!query_watchlist.Execute())
|
||||
var/err = query_watchlist.ErrorMsg()
|
||||
log_game("SQL ERROR obtaining ckey, reason, adminckey, timestamp, last_editor from watch table. Error : \[[err]\]\n")
|
||||
|
||||
var/datum/db_query/query_watchlist = SSdbcore.NewQuery("SELECT ckey, reason, adminckey, timestamp, last_editor FROM [format_table_name("watch")] WHERE ckey REGEXP :search ORDER BY ckey", list(
|
||||
"search" = search
|
||||
))
|
||||
if(!query_watchlist.warn_execute())
|
||||
qdel(query_watchlist)
|
||||
return
|
||||
while(query_watchlist.NextRow())
|
||||
var/ckey = query_watchlist.item[1]
|
||||
@@ -112,15 +125,19 @@
|
||||
output += " <font size='2'>Last edit by [last_editor] <a href='?_src_=holder;watcheditlog=[ckey]'>(Click here to see edit log)</a></font>"
|
||||
output += "<br>[reason]<hr style='background:#000000; border:0; height:1px'>"
|
||||
usr << browse(output, "window=watchwin;size=900x500")
|
||||
qdel(query_watchlist)
|
||||
|
||||
/proc/check_watchlist(target_ckey)
|
||||
var/target_sql_ckey = sanitizeSQL(target_ckey)
|
||||
var/DBQuery/query_watch = GLOB.dbcon.NewQuery("SELECT reason FROM [format_table_name("watch")] WHERE ckey = '[target_sql_ckey]'")
|
||||
if(!query_watch.Execute())
|
||||
var/err = query_watch.ErrorMsg()
|
||||
log_game("SQL ERROR obtaining reason from watch table. Error : \[[err]\]\n")
|
||||
var/datum/db_query/query_watch = SSdbcore.NewQuery("SELECT reason FROM [format_table_name("watch")] WHERE ckey=:target_ckey", list(
|
||||
"target_ckey" = target_ckey
|
||||
))
|
||||
if(!query_watch.warn_execute())
|
||||
qdel(query_watch)
|
||||
return
|
||||
if(query_watch.NextRow())
|
||||
return query_watch.item[1]
|
||||
var/entry = query_watch.item[1]
|
||||
qdel(query_watch)
|
||||
return entry
|
||||
else
|
||||
qdel(query_watch)
|
||||
return 0
|
||||
|
||||
+149
-143
@@ -188,73 +188,6 @@
|
||||
if("prefs") return prefs.process_link(usr,href_list)
|
||||
if("vars") return view_var_Topic(href,href_list,hsrc)
|
||||
|
||||
//Polls and shit
|
||||
if(href_list["showpoll"])
|
||||
handle_player_polling()
|
||||
return
|
||||
if(href_list["createpollwindow"])
|
||||
create_poll_window()
|
||||
return
|
||||
if(href_list["createpoll"])
|
||||
create_poll_function(href_list)
|
||||
return
|
||||
if(href_list["pollid"])
|
||||
var/pollid = href_list["pollid"]
|
||||
if(istext(pollid))
|
||||
pollid = text2num(pollid)
|
||||
if(isnum(pollid))
|
||||
poll_player(pollid)
|
||||
return
|
||||
if(href_list["pollresults"])
|
||||
var/pollid = href_list["pollresults"]
|
||||
if(istext(pollid))
|
||||
pollid = text2num(pollid)
|
||||
if(isnum(pollid))
|
||||
poll_results(pollid)
|
||||
if(href_list["votepollid"] && href_list["votetype"])
|
||||
if(!can_vote())
|
||||
return // No voting.
|
||||
var/pollid = text2num(href_list["votepollid"])
|
||||
var/votetype = href_list["votetype"]
|
||||
switch(votetype)
|
||||
if("OPTION")
|
||||
var/optionid = text2num(href_list["voteoptionid"])
|
||||
vote_on_poll(pollid, optionid)
|
||||
if("TEXT")
|
||||
var/replytext = href_list["replytext"]
|
||||
log_text_poll_reply(pollid, replytext)
|
||||
if("NUMVAL")
|
||||
var/id_min = text2num(href_list["minid"])
|
||||
var/id_max = text2num(href_list["maxid"])
|
||||
|
||||
if( (id_max - id_min) > 100 ) //Basic exploit prevention
|
||||
to_chat(usr, "The option ID difference is too big. Please contact administration or the database admin.")
|
||||
return
|
||||
|
||||
for(var/optionid = id_min; optionid <= id_max; optionid++)
|
||||
if(!isnull(href_list["o[optionid]"])) //Test if this optionid was replied to
|
||||
var/rating
|
||||
if(href_list["o[optionid]"] == "abstain")
|
||||
rating = null
|
||||
else
|
||||
rating = text2num(href_list["o[optionid]"])
|
||||
if(!isnum(rating))
|
||||
return
|
||||
|
||||
vote_on_numval_poll(pollid, optionid, rating)
|
||||
if("MULTICHOICE")
|
||||
var/id_min = text2num(href_list["minoptionid"])
|
||||
var/id_max = text2num(href_list["maxoptionid"])
|
||||
|
||||
if( (id_max - id_min) > 100 ) //Basic exploit prevention
|
||||
to_chat(usr, "The option ID difference is too big. Please contact administration or the database admin.")
|
||||
return
|
||||
|
||||
for(var/optionid = id_min; optionid <= id_max; optionid++)
|
||||
if(!isnull(href_list["option_[optionid]"])) //Test if this optionid was selected
|
||||
vote_on_poll(pollid, optionid, 1)
|
||||
src << browse(null, "window=playerpoll")
|
||||
handle_player_polling()
|
||||
if(href_list["ssdwarning"])
|
||||
ssd_warning_acknowledged = TRUE
|
||||
to_chat(src, "<span class='notice'>SSD warning acknowledged.</span>")
|
||||
@@ -337,8 +270,6 @@
|
||||
|
||||
to_chat(src, "<span class='warning'>If the title screen is black, resources are still downloading. Please be patient until the title screen appears.</span>")
|
||||
|
||||
|
||||
GLOB.clients += src
|
||||
GLOB.directory[ckey] = src
|
||||
//Admin Authorisation
|
||||
// Automatically makes localhost connection an admin
|
||||
@@ -362,6 +293,12 @@
|
||||
if(world.byond_version >= 511 && byond_version >= 511 && prefs.clientfps)
|
||||
fps = prefs.clientfps
|
||||
|
||||
// This has to go here to avoid issues
|
||||
// If you sleep past this point, you will get SSinput errors as well as goonchat errors
|
||||
// DO NOT STUFF RANDOM SQL QUERIES BELOW THIS POINT WITHOUT USING `INVOKE_ASYNC()` OR SIMILAR
|
||||
// YOU WILL BREAK STUFF. SERIOUSLY. -aa07
|
||||
GLOB.clients += src
|
||||
|
||||
spawn() // Goonchat does some non-instant checks in start()
|
||||
chatOutput.start()
|
||||
|
||||
@@ -372,7 +309,8 @@
|
||||
if(holder)
|
||||
on_holder_add()
|
||||
add_admin_verbs()
|
||||
admin_memo_output("Show", 0, 1)
|
||||
// Must be async because any sleeps (happen in sql queries) will break connectings clients
|
||||
INVOKE_ASYNC(src, .proc/admin_memo_output, "Show", FALSE, TRUE)
|
||||
|
||||
// Forcibly enable hardware-accelerated graphics, as we need them for the lighting overlays.
|
||||
// (but turn them off first, since sometimes BYOND doesn't turn them on properly otherwise)
|
||||
@@ -382,7 +320,6 @@
|
||||
winset(src, null, "command=\".configure graphics-hwmode on\"")
|
||||
|
||||
log_client_to_db(tdata)
|
||||
|
||||
. = ..() //calls mob.Login()
|
||||
|
||||
|
||||
@@ -406,11 +343,9 @@
|
||||
|
||||
|
||||
if(prefs.toggles & PREFTOGGLE_DISABLE_KARMA) // activates if karma is disabled
|
||||
if(establish_db_connection())
|
||||
to_chat(src,"<span class='notice'>You have disabled karma gains.") // reminds those who have it disabled
|
||||
to_chat(src,"<span class='notice'>You have disabled karma gains.") // reminds those who have it disabled
|
||||
else
|
||||
if(establish_db_connection())
|
||||
to_chat(src,"<span class='notice'>You have enabled karma gains.")
|
||||
to_chat(src,"<span class='notice'>You have enabled karma gains.")
|
||||
|
||||
generate_clickcatcher()
|
||||
apply_clickcatcher()
|
||||
@@ -482,11 +417,11 @@
|
||||
|
||||
|
||||
/client/proc/donator_check()
|
||||
set waitfor = FALSE // This needs to run async because any sleep() inside /client/New() breaks stuff badly
|
||||
if(IsGuestKey(key))
|
||||
return
|
||||
|
||||
establish_db_connection()
|
||||
if(!GLOB.dbcon.IsConnected())
|
||||
if(!SSdbcore.IsConnected())
|
||||
return
|
||||
|
||||
if(check_rights(R_ADMIN, 0, mob)) // Yes, the mob is required, regardless of other examples in this file, it won't work otherwise
|
||||
@@ -495,33 +430,44 @@
|
||||
return
|
||||
|
||||
//Donator stuff.
|
||||
var/DBQuery/query_donor_select = GLOB.dbcon.NewQuery("SELECT ckey, tier, active FROM `[format_table_name("donators")]` WHERE ckey = '[ckey]'")
|
||||
query_donor_select.Execute()
|
||||
var/datum/db_query/query_donor_select = SSdbcore.NewQuery("SELECT ckey, tier, active FROM `[format_table_name("donators")]` WHERE ckey=:ckey", list(
|
||||
"ckey" = ckey
|
||||
))
|
||||
|
||||
if(!query_donor_select.warn_execute())
|
||||
qdel(query_donor_select)
|
||||
return
|
||||
|
||||
while(query_donor_select.NextRow())
|
||||
if(!text2num(query_donor_select.item[3]))
|
||||
// Inactive donator.
|
||||
donator_level = 0
|
||||
qdel(query_donor_select)
|
||||
return
|
||||
donator_level = text2num(query_donor_select.item[2])
|
||||
donor_loadout_points()
|
||||
break
|
||||
qdel(query_donor_select)
|
||||
|
||||
/client/proc/donor_loadout_points()
|
||||
if(donator_level > 0 && prefs)
|
||||
prefs.max_gear_slots = config.max_loadout_points + 5
|
||||
|
||||
/client/proc/log_client_to_db(connectiontopic)
|
||||
set waitfor = FALSE // This needs to run async because any sleep() inside /client/New() breaks stuff badly
|
||||
if(IsGuestKey(key))
|
||||
return
|
||||
|
||||
|
||||
establish_db_connection()
|
||||
if(!GLOB.dbcon.IsConnected())
|
||||
if(!SSdbcore.IsConnected())
|
||||
return
|
||||
|
||||
var/datum/db_query/query = SSdbcore.NewQuery("SELECT id, datediff(Now(),firstseen) as age FROM [format_table_name("player")] WHERE ckey=:ckey", list(
|
||||
"ckey" = ckey
|
||||
))
|
||||
if(!query.warn_execute())
|
||||
qdel(query)
|
||||
return
|
||||
|
||||
var/DBQuery/query = GLOB.dbcon.NewQuery("SELECT id, datediff(Now(),firstseen) as age FROM [format_table_name("player")] WHERE ckey = '[ckey]'")
|
||||
query.Execute()
|
||||
var/sql_id = 0
|
||||
player_age = 0 // New players won't have an entry so knowing we have a connection we set this to zero to be updated if there is a record.
|
||||
while(query.NextRow())
|
||||
@@ -529,22 +475,33 @@
|
||||
player_age = text2num(query.item[2])
|
||||
break
|
||||
|
||||
|
||||
var/DBQuery/query_ip = GLOB.dbcon.NewQuery("SELECT ckey FROM [format_table_name("player")] WHERE ip = '[address]'")
|
||||
query_ip.Execute()
|
||||
qdel(query)
|
||||
var/datum/db_query/query_ip = SSdbcore.NewQuery("SELECT ckey FROM [format_table_name("player")] WHERE ip=:address", list(
|
||||
"address" = address
|
||||
))
|
||||
if(!query_ip.warn_execute())
|
||||
qdel(query_ip)
|
||||
return
|
||||
related_accounts_ip = list()
|
||||
while(query_ip.NextRow())
|
||||
if(ckey != query_ip.item[1])
|
||||
related_accounts_ip.Add("[query_ip.item[1]]")
|
||||
|
||||
qdel(query_ip)
|
||||
|
||||
var/datum/db_query/query_cid = SSdbcore.NewQuery("SELECT ckey FROM [format_table_name("player")] WHERE computerid=:cid", list(
|
||||
"cid" = computer_id
|
||||
))
|
||||
if(!query_cid.warn_execute())
|
||||
qdel(query_cid)
|
||||
return
|
||||
|
||||
var/DBQuery/query_cid = GLOB.dbcon.NewQuery("SELECT ckey FROM [format_table_name("player")] WHERE computerid = '[computer_id]'")
|
||||
query_cid.Execute()
|
||||
related_accounts_cid = list()
|
||||
while(query_cid.NextRow())
|
||||
if(ckey != query_cid.item[1])
|
||||
related_accounts_cid.Add("[query_cid.item[1]]")
|
||||
|
||||
qdel(query_cid)
|
||||
|
||||
var/admin_rank = "Player"
|
||||
if(holder)
|
||||
@@ -573,18 +530,19 @@
|
||||
if(!isnum(sql_id))
|
||||
return
|
||||
|
||||
var/sql_ip = sanitizeSQL(address)
|
||||
var/sql_computerid = sanitizeSQL(computer_id)
|
||||
var/sql_admin_rank = sanitizeSQL(admin_rank)
|
||||
|
||||
|
||||
if(sql_id)
|
||||
//Player already identified previously, we need to just update the 'lastseen', 'ip' and 'computer_id' variables
|
||||
var/DBQuery/query_update = GLOB.dbcon.NewQuery("UPDATE [format_table_name("player")] SET lastseen = Now(), ip = '[sql_ip]', computerid = '[sql_computerid]', lastadminrank = '[sql_admin_rank]' WHERE id = [sql_id]")
|
||||
if(!query_update.Execute())
|
||||
var/err = query_update.ErrorMsg()
|
||||
log_game("SQL ERROR during log_client_to_db (update). Error : \[[err]\]\n")
|
||||
message_admins("SQL ERROR during log_client_to_db (update). Error : \[[err]\]\n")
|
||||
var/datum/db_query/query_update = SSdbcore.NewQuery("UPDATE [format_table_name("player")] SET lastseen = Now(), ip=:sql_ip, computerid=:sql_cid, lastadminrank=:sql_ar WHERE id=:sql_id", list(
|
||||
"sql_ip" = address,
|
||||
"sql_cid" = computer_id,
|
||||
"sql_ar" = admin_rank,
|
||||
"sql_id" = sql_id
|
||||
))
|
||||
|
||||
if(!query_update.warn_execute())
|
||||
qdel(query_update)
|
||||
return
|
||||
qdel(query_update)
|
||||
// After the regular update
|
||||
INVOKE_ASYNC(src, /client/.proc/get_byond_account_date, FALSE) // Async to avoid other procs in the client chain being delayed by a web request
|
||||
else
|
||||
@@ -597,18 +555,30 @@
|
||||
qdel(src)
|
||||
return // Dont insert or they can just go in again
|
||||
|
||||
var/DBQuery/query_insert = GLOB.dbcon.NewQuery("INSERT INTO [format_table_name("player")] (id, ckey, firstseen, lastseen, ip, computerid, lastadminrank) VALUES (null, '[ckey]', Now(), Now(), '[sql_ip]', '[sql_computerid]', '[sql_admin_rank]')")
|
||||
if(!query_insert.Execute())
|
||||
var/err = query_insert.ErrorMsg()
|
||||
log_game("SQL ERROR during log_client_to_db (insert). Error : \[[err]\]\n")
|
||||
message_admins("SQL ERROR during log_client_to_db (insert). Error : \[[err]\]\n")
|
||||
var/datum/db_query/query_insert = SSdbcore.NewQuery("INSERT INTO [format_table_name("player")] (id, ckey, firstseen, lastseen, ip, computerid, lastadminrank) VALUES (null, :ckey, Now(), Now(), :ip, :cid, :rank)", list(
|
||||
"ckey" = ckey,
|
||||
"ip" = address,
|
||||
"cid" = computer_id,
|
||||
"rank" = admin_rank
|
||||
))
|
||||
if(!query_insert.warn_execute())
|
||||
qdel(query_insert)
|
||||
return
|
||||
qdel(query_insert)
|
||||
// This is their first connection instance, so TRUE here to nofiy admins
|
||||
// This needs to happen here to ensure they actually have a row to update
|
||||
INVOKE_ASYNC(src, /client/.proc/get_byond_account_date, TRUE) // Async to avoid other procs in the client chain being delayed by a web request
|
||||
|
||||
// Log player connections to DB
|
||||
var/DBQuery/query_accesslog = GLOB.dbcon.NewQuery("INSERT INTO `[format_table_name("connection_log")]`(`datetime`,`ckey`,`ip`,`computerid`) VALUES(Now(),'[ckey]','[sql_ip]','[sql_computerid]');")
|
||||
query_accesslog.Execute()
|
||||
var/datum/db_query/query_accesslog = SSdbcore.NewQuery("INSERT INTO `[format_table_name("connection_log")]`(`datetime`,`ckey`,`ip`,`computerid`) VALUES(Now(), :ckey, :ip, :cid)", list(
|
||||
"ckey" = ckey,
|
||||
"ip" = address,
|
||||
"cid" = computer_id
|
||||
))
|
||||
// We do nothing with output here, or anything else after, so we dont need to if() wrap it
|
||||
// If you ever extend this proc below this point, please wrap these with an if() in the same way its done above
|
||||
query_accesslog.warn_execute()
|
||||
qdel(query_accesslog)
|
||||
|
||||
/client/proc/check_ip_intel()
|
||||
set waitfor = 0 //we sleep when getting the intel, no need to hold up the client connection while we sleep
|
||||
@@ -655,16 +625,29 @@
|
||||
to_chat(src, "<B>You have no verified forum account. <a href='?src=[UID()];link_forum_account=true'>VERIFY FORUM ACCOUNT</a></B>")
|
||||
|
||||
/client/proc/create_oauth_token()
|
||||
var/DBQuery/query_find_token = GLOB.dbcon.NewQuery("SELECT token FROM [format_table_name("oauth_tokens")] WHERE ckey = '[ckey]' limit 1")
|
||||
if(!query_find_token.Execute())
|
||||
log_debug("create_oauth_token: failed db read")
|
||||
var/datum/db_query/query_find_token = SSdbcore.NewQuery("SELECT token FROM [format_table_name("oauth_tokens")] WHERE ckey=:ckey limit 1", list(
|
||||
"ckey" = ckey
|
||||
))
|
||||
// These queries have log_error=FALSE to avoid auth tokens being in plaintext logs
|
||||
if(!query_find_token.warn_execute(log_error=FALSE))
|
||||
qdel(query_find_token)
|
||||
return
|
||||
if(query_find_token.NextRow())
|
||||
qdel(query_find_token)
|
||||
return query_find_token.item[1]
|
||||
qdel(query_find_token)
|
||||
|
||||
var/tokenstr = md5("[rand(0,9999)][world.time][rand(0,9999)][ckey][rand(0,9999)][address][rand(0,9999)][computer_id][rand(0,9999)]")
|
||||
var/DBQuery/query_insert_token = GLOB.dbcon.NewQuery("INSERT INTO [format_table_name("oauth_tokens")] (ckey, token) VALUES('[ckey]','[tokenstr]')")
|
||||
if(!query_insert_token.Execute())
|
||||
|
||||
var/datum/db_query/query_insert_token = SSdbcore.NewQuery("INSERT INTO [format_table_name("oauth_tokens")] (ckey, token) VALUES(:ckey, :tokenstr)", list(
|
||||
"ckey" = ckey,
|
||||
"tokenstr" = tokenstr,
|
||||
))
|
||||
// These queries have log_error=FALSE to avoid auth tokens being in plaintext logs
|
||||
if(!query_insert_token.warn_execute(log_error=FALSE))
|
||||
qdel(query_insert_token)
|
||||
return
|
||||
qdel(query_insert_token)
|
||||
return tokenstr
|
||||
|
||||
/client/proc/link_forum_account(fromban)
|
||||
@@ -677,15 +660,19 @@
|
||||
if(!fromban)
|
||||
to_chat(src, "Your forum account is already set.")
|
||||
return
|
||||
var/DBQuery/query_find_link = GLOB.dbcon.NewQuery("SELECT fuid FROM [format_table_name("player")] WHERE ckey = '[ckey]' limit 1")
|
||||
if(!query_find_link.Execute())
|
||||
log_debug("link_forum_account: failed db read")
|
||||
var/datum/db_query/query_find_link = SSdbcore.NewQuery("SELECT fuid FROM [format_table_name("player")] WHERE ckey=:ckey LIMIT 1", list(
|
||||
"ckey" = ckey
|
||||
))
|
||||
if(!query_find_link.warn_execute())
|
||||
qdel(query_find_link)
|
||||
return
|
||||
if(query_find_link.NextRow())
|
||||
if(query_find_link.item[1])
|
||||
if(!fromban)
|
||||
to_chat(src, "Your forum account is already set. (" + query_find_link.item[1] + ")")
|
||||
qdel(query_find_link)
|
||||
return
|
||||
qdel(query_find_link)
|
||||
var/tokenid = create_oauth_token()
|
||||
if(!tokenid)
|
||||
to_chat(src, "link_forum_account: unable to create token")
|
||||
@@ -705,6 +692,7 @@
|
||||
|
||||
// Returns true if a randomizer is being used
|
||||
/client/proc/check_randomizer(topic)
|
||||
set waitfor = FALSE // Yes I know this is already called from an async proc but someone may change that without thinking properly
|
||||
. = FALSE
|
||||
if(connection != "seeker") //Invalid connection type.
|
||||
return null
|
||||
@@ -721,12 +709,17 @@
|
||||
var/oldcid = cidcheck[ckey]
|
||||
|
||||
if(!oldcid)
|
||||
var/DBQuery/query_cidcheck = GLOB.dbcon.NewQuery("SELECT computerid FROM [format_table_name("player")] WHERE ckey = '[ckey]'")
|
||||
query_cidcheck.Execute()
|
||||
var/datum/db_query/query_cidcheck = SSdbcore.NewQuery("SELECT computerid FROM [format_table_name("player")] WHERE ckey=:ckey", list(
|
||||
"ckey" = ckey
|
||||
))
|
||||
if(!query_cidcheck.warn_execute())
|
||||
qdel(query_cidcheck)
|
||||
return
|
||||
|
||||
var/lastcid = computer_id
|
||||
if(query_cidcheck.NextRow())
|
||||
lastcid = query_cidcheck.item[1]
|
||||
qdel(query_cidcheck)
|
||||
|
||||
if(computer_id != lastcid)
|
||||
// Their current CID does not match what the DB says - OFF WITH THEIR HEAD
|
||||
@@ -786,23 +779,30 @@
|
||||
var/const/adminckey = "CID-Error"
|
||||
|
||||
// Check for notes in the last day - only 1 note per 24 hours
|
||||
var/DBQuery/query_get_notes = GLOB.dbcon.NewQuery("SELECT id from [format_table_name("notes")] WHERE ckey = '[ckey]' AND adminckey = '[adminckey]' AND timestamp + INTERVAL 1 DAY < NOW()")
|
||||
if(!query_get_notes.Execute())
|
||||
var/err = query_get_notes.ErrorMsg()
|
||||
log_game("SQL ERROR obtaining id from notes table. Error : \[[err]\]\n")
|
||||
var/datum/db_query/query_get_notes = SSdbcore.NewQuery("SELECT id from [format_table_name("notes")] WHERE ckey=:ckey AND adminckey=:adminckey AND timestamp + INTERVAL 1 DAY < NOW()", list(
|
||||
"ckey" = ckey,
|
||||
"adminckey" = adminckey
|
||||
))
|
||||
if(!query_get_notes.warn_execute())
|
||||
qdel(query_get_notes)
|
||||
return
|
||||
if(query_get_notes.NextRow())
|
||||
qdel(query_get_notes)
|
||||
return
|
||||
qdel(query_get_notes)
|
||||
|
||||
// Only add a note if their most recent note isn't from the randomizer blocker, either
|
||||
query_get_notes = GLOB.dbcon.NewQuery("SELECT adminckey FROM [format_table_name("notes")] WHERE ckey = '[ckey]' ORDER BY timestamp DESC LIMIT 1")
|
||||
if(!query_get_notes.Execute())
|
||||
var/err = query_get_notes.ErrorMsg()
|
||||
log_game("SQL ERROR obtaining adminckey from notes table. Error : \[[err]\]\n")
|
||||
var/datum/db_query/query_get_note = SSdbcore.NewQuery("SELECT adminckey FROM [format_table_name("notes")] WHERE ckey=:ckey ORDER BY timestamp DESC LIMIT 1", list(
|
||||
"ckey" = ckey
|
||||
))
|
||||
if(!query_get_note.warn_execute())
|
||||
qdel(query_get_note)
|
||||
return
|
||||
if(query_get_notes.NextRow())
|
||||
if(query_get_notes.item[1] == adminckey)
|
||||
if(query_get_note.NextRow())
|
||||
if(query_get_note.item[1] == adminckey)
|
||||
qdel(query_get_note)
|
||||
return
|
||||
qdel(query_get_note)
|
||||
add_note(ckey, "Detected as using a cid randomizer.", null, adminckey, logged = 0)
|
||||
|
||||
/client/proc/cid_check_reconnect()
|
||||
@@ -1043,17 +1043,19 @@
|
||||
|
||||
/client/proc/get_byond_account_date(notify = FALSE)
|
||||
// First we see if the client has a saved date in the DB
|
||||
var/sql_ckey = sanitizeSQL(ckey)
|
||||
var/DBQuery/query_date = GLOB.dbcon.NewQuery("SELECT byond_date, DATEDIFF(Now(), byond_date) FROM [format_table_name("player")] WHERE ckey = '[sql_ckey]'")
|
||||
if(!query_date.Execute())
|
||||
var/err = query_date.ErrorMsg()
|
||||
log_game("SQL ERROR during get_byond_account_date (Line 1047). Error: \[[err]\]\n")
|
||||
message_admins("SQL ERROR during get_byond_account_date (Line 1047). Error: \[[err]\]\n")
|
||||
var/datum/db_query/query_date = SSdbcore.NewQuery("SELECT byond_date, DATEDIFF(Now(), byond_date) FROM [format_table_name("player")] WHERE ckey=:ckey", list(
|
||||
"ckey" = ckey
|
||||
))
|
||||
if(!query_date.warn_execute())
|
||||
qdel(query_date)
|
||||
return
|
||||
|
||||
while(query_date.NextRow())
|
||||
byondacc_date = query_date.item[1]
|
||||
byondacc_age = max(text2num(query_date.item[2]), 0) // Ensure account isnt negative days old
|
||||
|
||||
qdel(query_date)
|
||||
|
||||
// They have a date, lets bail
|
||||
if(byondacc_date)
|
||||
return
|
||||
@@ -1067,22 +1069,26 @@
|
||||
byondacc_date = byond_data["general"]["joined"]
|
||||
|
||||
// Now save it
|
||||
var/sql_date = sanitizeSQL(byondacc_date) // Yes, this is top level paranoia
|
||||
var/DBQuery/query_update = GLOB.dbcon.NewQuery("UPDATE [format_table_name("player")] SET byond_date = '[sql_date]' WHERE ckey = '[sql_ckey]'")
|
||||
if(!query_update.Execute())
|
||||
var/err = query_update.ErrorMsg()
|
||||
log_game("SQL ERROR during get_byond_account_date (Line 1071). Error: \[[err]\]\n")
|
||||
message_admins("SQL ERROR during get_byond_account_date (Line 1071). Error: \[[err]\]\n")
|
||||
var/datum/db_query/query_update = SSdbcore.NewQuery("UPDATE [format_table_name("player")] SET byond_date=:date WHERE ckey=:ckey", list(
|
||||
"date" = byondacc_date,
|
||||
"ckey" = ckey
|
||||
))
|
||||
if(!query_update.warn_execute())
|
||||
qdel(query_update)
|
||||
return
|
||||
qdel(query_update)
|
||||
|
||||
// Now retrieve the age again because BYOND doesnt have native methods for this
|
||||
var/DBQuery/query_age = GLOB.dbcon.NewQuery("SELECT DATEDIFF(Now(), byond_date) FROM [format_table_name("player")] WHERE ckey = '[sql_ckey]'")
|
||||
if(!query_age.Execute())
|
||||
var/err = query_age.ErrorMsg()
|
||||
log_game("SQL ERROR during get_byond_account_date (Line 1078). Error: \[[err]\]\n")
|
||||
message_admins("SQL ERROR during get_byond_account_date (Line 1078). Error: \[[err]\]\n")
|
||||
var/datum/db_query/query_age = SSdbcore.NewQuery("SELECT DATEDIFF(Now(), byond_date) FROM [format_table_name("player")] WHERE ckey=:ckey", list(
|
||||
"ckey" = ckey
|
||||
))
|
||||
if(!query_age.warn_execute())
|
||||
qdel(query_age)
|
||||
return
|
||||
|
||||
while(query_age.NextRow())
|
||||
byondacc_age = max(text2num(query_age.item[1]), 0) // Ensure account isnt negative days old
|
||||
qdel(query_age)
|
||||
|
||||
// Notify admins on new clients connecting, if the byond account age is less than a config value
|
||||
if(notify && (byondacc_age < config.byond_account_age_threshold))
|
||||
|
||||
@@ -2306,16 +2306,18 @@ GLOBAL_LIST_INIT(special_role_times, list( //minimum age (in days) for accounts
|
||||
|
||||
/datum/preferences/proc/open_load_dialog(mob/user)
|
||||
|
||||
var/DBQuery/query = GLOB.dbcon.NewQuery("SELECT slot,real_name FROM [format_table_name("characters")] WHERE ckey='[user.ckey]' ORDER BY slot")
|
||||
var/datum/db_query/query = SSdbcore.NewQuery("SELECT slot, real_name FROM [format_table_name("characters")] WHERE ckey=:ckey ORDER BY slot", list(
|
||||
"ckey" = user.ckey
|
||||
))
|
||||
var/list/slotnames[max_save_slots]
|
||||
|
||||
if(!query.Execute())
|
||||
var/err = query.ErrorMsg()
|
||||
log_game("SQL ERROR during character slot loading. Error : \[[err]\]\n")
|
||||
message_admins("SQL ERROR during character slot loading. Error : \[[err]\]\n")
|
||||
if(!query.warn_execute())
|
||||
qdel(query)
|
||||
return
|
||||
|
||||
while(query.NextRow())
|
||||
slotnames[text2num(query.item[1])] = query.item[2]
|
||||
qdel(query)
|
||||
|
||||
var/dat = "<body>"
|
||||
dat += "<tt><center>"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/datum/preferences/proc/load_preferences(client/C)
|
||||
|
||||
var/DBQuery/query = GLOB.dbcon.NewQuery({"SELECT
|
||||
var/datum/db_query/query = SSdbcore.NewQuery({"SELECT
|
||||
ooccolor,
|
||||
UI_style,
|
||||
UI_style_color,
|
||||
@@ -18,13 +18,12 @@
|
||||
fuid,
|
||||
parallax
|
||||
FROM [format_table_name("player")]
|
||||
WHERE ckey='[C.ckey]'"}
|
||||
)
|
||||
WHERE ckey=:ckey"}, list(
|
||||
"ckey" = C.ckey
|
||||
))
|
||||
|
||||
if(!query.Execute())
|
||||
var/err = query.ErrorMsg()
|
||||
log_game("SQL ERROR during loading player preferences. Error : \[[err]\]\n")
|
||||
message_admins("SQL ERROR during loading player preferences. Error : \[[err]\]\n")
|
||||
if(!query.warn_execute())
|
||||
qdel(query)
|
||||
return
|
||||
|
||||
|
||||
@@ -47,6 +46,8 @@
|
||||
fuid = text2num(query.item[15])
|
||||
parallax = text2num(query.item[16])
|
||||
|
||||
qdel(query)
|
||||
|
||||
//Sanitize
|
||||
ooccolor = sanitize_hexcolor(ooccolor, initial(ooccolor))
|
||||
UI_style = sanitize_inlist(UI_style, list("White", "Midnight"), initial(UI_style))
|
||||
@@ -73,30 +74,48 @@
|
||||
log_runtime(EXCEPTION("[C.key] had a malformed role entry: '[role]'. Removing!"), src)
|
||||
be_special -= role
|
||||
|
||||
var/DBQuery/query = GLOB.dbcon.NewQuery({"UPDATE [format_table_name("player")]
|
||||
var/datum/db_query/query = SSdbcore.NewQuery({"UPDATE [format_table_name("player")]
|
||||
SET
|
||||
ooccolor='[ooccolor]',
|
||||
UI_style='[UI_style]',
|
||||
UI_style_color='[UI_style_color]',
|
||||
UI_style_alpha='[UI_style_alpha]',
|
||||
be_role='[sanitizeSQL(list2params(be_special))]',
|
||||
default_slot='[default_slot]',
|
||||
toggles='[num2text(toggles, CEILING(log(10, (TOGGLES_TOTAL)), 1))]',
|
||||
toggles_2='[num2text(toggles2, CEILING(log(10, (TOGGLES_2_TOTAL)), 1))]',
|
||||
atklog='[atklog]',
|
||||
sound='[sound]',
|
||||
volume='[volume]',
|
||||
lastchangelog='[lastchangelog]',
|
||||
clientfps='[clientfps]',
|
||||
parallax='[parallax]'
|
||||
WHERE ckey='[C.ckey]'"}
|
||||
ooccolor=:ooccolour,
|
||||
UI_style=:ui_style,
|
||||
UI_style_color=:ui_colour,
|
||||
UI_style_alpha=:ui_alpha,
|
||||
be_role=:berole,
|
||||
default_slot=:defaultslot,
|
||||
toggles=:toggles,
|
||||
toggles_2=:toggles2,
|
||||
atklog=:atklog,
|
||||
sound=:sound,
|
||||
volume=:volume,
|
||||
lastchangelog=:lastchangelog,
|
||||
clientfps=:clientfps,
|
||||
parallax=:parallax
|
||||
WHERE ckey=:ckey"}, list(
|
||||
// OH GOD THE PARAMETERS
|
||||
"ooccolour" = ooccolor,
|
||||
"ui_style" = UI_style,
|
||||
"ui_colour" = UI_style_color,
|
||||
"ui_alpha" = UI_style_alpha,
|
||||
"berole" = list2params(be_special),
|
||||
"defaultslot" = default_slot,
|
||||
// Even though its a number in the DB, you have to use num2text here, otherwise byond adds scientific notation to the number
|
||||
"toggles" = num2text(toggles, CEILING(log(10, (TOGGLES_TOTAL)), 1)),
|
||||
"toggles2" = num2text(toggles2, CEILING(log(10, (TOGGLES_2_TOTAL)), 1)),
|
||||
"atklog" = atklog,
|
||||
"sound" = sound,
|
||||
"volume" = volume,
|
||||
"lastchangelog" = lastchangelog,
|
||||
"clientfps" = clientfps,
|
||||
"parallax" = parallax,
|
||||
"ckey" = C.ckey
|
||||
)
|
||||
)
|
||||
|
||||
if(!query.Execute())
|
||||
var/err = query.ErrorMsg()
|
||||
log_game("SQL ERROR during saving player preferences. Error : \[[err]\]\n")
|
||||
message_admins("SQL ERROR during saving player preferences. Error : \[[err]\]\n")
|
||||
if(!query.warn_execute())
|
||||
qdel(query)
|
||||
return
|
||||
|
||||
qdel(query)
|
||||
return 1
|
||||
|
||||
/datum/preferences/proc/load_character(client/C,slot)
|
||||
@@ -106,11 +125,17 @@
|
||||
slot = sanitize_integer(slot, 1, max_save_slots, initial(default_slot))
|
||||
if(slot != default_slot)
|
||||
default_slot = slot
|
||||
var/DBQuery/firstquery = GLOB.dbcon.NewQuery("UPDATE [format_table_name("player")] SET default_slot=[slot] WHERE ckey='[C.ckey]'")
|
||||
firstquery.Execute()
|
||||
var/datum/db_query/firstquery = SSdbcore.NewQuery("UPDATE [format_table_name("player")] SET default_slot=:slot WHERE ckey=:ckey", list(
|
||||
"slot" = slot,
|
||||
"ckey" = C.ckey
|
||||
))
|
||||
if(!firstquery.warn_execute())
|
||||
qdel(firstquery)
|
||||
return
|
||||
qdel(firstquery)
|
||||
|
||||
// Let's not have this explode if you sneeze on the DB
|
||||
var/DBQuery/query = GLOB.dbcon.NewQuery({"SELECT
|
||||
var/datum/db_query/query = SSdbcore.NewQuery({"SELECT
|
||||
OOC_Notes,
|
||||
real_name,
|
||||
name_is_always_random,
|
||||
@@ -163,11 +188,12 @@
|
||||
body_accessory,
|
||||
gear,
|
||||
autohiss
|
||||
FROM [format_table_name("characters")] WHERE ckey='[C.ckey]' AND slot='[slot]'"})
|
||||
if(!query.Execute())
|
||||
var/err = query.ErrorMsg()
|
||||
log_game("SQL ERROR during character slot loading. Error : \[[err]\]\n")
|
||||
message_admins("SQL ERROR during character slot loading. Error : \[[err]\]\n")
|
||||
FROM [format_table_name("characters")] WHERE ckey=:ckey AND slot=:slot"}, list(
|
||||
"ckey" = C.ckey,
|
||||
"slot" = slot
|
||||
))
|
||||
if(!query.warn_execute())
|
||||
qdel(query)
|
||||
return
|
||||
|
||||
while(query.NextRow())
|
||||
@@ -244,6 +270,7 @@
|
||||
|
||||
saved = TRUE
|
||||
|
||||
qdel(query)
|
||||
//Sanitize
|
||||
var/datum/species/SP = GLOB.all_species[species]
|
||||
metadata = sanitize_text(metadata, initial(metadata))
|
||||
@@ -325,74 +352,139 @@
|
||||
if(!isemptylist(loadout_gear))
|
||||
gearlist = list2params(loadout_gear)
|
||||
|
||||
var/DBQuery/firstquery = GLOB.dbcon.NewQuery("SELECT slot FROM [format_table_name("characters")] WHERE ckey='[C.ckey]' ORDER BY slot")
|
||||
firstquery.Execute()
|
||||
var/datum/db_query/firstquery = SSdbcore.NewQuery("SELECT slot FROM [format_table_name("characters")] WHERE ckey=:ckey ORDER BY slot", list(
|
||||
"ckey" = C.ckey
|
||||
))
|
||||
if(!firstquery.warn_execute())
|
||||
qdel(firstquery)
|
||||
return
|
||||
while(firstquery.NextRow())
|
||||
if(text2num(firstquery.item[1]) == default_slot)
|
||||
var/DBQuery/query = GLOB.dbcon.NewQuery({"UPDATE [format_table_name("characters")] SET OOC_Notes='[sanitizeSQL(metadata)]',
|
||||
real_name='[sanitizeSQL(real_name)]',
|
||||
name_is_always_random='[be_random_name]',
|
||||
gender='[gender]',
|
||||
age='[age]',
|
||||
species='[sanitizeSQL(species)]',
|
||||
language='[sanitizeSQL(language)]',
|
||||
hair_colour='[h_colour]',
|
||||
secondary_hair_colour='[h_sec_colour]',
|
||||
facial_hair_colour='[f_colour]',
|
||||
secondary_facial_hair_colour='[f_sec_colour]',
|
||||
skin_tone='[s_tone]',
|
||||
skin_colour='[s_colour]',
|
||||
marking_colours='[sanitizeSQL(markingcolourslist)]',
|
||||
head_accessory_colour='[hacc_colour]',
|
||||
hair_style_name='[sanitizeSQL(h_style)]',
|
||||
facial_style_name='[sanitizeSQL(f_style)]',
|
||||
marking_styles='[sanitizeSQL(markingstyleslist)]',
|
||||
head_accessory_style_name='[sanitizeSQL(ha_style)]',
|
||||
alt_head_name='[sanitizeSQL(alt_head)]',
|
||||
eye_colour='[e_colour]',
|
||||
underwear='[underwear]',
|
||||
undershirt='[undershirt]',
|
||||
backbag='[backbag]',
|
||||
b_type='[b_type]',
|
||||
alternate_option='[alternate_option]',
|
||||
job_support_high='[job_support_high]',
|
||||
job_support_med='[job_support_med]',
|
||||
job_support_low='[job_support_low]',
|
||||
job_medsci_high='[job_medsci_high]',
|
||||
job_medsci_med='[job_medsci_med]',
|
||||
job_medsci_low='[job_medsci_low]',
|
||||
job_engsec_high='[job_engsec_high]',
|
||||
job_engsec_med='[job_engsec_med]',
|
||||
job_engsec_low='[job_engsec_low]',
|
||||
job_karma_high='[job_karma_high]',
|
||||
job_karma_med='[job_karma_med]',
|
||||
job_karma_low='[job_karma_low]',
|
||||
flavor_text='[sanitizeSQL(flavor_text)]',
|
||||
med_record='[sanitizeSQL(med_record)]',
|
||||
sec_record='[sanitizeSQL(sec_record)]',
|
||||
gen_record='[sanitizeSQL(gen_record)]',
|
||||
player_alt_titles='[playertitlelist]',
|
||||
disabilities='[disabilities]',
|
||||
organ_data='[organlist]',
|
||||
rlimb_data='[rlimblist]',
|
||||
nanotrasen_relation='[nanotrasen_relation]',
|
||||
speciesprefs='[speciesprefs]',
|
||||
socks='[socks]',
|
||||
body_accessory='[body_accessory]',
|
||||
gear='[gearlist]',
|
||||
autohiss='[autohiss_mode]'
|
||||
WHERE ckey='[C.ckey]'
|
||||
AND slot='[default_slot]'"}
|
||||
var/datum/db_query/query = SSdbcore.NewQuery({"UPDATE [format_table_name("characters")]
|
||||
SET
|
||||
OOC_Notes=:metadata,
|
||||
real_name=:real_name,
|
||||
name_is_always_random=:be_random_name,
|
||||
gender=:gender,
|
||||
age=:age,
|
||||
species=:species,
|
||||
language=:language,
|
||||
hair_colour=:h_colour,
|
||||
secondary_hair_colour=:h_sec_colour,
|
||||
facial_hair_colour=:f_colour,
|
||||
secondary_facial_hair_colour=:f_sec_colour,
|
||||
skin_tone=:s_tone,
|
||||
skin_colour=:s_colour,
|
||||
marking_colours=:markingcolourslist,
|
||||
head_accessory_colour=:hacc_colour,
|
||||
hair_style_name=:h_style,
|
||||
facial_style_name=:f_style,
|
||||
marking_styles=:markingstyleslist,
|
||||
head_accessory_style_name=:ha_style,
|
||||
alt_head_name=:alt_head,
|
||||
eye_colour=:e_colour,
|
||||
underwear=:underwear,
|
||||
undershirt=:undershirt,
|
||||
backbag=:backbag,
|
||||
b_type=:b_type,
|
||||
alternate_option=:alternate_option,
|
||||
job_support_high=:job_support_high,
|
||||
job_support_med=:job_support_med,
|
||||
job_support_low=:job_support_low,
|
||||
job_medsci_high=:job_medsci_high,
|
||||
job_medsci_med=:job_medsci_med,
|
||||
job_medsci_low=:job_medsci_low,
|
||||
job_engsec_high=:job_engsec_high,
|
||||
job_engsec_med=:job_engsec_med,
|
||||
job_engsec_low=:job_engsec_low,
|
||||
job_karma_high=:job_karma_high,
|
||||
job_karma_med=:job_karma_med,
|
||||
job_karma_low=:job_karma_low,
|
||||
flavor_text=:flavor_text,
|
||||
med_record=:med_record,
|
||||
sec_record=:sec_record,
|
||||
gen_record=:gen_record,
|
||||
player_alt_titles=:playertitlelist,
|
||||
disabilities=:disabilities,
|
||||
organ_data=:organlist,
|
||||
rlimb_data=:rlimblist,
|
||||
nanotrasen_relation=:nanotrasen_relation,
|
||||
speciesprefs=:speciesprefs,
|
||||
socks=:socks,
|
||||
body_accessory=:body_accessory,
|
||||
gear=:gearlist,
|
||||
autohiss=:autohiss_mode
|
||||
WHERE ckey=:ckey
|
||||
AND slot=:slot"}, list(
|
||||
// OH GOD SO MANY PARAMETERS
|
||||
"metadata" = metadata,
|
||||
"real_name" = real_name,
|
||||
"be_random_name" = be_random_name,
|
||||
"gender" = gender,
|
||||
"age" = age,
|
||||
"species" = species,
|
||||
"language" = language,
|
||||
"h_colour" = h_colour,
|
||||
"h_sec_colour" = h_sec_colour,
|
||||
"f_colour" = f_colour,
|
||||
"f_sec_colour" = f_sec_colour,
|
||||
"s_tone" = s_tone,
|
||||
"s_colour" = s_colour,
|
||||
"markingcolourslist" = markingcolourslist,
|
||||
"hacc_colour" = hacc_colour,
|
||||
"h_style" = h_style,
|
||||
"f_style" = f_style,
|
||||
"markingstyleslist" = markingstyleslist,
|
||||
"ha_style" = ha_style,
|
||||
"alt_head" = alt_head,
|
||||
"e_colour" = e_colour,
|
||||
"underwear" = underwear,
|
||||
"undershirt" = undershirt,
|
||||
"backbag" = backbag,
|
||||
"b_type" = b_type,
|
||||
"alternate_option" = alternate_option,
|
||||
"job_support_high" = job_support_high,
|
||||
"job_support_med" = job_support_med,
|
||||
"job_support_low" = job_support_low,
|
||||
"job_medsci_high" = job_medsci_high,
|
||||
"job_medsci_med" = job_medsci_med,
|
||||
"job_medsci_low" = job_medsci_low,
|
||||
"job_engsec_high" = job_engsec_high,
|
||||
"job_engsec_med" = job_engsec_med,
|
||||
"job_engsec_low" = job_engsec_low,
|
||||
"job_karma_high" = job_karma_high,
|
||||
"job_karma_med" = job_karma_med,
|
||||
"job_karma_low" = job_karma_low,
|
||||
"flavor_text" = flavor_text,
|
||||
"med_record" = med_record,
|
||||
"sec_record" = sec_record,
|
||||
"gen_record" = gen_record,
|
||||
"playertitlelist" = (playertitlelist ? playertitlelist : ""), // This it intentnional. It wont work without it!
|
||||
"disabilities" = disabilities,
|
||||
"organlist" = (organlist ? organlist : ""),
|
||||
"rlimblist" = (rlimblist ? rlimblist : ""),
|
||||
"nanotrasen_relation" = nanotrasen_relation,
|
||||
"speciesprefs" = speciesprefs,
|
||||
"socks" = socks,
|
||||
"body_accessory" = (body_accessory ? body_accessory : ""),
|
||||
"gearlist" = (gearlist ? gearlist : ""),
|
||||
"autohiss_mode" = autohiss_mode,
|
||||
"ckey" = C.ckey,
|
||||
"slot" = default_slot
|
||||
)
|
||||
)
|
||||
|
||||
if(!query.Execute())
|
||||
var/err = query.ErrorMsg()
|
||||
log_game("SQL ERROR during character slot saving. Error : \[[err]\]\n")
|
||||
message_admins("SQL ERROR during character slot saving. Error : \[[err]\]\n")
|
||||
if(!query.warn_execute())
|
||||
qdel(firstquery)
|
||||
qdel(query)
|
||||
return
|
||||
qdel(firstquery)
|
||||
qdel(query)
|
||||
return 1
|
||||
|
||||
qdel(firstquery)
|
||||
|
||||
var/DBQuery/query = GLOB.dbcon.NewQuery({"
|
||||
var/datum/db_query/query = SSdbcore.NewQuery({"
|
||||
INSERT INTO [format_table_name("characters")] (ckey, slot, OOC_Notes, real_name, name_is_always_random, gender,
|
||||
age, species, language,
|
||||
hair_colour, secondary_hair_colour,
|
||||
@@ -421,57 +513,112 @@
|
||||
socks, body_accessory, gear, autohiss)
|
||||
|
||||
VALUES
|
||||
('[C.ckey]', '[default_slot]', '[sanitizeSQL(metadata)]', '[sanitizeSQL(real_name)]', '[be_random_name]','[gender]',
|
||||
'[age]', '[sanitizeSQL(species)]', '[sanitizeSQL(language)]',
|
||||
'[h_colour]', '[h_sec_colour]',
|
||||
'[f_colour]', '[f_sec_colour]',
|
||||
'[s_tone]', '[s_colour]',
|
||||
'[sanitizeSQL(markingcolourslist)]',
|
||||
'[hacc_colour]',
|
||||
'[sanitizeSQL(h_style)]',
|
||||
'[sanitizeSQL(f_style)]',
|
||||
'[sanitizeSQL(markingstyleslist)]',
|
||||
'[sanitizeSQL(ha_style)]',
|
||||
'[sanitizeSQL(alt_head)]',
|
||||
'[e_colour]',
|
||||
'[underwear]', '[undershirt]',
|
||||
'[backbag]', '[b_type]', '[alternate_option]',
|
||||
'[job_support_high]', '[job_support_med]', '[job_support_low]',
|
||||
'[job_medsci_high]', '[job_medsci_med]', '[job_medsci_low]',
|
||||
'[job_engsec_high]', '[job_engsec_med]', '[job_engsec_low]',
|
||||
'[job_karma_high]', '[job_karma_med]', '[job_karma_low]',
|
||||
'[sanitizeSQL(flavor_text)]',
|
||||
'[sanitizeSQL(med_record)]',
|
||||
'[sanitizeSQL(sec_record)]',
|
||||
'[sanitizeSQL(gen_record)]',
|
||||
'[playertitlelist]',
|
||||
'[disabilities]', '[organlist]', '[rlimblist]', '[nanotrasen_relation]', '[speciesprefs]',
|
||||
'[socks]', '[body_accessory]', '[gearlist]', '[autohiss_mode]')
|
||||
(:ckey, :slot, :metadata, :name, :be_random_name, :gender,
|
||||
:age, :species, :language,
|
||||
:h_colour, :h_sec_colour,
|
||||
:f_colour, :f_sec_colour,
|
||||
:s_tone, :s_colour,
|
||||
:markingcolourslist,
|
||||
:hacc_colour,
|
||||
:h_style,
|
||||
:f_style,
|
||||
:markingstyleslist,
|
||||
:ha_style,
|
||||
:alt_head,
|
||||
:e_colour,
|
||||
:underwear, :undershirt,
|
||||
:backbag, :b_type, :alternate_option,
|
||||
:job_support_high, :job_support_med, :job_support_low,
|
||||
:job_medsci_high, :job_medsci_med, :job_medsci_low,
|
||||
:job_engsec_high, :job_engsec_med, :job_engsec_low,
|
||||
:job_karma_high, :job_karma_med, :job_karma_low,
|
||||
:flavor_text,
|
||||
:med_record,
|
||||
:sec_record,
|
||||
:gen_record,
|
||||
:playertitlelist,
|
||||
:disabilities, :organlist, :rlimblist, :nanotrasen_relation, :speciesprefs,
|
||||
:socks, :body_accessory, :gearlist, :autohiss_mode)
|
||||
|
||||
"}
|
||||
)
|
||||
"}, list(
|
||||
// This has too many params for anyone to look at this without going insae
|
||||
"ckey" = C.ckey,
|
||||
"slot" = default_slot,
|
||||
"metadata" = metadata,
|
||||
"name" = real_name,
|
||||
"be_random_name" = be_random_name,
|
||||
"gender" = gender,
|
||||
"age" = age,
|
||||
"species" = species,
|
||||
"language" = language,
|
||||
"h_colour" = h_colour,
|
||||
"h_sec_colour" = h_sec_colour,
|
||||
"f_colour" = f_colour,
|
||||
"f_sec_colour" = f_sec_colour,
|
||||
"s_tone" = s_tone,
|
||||
"s_colour" = s_colour,
|
||||
"markingcolourslist" = markingcolourslist,
|
||||
"hacc_colour" = hacc_colour,
|
||||
"h_style" = h_style,
|
||||
"f_style" = f_style,
|
||||
"markingstyleslist" = markingstyleslist,
|
||||
"ha_style" = ha_style,
|
||||
"alt_head" = alt_head,
|
||||
"e_colour" = e_colour,
|
||||
"underwear" = underwear,
|
||||
"undershirt" = undershirt,
|
||||
"backbag" = backbag,
|
||||
"b_type" = b_type,
|
||||
"alternate_option" = alternate_option,
|
||||
"job_support_high" = job_support_high,
|
||||
"job_support_med" = job_support_med,
|
||||
"job_support_low" = job_support_low,
|
||||
"job_medsci_high" = job_medsci_high,
|
||||
"job_medsci_med" = job_medsci_med,
|
||||
"job_medsci_low" = job_medsci_low,
|
||||
"job_engsec_high" = job_engsec_high,
|
||||
"job_engsec_med" = job_engsec_med,
|
||||
"job_engsec_low" = job_engsec_low,
|
||||
"job_karma_high" = job_karma_high,
|
||||
"job_karma_med" = job_karma_med,
|
||||
"job_karma_low" = job_karma_low,
|
||||
"flavor_text" = flavor_text,
|
||||
"med_record" = med_record,
|
||||
"sec_record" = sec_record,
|
||||
"gen_record" = gen_record,
|
||||
"playertitlelist" = (playertitlelist ? playertitlelist : ""), // This it intentnional. It wont work without it!
|
||||
"disabilities" = disabilities,
|
||||
"organlist" = (organlist ? organlist : ""),
|
||||
"rlimblist" = (rlimblist ? rlimblist : ""),
|
||||
"nanotrasen_relation" = nanotrasen_relation,
|
||||
"speciesprefs" = speciesprefs,
|
||||
"socks" = socks,
|
||||
"body_accessory" = (body_accessory ? body_accessory : ""),
|
||||
"gearlist" = (gearlist ? gearlist : ""),
|
||||
"autohiss_mode" = autohiss_mode
|
||||
))
|
||||
|
||||
if(!query.Execute())
|
||||
var/err = query.ErrorMsg()
|
||||
log_game("SQL ERROR during character slot saving. Error : \[[err]\]\n")
|
||||
message_admins("SQL ERROR during character slot saving. Error : \[[err]\]\n")
|
||||
if(!query.warn_execute())
|
||||
qdel(query)
|
||||
return
|
||||
|
||||
qdel(query)
|
||||
saved = TRUE
|
||||
return 1
|
||||
|
||||
/datum/preferences/proc/load_random_character_slot(client/C)
|
||||
var/DBQuery/query = GLOB.dbcon.NewQuery("SELECT slot FROM [format_table_name("characters")] WHERE ckey='[C.ckey]' ORDER BY slot")
|
||||
var/datum/db_query/query = SSdbcore.NewQuery("SELECT slot FROM [format_table_name("characters")] WHERE ckey=:ckey ORDER BY slot", list(
|
||||
"ckey" = C.ckey
|
||||
))
|
||||
var/list/saves = list()
|
||||
|
||||
if(!query.Execute())
|
||||
var/err = query.ErrorMsg()
|
||||
log_game("SQL ERROR during random character slot picking. Error : \[[err]\]\n")
|
||||
message_admins("SQL ERROR during random character slot picking. Error : \[[err]\]\n")
|
||||
if(!query.warn_execute())
|
||||
qdel(query)
|
||||
return
|
||||
|
||||
while(query.NextRow())
|
||||
saves += text2num(query.item[1])
|
||||
qdel(query)
|
||||
|
||||
if(!saves.len)
|
||||
load_character(C)
|
||||
@@ -482,17 +629,31 @@
|
||||
/datum/preferences/proc/clear_character_slot(client/C)
|
||||
. = FALSE
|
||||
// Is there a character in that slot?
|
||||
var/DBQuery/query = GLOB.dbcon.NewQuery("SELECT slot FROM [format_table_name("characters")] WHERE ckey='[C.ckey]' AND slot='[default_slot]'")
|
||||
query.Execute()
|
||||
if(!query.RowCount())
|
||||
var/datum/db_query/query = SSdbcore.NewQuery("SELECT slot FROM [format_table_name("characters")] WHERE ckey=:ckey AND slot=:slot", list(
|
||||
"ckey" = C.ckey,
|
||||
"slot" = default_slot
|
||||
))
|
||||
|
||||
if(!query.warn_execute())
|
||||
qdel(query)
|
||||
return
|
||||
|
||||
var/DBQuery/query2 = GLOB.dbcon.NewQuery("DELETE FROM [format_table_name("characters")] WHERE ckey='[C.ckey]' AND slot='[default_slot]'")
|
||||
if(!query2.Execute())
|
||||
var/err = query2.ErrorMsg()
|
||||
log_game("SQL ERROR during character slot clearing. Error : \[[err]\]\n")
|
||||
message_admins("SQL ERROR during character slot clearing. Error : \[[err]\]\n")
|
||||
if(!query.NextRow())
|
||||
qdel(query)
|
||||
return
|
||||
|
||||
qdel(query)
|
||||
|
||||
var/datum/db_query/delete_query = SSdbcore.NewQuery("DELETE FROM [format_table_name("characters")] WHERE ckey=:ckey AND slot=:slot", list(
|
||||
"ckey" = C.ckey,
|
||||
"slot" = default_slot
|
||||
))
|
||||
|
||||
if(!delete_query.warn_execute())
|
||||
qdel(delete_query)
|
||||
return
|
||||
|
||||
qdel(delete_query)
|
||||
|
||||
saved = FALSE
|
||||
return TRUE
|
||||
|
||||
@@ -1,10 +1,17 @@
|
||||
/proc/EquipCustomItems(mob/living/carbon/human/M)
|
||||
if(!establish_db_connection())
|
||||
if(!SSdbcore.IsConnected())
|
||||
return
|
||||
|
||||
// Grab the info we want.
|
||||
var/DBQuery/query = GLOB.dbcon.NewQuery("SELECT cuiPath, cuiPropAdjust, cuiJobMask, cuiDescription, cuiItemName FROM [format_table_name("customuseritems")] WHERE cuiCKey='[M.ckey]' AND (cuiRealName='[sanitizeSQL(M.real_name)]' OR cuiRealName='*')")
|
||||
query.Execute()
|
||||
var/datum/db_query/query = SSdbcore.NewQuery({"
|
||||
SELECT cuiPath, cuiPropAdjust, cuiJobMask, cuiDescription, cuiItemName FROM [format_table_name("customuseritems")]
|
||||
WHERE cuiCKey=:ckey AND (cuiRealName=:realname OR cuiRealName='*')"}, list(
|
||||
"ckey" = M.ckey,
|
||||
"realname" = M.real_name
|
||||
))
|
||||
if(!query.warn_execute())
|
||||
qdel(query)
|
||||
return
|
||||
|
||||
while(query.NextRow())
|
||||
var/path = text2path(query.item[1])
|
||||
@@ -12,7 +19,7 @@
|
||||
var/jobmask = query.item[3]
|
||||
var/ok = 0
|
||||
if(!path || !ispath(path))
|
||||
log_debug("Incorrect database entry found in table 'customuseritems' path value = [path], cuiPath is null. cuiCKey='[M.ckey]' AND (cuiRealName='[sanitizeSQL(M.real_name)]' OR cuiRealName='*'")
|
||||
log_debug("Incorrect database entry found in table 'customuseritems' path value = [path], cuiPath is null. cuiCKey='[M.ckey]' AND (cuiRealName='[M.real_name]' OR cuiRealName='*'")
|
||||
continue
|
||||
if(jobmask != "*")
|
||||
var/list/allowed_jobs = splittext(jobmask,",")
|
||||
@@ -66,6 +73,7 @@
|
||||
|
||||
HackProperties(Item,propadjust)
|
||||
M.regenerate_icons()
|
||||
qdel(query)
|
||||
|
||||
// This is hacky, but since it's difficult as fuck to make a proper parser in BYOND without killing the server, here it is. - N3X
|
||||
/proc/HackProperties(var/mob/living/carbon/human/M,var/obj/item/I,var/script)
|
||||
|
||||
+183
-108
@@ -3,51 +3,73 @@
|
||||
Part of karma purchase is handled in client_procs.dm */
|
||||
|
||||
/proc/sql_report_karma(var/mob/spender, var/mob/receiver)
|
||||
var/sqlspendername = sanitizeSQL(spender.name)
|
||||
var/sqlspenderkey = sanitizeSQL(spender.ckey)
|
||||
var/sqlreceivername = sanitizeSQL(receiver.name)
|
||||
var/sqlreceiverkey = sanitizeSQL(receiver.ckey)
|
||||
var/sqlreceiverrole = "None"
|
||||
var/sqlreceiverspecial = "None"
|
||||
|
||||
var/sqlspenderip = spender.client.address
|
||||
var/receiverrole = "None"
|
||||
var/receiverspecial = "None"
|
||||
|
||||
if(receiver.mind)
|
||||
if(receiver.mind.special_role)
|
||||
sqlreceiverspecial = sanitizeSQL(receiver.mind.special_role)
|
||||
receiverspecial = receiver.mind.special_role
|
||||
if(receiver.mind.assigned_role)
|
||||
sqlreceiverrole = sanitizeSQL(receiver.mind.assigned_role)
|
||||
receiverrole = receiver.mind.assigned_role
|
||||
|
||||
if(!GLOB.dbcon.IsConnected())
|
||||
log_game("SQL ERROR during karma logging. Failed to connect.")
|
||||
if(!SSdbcore.IsConnected())
|
||||
return
|
||||
|
||||
var/datum/db_query/log_query = SSdbcore.NewQuery({"
|
||||
INSERT INTO [format_table_name("karma")] (spendername, spenderkey, receivername, receiverkey, receiverrole, receiverspecial, spenderip, time)
|
||||
VALUES (:sname, :skey, :rname, :rkey, :rrole, :rspecial, :sip, Now())"}, list(
|
||||
"sname" = spender.name,
|
||||
"skey" = spender.ckey,
|
||||
"rname" = receiver.name,
|
||||
"rkey" = receiver.ckey,
|
||||
"rrole" = receiverrole,
|
||||
"rspecial" = receiverspecial,
|
||||
"sip" = spender.client.address
|
||||
))
|
||||
|
||||
if(!log_query.warn_execute())
|
||||
qdel(log_query)
|
||||
return
|
||||
|
||||
qdel(log_query)
|
||||
|
||||
var/datum/db_query/select_spender = SSdbcore.NewQuery("SELECT id, karma FROM [format_table_name("karmatotals")] WHERE byondkey=:rkey", list(
|
||||
"rkey" = receiver.ckey
|
||||
))
|
||||
|
||||
if(!select_spender.warn_execute())
|
||||
qdel(select_spender)
|
||||
return
|
||||
|
||||
var/karma
|
||||
var/id
|
||||
while(select_spender.NextRow())
|
||||
id = select_spender.item[1]
|
||||
karma = text2num(select_spender.item[2])
|
||||
|
||||
qdel(select_spender)
|
||||
|
||||
if(karma == null)
|
||||
karma = 1
|
||||
|
||||
var/datum/db_query/insert_query = SSdbcore.NewQuery("INSERT INTO [format_table_name("karmatotals")] (byondkey, karma) VALUES (:rkey, :karma)", list(
|
||||
"rkey" = receiver.ckey,
|
||||
"karma" = karma
|
||||
))
|
||||
if(!insert_query.warn_execute())
|
||||
qdel(insert_query)
|
||||
return
|
||||
qdel(insert_query)
|
||||
else
|
||||
var/sqltime = time2text(world.realtime, "YYYY-MM-DD hh:mm:ss")
|
||||
var/DBQuery/query = GLOB.dbcon.NewQuery("INSERT INTO [format_table_name("karma")] (spendername, spenderkey, receivername, receiverkey, receiverrole, receiverspecial, spenderip, time) VALUES ('[sqlspendername]', '[sqlspenderkey]', '[sqlreceivername]', '[sqlreceiverkey]', '[sqlreceiverrole]', '[sqlreceiverspecial]', '[sqlspenderip]', '[sqltime]')")
|
||||
if(!query.Execute())
|
||||
var/err = query.ErrorMsg()
|
||||
log_game("SQL ERROR during karma logging. Error : \[[err]\]\n")
|
||||
|
||||
|
||||
query = GLOB.dbcon.NewQuery("SELECT * FROM [format_table_name("karmatotals")] WHERE byondkey='[sqlreceiverkey]'")
|
||||
query.Execute()
|
||||
|
||||
var/karma
|
||||
var/id
|
||||
while(query.NextRow())
|
||||
id = query.item[1]
|
||||
karma = text2num(query.item[3])
|
||||
if(karma == null)
|
||||
karma = 1
|
||||
query = GLOB.dbcon.NewQuery("INSERT INTO [format_table_name("karmatotals")] (byondkey, karma) VALUES ('[sqlreceiverkey]', [karma])")
|
||||
if(!query.Execute())
|
||||
var/err = query.ErrorMsg()
|
||||
log_game("SQL ERROR during karmatotal logging (adding new key). Error : \[[err]\]\n")
|
||||
else
|
||||
karma++
|
||||
query = GLOB.dbcon.NewQuery("UPDATE [format_table_name("karmatotals")] SET karma=[karma] WHERE id=[id]")
|
||||
if(!query.Execute())
|
||||
var/err = query.ErrorMsg()
|
||||
log_game("SQL ERROR during karmatotal logging (updating existing entry). Error : \[[err]\]\n")
|
||||
karma++
|
||||
var/datum/db_query/update_query = SSdbcore.NewQuery("UPDATE [format_table_name("karmatotals")] SET karma=:karma WHERE id=:id", list(
|
||||
"karma" = karma,
|
||||
"id" = id
|
||||
))
|
||||
if(!update_query.warn_execute())
|
||||
qdel(update_query)
|
||||
return
|
||||
qdel(update_query)
|
||||
|
||||
GLOBAL_LIST_EMPTY(karma_spenders)
|
||||
|
||||
@@ -168,20 +190,24 @@ GLOBAL_LIST_EMPTY(karma_spenders)
|
||||
|
||||
/client/proc/verify_karma()
|
||||
var/currentkarma = 0
|
||||
var/sanitzedkey = sanitizeSQL(src.ckey)
|
||||
if(!GLOB.dbcon.IsConnected())
|
||||
if(!SSdbcore.IsConnected())
|
||||
to_chat(usr, "<span class='warning'>Unable to connect to karma database. Please try again later.<br></span>")
|
||||
return
|
||||
else
|
||||
var/DBQuery/query = GLOB.dbcon.NewQuery("SELECT karma, karmaspent FROM [format_table_name("karmatotals")] WHERE byondkey='[sanitzedkey]'")
|
||||
query.Execute()
|
||||
|
||||
var/totalkarma
|
||||
var/karmaspent
|
||||
while(query.NextRow())
|
||||
totalkarma = query.item[1]
|
||||
karmaspent = query.item[2]
|
||||
currentkarma = (text2num(totalkarma) - text2num(karmaspent))
|
||||
var/datum/db_query/query = SSdbcore.NewQuery("SELECT karma, karmaspent FROM [format_table_name("karmatotals")] WHERE byondkey=:ckey", list(
|
||||
"ckey" = ckey
|
||||
))
|
||||
if(!query.warn_execute())
|
||||
qdel(query)
|
||||
return
|
||||
|
||||
var/totalkarma
|
||||
var/karmaspent
|
||||
while(query.NextRow())
|
||||
totalkarma = query.item[1]
|
||||
karmaspent = query.item[2]
|
||||
qdel(query)
|
||||
currentkarma = (text2num(totalkarma) - text2num(karmaspent))
|
||||
|
||||
return currentkarma
|
||||
|
||||
@@ -196,9 +222,12 @@ GLOBAL_LIST_EMPTY(karma_spenders)
|
||||
karmashopmenu()
|
||||
|
||||
/client/proc/karmashopmenu()
|
||||
var/sanitzedkey = sanitizeSQL(usr.ckey)
|
||||
var/DBQuery/query = GLOB.dbcon.NewQuery("SELECT * FROM [format_table_name("whitelist")] WHERE ckey='[sanitzedkey]'")
|
||||
query.Execute()
|
||||
var/datum/db_query/query = SSdbcore.NewQuery("SELECT ckey, job, species FROM [format_table_name("whitelist")] WHERE ckey=:ckey", list(
|
||||
"ckey" = ckey
|
||||
))
|
||||
if(!query.warn_execute())
|
||||
qdel(query)
|
||||
return
|
||||
|
||||
var/list/joblist
|
||||
var/list/specieslist
|
||||
@@ -206,9 +235,11 @@ GLOBAL_LIST_EMPTY(karma_spenders)
|
||||
var/dbspecies
|
||||
var/dbckey
|
||||
while(query.NextRow())
|
||||
dbckey = query.item[2]
|
||||
dbjob = query.item[3]
|
||||
dbspecies = query.item[4]
|
||||
dbckey = query.item[1]
|
||||
dbjob = query.item[2]
|
||||
dbspecies = query.item[3]
|
||||
|
||||
qdel(query)
|
||||
|
||||
if(dbckey)
|
||||
joblist = splittext(dbjob,",")
|
||||
@@ -349,60 +380,81 @@ GLOBAL_LIST_EMPTY(karma_spenders)
|
||||
karmashopmenu()
|
||||
|
||||
/client/proc/DB_job_unlock(var/job,var/cost)
|
||||
var/sanitzedkey = sanitizeSQL(usr.ckey)
|
||||
var/DBQuery/query = GLOB.dbcon.NewQuery("SELECT * FROM [format_table_name("whitelist")] WHERE ckey='[sanitzedkey]'")
|
||||
query.Execute()
|
||||
var/datum/db_query/select_query = SSdbcore.NewQuery("SELECT ckey, job FROM [format_table_name("whitelist")] WHERE ckey=:ckey", list(
|
||||
"ckey" = ckey
|
||||
))
|
||||
if(!select_query.warn_execute())
|
||||
qdel(select_query)
|
||||
return
|
||||
|
||||
var/dbjob
|
||||
var/dbckey
|
||||
while(query.NextRow())
|
||||
dbckey = query.item[2]
|
||||
dbjob = query.item[3]
|
||||
while(select_query.NextRow())
|
||||
dbckey = select_query.item[1]
|
||||
dbjob = select_query.item[2]
|
||||
|
||||
qdel(select_query)
|
||||
if(!dbckey)
|
||||
query = GLOB.dbcon.NewQuery("INSERT INTO [format_table_name("whitelist")] (ckey, job) VALUES ('[sanitzedkey]','[job]')")
|
||||
if(!query.Execute())
|
||||
queryErrorLog(query.ErrorMsg(),"adding new key")
|
||||
var/datum/db_query/insert_query = SSdbcore.NewQuery("INSERT INTO [format_table_name("whitelist")] (ckey, job) VALUES (:ckey, :job)", list(
|
||||
"ckey" = ckey,
|
||||
"job" = job
|
||||
))
|
||||
if(!insert_query.warn_execute())
|
||||
qdel(insert_query)
|
||||
return
|
||||
else
|
||||
to_chat(usr, "You have unlocked [job].")
|
||||
message_admins("[key_name(usr)] has unlocked [job].")
|
||||
message_admins("[key_name(usr)] has unlocked [job].") // why do we admin log this
|
||||
karmacharge(cost)
|
||||
|
||||
qdel(insert_query)
|
||||
|
||||
if(dbckey)
|
||||
var/list/joblist = splittext(dbjob,",")
|
||||
if(!(job in joblist))
|
||||
joblist += job
|
||||
var/newjoblist = jointext(joblist,",")
|
||||
query = GLOB.dbcon.NewQuery("UPDATE [format_table_name("whitelist")] SET job='[newjoblist]' WHERE ckey='[dbckey]'")
|
||||
if(!query.Execute())
|
||||
queryErrorLog(query.ErrorMsg(),"updating existing entry")
|
||||
var/datum/db_query/update_query = SSdbcore.NewQuery("UPDATE [format_table_name("whitelist")] SET job=:newjoblist WHERE ckey=:ckey", list(
|
||||
"newjoblist" = newjoblist,
|
||||
"ckey" = ckey
|
||||
))
|
||||
if(!update_query.warn_execute())
|
||||
qdel(update_query)
|
||||
return
|
||||
else
|
||||
to_chat(usr, "You have unlocked [job].")
|
||||
message_admins("[key_name(usr)] has unlocked [job].")
|
||||
karmacharge(cost)
|
||||
qdel(update_query)
|
||||
else
|
||||
to_chat(usr, "You already have this job unlocked!")
|
||||
return
|
||||
|
||||
/client/proc/DB_species_unlock(var/species,var/cost)
|
||||
var/sanitzedkey = sanitizeSQL(usr.ckey)
|
||||
var/DBQuery/query = GLOB.dbcon.NewQuery("SELECT * FROM [format_table_name("whitelist")] WHERE ckey='[sanitzedkey]'")
|
||||
query.Execute()
|
||||
var/datum/db_query/select_query = SSdbcore.NewQuery("SELECT ckey, species FROM [format_table_name("whitelist")] WHERE ckey=:ckey", list(
|
||||
"ckey" = ckey
|
||||
))
|
||||
if(!select_query.warn_execute())
|
||||
qdel(select_query)
|
||||
return
|
||||
|
||||
var/dbspecies
|
||||
var/dbckey
|
||||
while(query.NextRow())
|
||||
dbckey = query.item[2]
|
||||
dbspecies = query.item[4]
|
||||
while(select_query.NextRow())
|
||||
dbckey = select_query.item[1]
|
||||
dbspecies = select_query.item[2]
|
||||
if(!dbckey)
|
||||
query = GLOB.dbcon.NewQuery("INSERT INTO [format_table_name("whitelist")] (ckey, species) VALUES ('[sanitzedkey]','[species]')")
|
||||
if(!query.Execute())
|
||||
queryErrorLog(query.ErrorMsg(),"adding new key")
|
||||
var/datum/db_query/insert_query = SSdbcore.NewQuery("INSERT INTO [format_table_name("whitelist")] (ckey, species) VALUES (:ckey, :species)", list(
|
||||
"ckey" = ckey,
|
||||
"species" = species
|
||||
))
|
||||
if(!insert_query.warn_execute())
|
||||
qdel(insert_query)
|
||||
return
|
||||
else
|
||||
to_chat(usr, "You have unlocked [species].")
|
||||
message_admins("[key_name(usr)] has unlocked [species].")
|
||||
qdel(insert_query)
|
||||
karmacharge(cost)
|
||||
|
||||
if(dbckey)
|
||||
@@ -410,40 +462,50 @@ GLOBAL_LIST_EMPTY(karma_spenders)
|
||||
if(!(species in specieslist))
|
||||
specieslist += species
|
||||
var/newspecieslist = jointext(specieslist,",")
|
||||
query = GLOB.dbcon.NewQuery("UPDATE [format_table_name("whitelist")] SET species='[newspecieslist]' WHERE ckey='[dbckey]'")
|
||||
if(!query.Execute())
|
||||
queryErrorLog(query.ErrorMsg(),"updating existing entry")
|
||||
var/datum/db_query/update_query = SSdbcore.NewQuery("UPDATE [format_table_name("whitelist")] SET species=:newspecieslist WHERE ckey=:ckey", list(
|
||||
"newspecieslist" = newspecieslist,
|
||||
"ckey" = ckey
|
||||
))
|
||||
if(!update_query.warn_execute())
|
||||
qdel(update_query)
|
||||
return
|
||||
else
|
||||
to_chat(usr, "You have unlocked [species].")
|
||||
message_admins("[key_name(usr)] has unlocked [species].")
|
||||
qdel(update_query)
|
||||
karmacharge(cost)
|
||||
else
|
||||
to_chat(usr, "You already have this species unlocked!")
|
||||
return
|
||||
|
||||
/client/proc/karmacharge(var/cost,var/refund = FALSE)
|
||||
var/sanitzedkey = sanitizeSQL(usr.ckey)
|
||||
var/DBQuery/query = GLOB.dbcon.NewQuery("SELECT * FROM [format_table_name("karmatotals")] WHERE byondkey='[sanitzedkey]'")
|
||||
query.Execute()
|
||||
var/datum/db_query/select_query = SSdbcore.NewQuery("SELECT karmaspent FROM [format_table_name("karmatotals")] WHERE byondkey=:ckey", list(
|
||||
"ckey" = ckey
|
||||
))
|
||||
if(!select_query.warn_execute())
|
||||
qdel(select_query)
|
||||
return
|
||||
|
||||
while(query.NextRow())
|
||||
var/spent = text2num(query.item[4])
|
||||
while(select_query.NextRow())
|
||||
var/spent = text2num(select_query.item[1])
|
||||
if(refund)
|
||||
spent -= cost
|
||||
else
|
||||
spent += cost
|
||||
query = GLOB.dbcon.NewQuery("UPDATE [format_table_name("karmatotals")] SET karmaspent=[spent] WHERE byondkey='[sanitzedkey]'")
|
||||
if(!query.Execute())
|
||||
queryErrorLog(query.ErrorMsg(),"updating existing entry")
|
||||
var/datum/db_query/update_query = SSdbcore.NewQuery("UPDATE [format_table_name("karmatotals")] SET karmaspent=:spent WHERE byondkey=:ckey", list(
|
||||
"spent" = spent,
|
||||
"ckey" = ckey
|
||||
))
|
||||
if(!update_query.warn_execute())
|
||||
qdel(update_query)
|
||||
return
|
||||
else
|
||||
to_chat(usr, "You have been [refund ? "refunded" : "charged"] [cost] karma.")
|
||||
message_admins("[key_name(usr)] has been [refund ? "refunded" : "charged"] [cost] karma.")
|
||||
qdel(update_query)
|
||||
return
|
||||
|
||||
/client/proc/karmarefund(var/type,var/name,var/cost)
|
||||
var/sanitzedkey = sanitizeSQL(usr.ckey)
|
||||
switch(name)
|
||||
if("Tajaran Ambassador","Unathi Ambassador","Skrell Ambassador","Diona Ambassador","Kidan Ambassador",
|
||||
"Slime People Ambassador","Grey Ambassador","Vox Ambassador","Customs Officer")
|
||||
@@ -454,37 +516,50 @@ GLOBAL_LIST_EMPTY(karma_spenders)
|
||||
to_chat(usr, "<span class='warning'>That job is not refundable.</span>")
|
||||
return
|
||||
|
||||
var/DBQuery/query = GLOB.dbcon.NewQuery("SELECT * FROM [format_table_name("whitelist")] WHERE ckey='[sanitzedkey]'")
|
||||
query.Execute()
|
||||
var/datum/db_query/query = SSdbcore.NewQuery("SELECT ckey, job, species FROM [format_table_name("whitelist")] WHERE ckey=:ckey", list(
|
||||
"ckey" = ckey
|
||||
))
|
||||
if(!query.warn_execute())
|
||||
qdel(query)
|
||||
return
|
||||
|
||||
var/dbjob
|
||||
var/dbspecies
|
||||
var/dbckey
|
||||
while(query.NextRow())
|
||||
dbckey = query.item[2]
|
||||
dbjob = query.item[3]
|
||||
dbspecies = query.item[4]
|
||||
dbckey = query.item[1]
|
||||
dbjob = query.item[2]
|
||||
dbspecies = query.item[3]
|
||||
|
||||
qdel(query)
|
||||
|
||||
if(dbckey)
|
||||
var/list/typelist = list()
|
||||
var/statement
|
||||
switch(type)
|
||||
if("job")
|
||||
typelist = splittext(dbjob,",")
|
||||
statement = "UPDATE [format_table_name("whitelist")] SET job=:newtypelist WHERE ckey=:ckey"
|
||||
if("species")
|
||||
typelist = splittext(dbspecies,",")
|
||||
statement = "UPDATE [format_table_name("whitelist")] SET species=:newtypelist WHERE ckey=:ckey"
|
||||
else
|
||||
to_chat(usr, "<span class='warning'>Type [type] is not a valid column.</span>")
|
||||
|
||||
if(name in typelist)
|
||||
typelist -= name
|
||||
var/newtypelist = jointext(typelist,",")
|
||||
query = GLOB.dbcon.NewQuery("UPDATE [format_table_name("whitelist")] SET [type]='[newtypelist]' WHERE ckey='[dbckey]'")
|
||||
if(!query.Execute())
|
||||
queryErrorLog(query.ErrorMsg(),"updating existing entry")
|
||||
var/datum/db_query/update_query = SSdbcore.NewQuery(statement, list(
|
||||
"ckey" = ckey,
|
||||
"newtypelist" = newtypelist
|
||||
))
|
||||
if(!update_query.warn_execute())
|
||||
qdel(update_query)
|
||||
return
|
||||
else
|
||||
to_chat(usr, "You have been refunded [cost] karma for [type] [name].")
|
||||
message_admins("[key_name(usr)] has been refunded [cost] karma for [type] [name].")
|
||||
qdel(update_query)
|
||||
karmacharge(text2num(cost),1)
|
||||
else
|
||||
to_chat(usr, "<span class='warning'>You have not bought [name].</span>")
|
||||
@@ -492,23 +567,23 @@ GLOBAL_LIST_EMPTY(karma_spenders)
|
||||
else
|
||||
to_chat(usr, "<span class='warning'>Your ckey ([dbckey]) was not found.</span>")
|
||||
|
||||
/client/proc/queryErrorLog(err = null, errType)
|
||||
log_game("SQL ERROR during whitelist logging ([errType]]). Error : \[[err]\]\n")
|
||||
message_admins("SQL ERROR during whitelist logging ([errType]]). Error : \[[err]\]\n")
|
||||
|
||||
/client/proc/checkpurchased(var/name = null) // If the first parameter is null, return a full list of purchases
|
||||
var/sanitzedkey = sanitizeSQL(usr.ckey)
|
||||
var/DBQuery/query = GLOB.dbcon.NewQuery("SELECT * FROM [format_table_name("whitelist")] WHERE ckey='[sanitzedkey]'")
|
||||
query.Execute()
|
||||
var/datum/db_query/query = SSdbcore.NewQuery("SELECT ckey, job, species FROM [format_table_name("whitelist")] WHERE ckey=:ckey", list(
|
||||
"ckey" = ckey
|
||||
))
|
||||
if(!query.warn_execute())
|
||||
qdel(query)
|
||||
return
|
||||
|
||||
var/dbjob
|
||||
var/dbspecies
|
||||
var/dbckey
|
||||
while(query.NextRow())
|
||||
dbckey = query.item[2]
|
||||
dbjob = query.item[3]
|
||||
dbspecies = query.item[4]
|
||||
dbckey = query.item[1]
|
||||
dbjob = query.item[2]
|
||||
dbspecies = query.item[3]
|
||||
|
||||
qdel(query)
|
||||
if(dbckey)
|
||||
var/list/joblist = splittext(dbjob,",")
|
||||
var/list/specieslist = splittext(dbspecies,",")
|
||||
|
||||
@@ -10,12 +10,14 @@
|
||||
if(!isbn)
|
||||
return
|
||||
|
||||
var/DBQuery/query_delbook = GLOB.dbcon.NewQuery("DELETE FROM [format_table_name("library")] WHERE id=[isbn]")
|
||||
if(!query_delbook.Execute())
|
||||
var/err = query_delbook.ErrorMsg()
|
||||
log_game("SQL ERROR deleting book. Error : \[[err]\]\n")
|
||||
var/datum/db_query/query_delbook = SSdbcore.NewQuery("DELETE FROM [format_table_name("library")] WHERE id=:isbn", list(
|
||||
"isbn" = text2num(isbn) // just to be sure
|
||||
))
|
||||
if(!query_delbook.warn_execute())
|
||||
qdel(query_delbook)
|
||||
return
|
||||
|
||||
qdel(query_delbook)
|
||||
log_admin("[key_name(usr)] has deleted the book [isbn].")
|
||||
message_admins("[key_name_admin(usr)] has deleted the book [isbn].")
|
||||
|
||||
@@ -35,10 +37,9 @@
|
||||
|
||||
var/dat = "<table><tr><th>ISBN</th><th>Title</th><th>Total Flags</th><th>Options</th></tr>"
|
||||
|
||||
var/DBQuery/query = GLOB.dbcon.NewQuery("SELECT id, title, flagged FROM [format_table_name("library")] WHERE flagged > 0 ORDER BY flagged DESC")
|
||||
if(!query.Execute())
|
||||
var/err = query.ErrorMsg()
|
||||
log_game("SQL ERROR getting flagged books. Error : \[[err]\]\n")
|
||||
var/datum/db_query/query = SSdbcore.NewQuery("SELECT id, title, flagged FROM [format_table_name("library")] WHERE flagged > 0 ORDER BY flagged DESC")
|
||||
if(!query.warn_execute())
|
||||
qdel(query)
|
||||
return
|
||||
|
||||
var/books = 0
|
||||
@@ -52,6 +53,7 @@
|
||||
dat += "</td>"
|
||||
|
||||
dat += "</table>"
|
||||
qdel(query)
|
||||
|
||||
if(!books)
|
||||
dat = "<h1>No flagged books! :)</h1>"
|
||||
|
||||
@@ -31,48 +31,65 @@
|
||||
/obj/machinery/computer/library/proc/get_page(var/page_num)
|
||||
var/searchquery = ""
|
||||
var/where = 0
|
||||
var/list/sql_params = list()
|
||||
if(query)
|
||||
if(query.title && query.title != "")
|
||||
searchquery += " WHERE title LIKE '%[sanitizeSQL(query.title)]%'"
|
||||
searchquery += " WHERE title LIKE :title"
|
||||
sql_params["title"] = "%[query.title]%"
|
||||
where = 1
|
||||
if(query.author && query.author != "")
|
||||
searchquery += " [!where ? "WHERE" : "AND"] author LIKE '%[sanitizeSQL(query.author)]%'"
|
||||
searchquery += " [!where ? "WHERE" : "AND"] author LIKE :author"
|
||||
sql_params["author"] = "%[query.author]%"
|
||||
where = 1
|
||||
if(query.category && query.category != "")
|
||||
searchquery += " [!where ? "WHERE" : "AND"] category LIKE '%[sanitizeSQL(query.category)]%'"
|
||||
searchquery += " [!where ? "WHERE" : "AND"] category LIKE :cat"
|
||||
sql_params["cat"] = "%[query.category]%"
|
||||
if(query.category == "Fiction")
|
||||
searchquery += " AND category NOT LIKE '%Non-Fiction%'"
|
||||
where = 1
|
||||
|
||||
// This one doesnt take player input directly, so it doesnt require params
|
||||
searchquery += " [!where ? "WHERE" : "AND"] flagged < [MAX_BOOK_FLAGS]"
|
||||
var/sql = "SELECT id, author, title, category, ckey, flagged FROM [format_table_name("library")] [searchquery] LIMIT [(page_num - 1) * LIBRARY_BOOKS_PER_PAGE], [LIBRARY_BOOKS_PER_PAGE]"
|
||||
// This does though
|
||||
var/sql = "SELECT id, author, title, category, ckey, flagged FROM [format_table_name("library")] [searchquery] LIMIT :lowerlimit, :upperlimit"
|
||||
sql_params["lowerlimit"] = text2num((page_num - 1) * LIBRARY_BOOKS_PER_PAGE)
|
||||
sql_params["upperlimit"] = LIBRARY_BOOKS_PER_PAGE
|
||||
|
||||
// Pagination
|
||||
var/DBQuery/_query = GLOB.dbcon.NewQuery(sql)
|
||||
_query.Execute()
|
||||
if(_query.ErrorMsg())
|
||||
log_world(_query.ErrorMsg())
|
||||
var/datum/db_query/select_query = SSdbcore.NewQuery(sql, sql_params)
|
||||
|
||||
if(!select_query.warn_execute())
|
||||
qdel(select_query)
|
||||
return
|
||||
|
||||
var/list/results = list()
|
||||
while(_query.NextRow())
|
||||
while(select_query.NextRow())
|
||||
var/datum/cachedbook/CB = new()
|
||||
CB.LoadFromRow(list(
|
||||
"id" =_query.item[1],
|
||||
"author" =_query.item[2],
|
||||
"title" =_query.item[3],
|
||||
"category"=_query.item[4],
|
||||
"ckey" =_query.item[5],
|
||||
"flagged" =text2num(_query.item[6])
|
||||
"id" =select_query.item[1],
|
||||
"author" =select_query.item[2],
|
||||
"title" =select_query.item[3],
|
||||
"category"=select_query.item[4],
|
||||
"ckey" =select_query.item[5],
|
||||
"flagged" =text2num(select_query.item[6])
|
||||
))
|
||||
results += CB
|
||||
qdel(select_query)
|
||||
return results
|
||||
|
||||
/obj/machinery/computer/library/proc/get_num_results()
|
||||
var/sql = "SELECT COUNT(*) FROM [format_table_name("library")]"
|
||||
var/sql = "SELECT COUNT(id) FROM [format_table_name("library")]"
|
||||
|
||||
var/DBQuery/_query = GLOB.dbcon.NewQuery(sql)
|
||||
_query.Execute()
|
||||
while(_query.NextRow())
|
||||
return text2num(_query.item[1])
|
||||
var/datum/db_query/count_query = SSdbcore.NewQuery(sql)
|
||||
if(!count_query.warn_execute())
|
||||
qdel(count_query)
|
||||
return
|
||||
|
||||
while(count_query.NextRow())
|
||||
var/value = text2num(count_query.item[1])
|
||||
qdel(count_query)
|
||||
return value
|
||||
qdel(count_query)
|
||||
return 0
|
||||
|
||||
/obj/machinery/computer/library/proc/get_pagelist()
|
||||
|
||||
@@ -91,7 +91,7 @@
|
||||
<A href='?src=[UID()];switchscreen=0'>(Return to main menu)</A><BR>"}
|
||||
if(4)
|
||||
dat += "<h3>External Archive</h3>"
|
||||
if(!GLOB.dbcon.IsConnected())
|
||||
if(!SSdbcore.IsConnected())
|
||||
dat += "<font color=red><b>ERROR</b>: Unable to contact External Archive. Please contact your system administrator for assistance.</font>"
|
||||
else
|
||||
num_results = src.get_num_results()
|
||||
@@ -262,11 +262,13 @@
|
||||
var/datum/cachedbook/target = getBookByID(href_list["del"]) // Sanitized in getBookByID
|
||||
var/ans = alert(usr, "Are you sure you wish to delete \"[target.title]\", by [target.author]? This cannot be undone.", "Library System", "Yes", "No")
|
||||
if(ans=="Yes")
|
||||
var/DBQuery/query = GLOB.dbcon.NewQuery("DELETE FROM [format_table_name("library")] WHERE id=[target.id]")
|
||||
var/response = query.Execute()
|
||||
if(!response)
|
||||
to_chat(usr, query.ErrorMsg())
|
||||
var/datum/db_query/query = SSdbcore.NewQuery("DELETE FROM [format_table_name("library")] WHERE id=:id", list(
|
||||
"id" = text2num(target.id)
|
||||
))
|
||||
if(!query.warn_execute())
|
||||
qdel(query)
|
||||
return
|
||||
qdel(query)
|
||||
log_admin("LIBRARY: [key_name(usr)] has deleted \"[target.title]\", by [target.author] ([target.ckey])!")
|
||||
message_admins("[key_name_admin(usr)] has deleted \"[target.title]\", by [target.author] ([target.ckey])!")
|
||||
src.updateUsrDialog()
|
||||
@@ -278,22 +280,25 @@
|
||||
var/tckey = ckey(href_list["delbyckey"])
|
||||
var/ans = alert(usr,"Are you sure you wish to delete all books by [tckey]? This cannot be undone.", "Library System", "Yes", "No")
|
||||
if(ans=="Yes")
|
||||
var/DBQuery/query = GLOB.dbcon.NewQuery("DELETE FROM [format_table_name("library")] WHERE ckey='[sanitizeSQL(tckey)]'")
|
||||
var/response = query.Execute()
|
||||
if(!response)
|
||||
to_chat(usr, query.ErrorMsg())
|
||||
var/datum/db_query/query = SSdbcore.NewQuery("DELETE FROM [format_table_name("library")] WHERE ckey=:ckey", list(
|
||||
"ckey" = tckey
|
||||
))
|
||||
if(!query.warn_execute())
|
||||
qdel(query)
|
||||
return
|
||||
var/affected=query.RowsAffected()
|
||||
if(affected==0)
|
||||
|
||||
if(query.affected == 0)
|
||||
to_chat(usr, "<span class='danger'>Unable to find any matching rows.</span>")
|
||||
qdel(query)
|
||||
return
|
||||
log_admin("LIBRARY: [key_name(usr)] has deleted [affected] books written by [tckey]!")
|
||||
message_admins("[key_name_admin(usr)] has deleted [affected] books written by [tckey]!")
|
||||
qdel(query)
|
||||
log_admin("LIBRARY: [key_name(usr)] has deleted [query.affected] books written by [tckey]!")
|
||||
message_admins("[key_name_admin(usr)] has deleted [query.affected] books written by [tckey]!")
|
||||
src.updateUsrDialog()
|
||||
return
|
||||
|
||||
if(href_list["flag"])
|
||||
if(!GLOB.dbcon.IsConnected())
|
||||
if(!SSdbcore.IsConnected())
|
||||
alert("Connection to Archive has been severed. Aborting.")
|
||||
return
|
||||
var/id = href_list["flag"]
|
||||
@@ -378,21 +383,26 @@
|
||||
if(scanner.cache)
|
||||
var/choice = input("Are you certain you wish to upload this title to the Archive?") in list("Confirm", "Abort")
|
||||
if(choice == "Confirm")
|
||||
establish_db_connection()
|
||||
if(!GLOB.dbcon.IsConnected())
|
||||
if(!SSdbcore.IsConnected())
|
||||
alert("Connection to Archive has been severed. Aborting.")
|
||||
else
|
||||
var/sqltitle = sanitizeSQL(scanner.cache.name)
|
||||
var/sqlauthor = sanitizeSQL(scanner.cache.author)
|
||||
var/sqlcontent = sanitizeSQL(scanner.cache.dat)
|
||||
var/sqlcategory = sanitizeSQL(upload_category)
|
||||
var/DBQuery/query = GLOB.dbcon.NewQuery("INSERT INTO [format_table_name("library")] (author, title, content, category, ckey, flagged) VALUES ('[sqlauthor]', '[sqltitle]', '[sqlcontent]', '[sqlcategory]', '[ckey(usr.key)]', 0)")
|
||||
var/response = query.Execute()
|
||||
if(!response)
|
||||
to_chat(usr, query.ErrorMsg())
|
||||
else
|
||||
log_admin("[usr.name]/[usr.key] has uploaded the book titled [scanner.cache.name], [length(scanner.cache.dat)] characters in length")
|
||||
message_admins("[key_name_admin(usr)] has uploaded the book titled [scanner.cache.name], [length(scanner.cache.dat)] characters in length")
|
||||
var/datum/db_query/query = SSdbcore.NewQuery({"
|
||||
INSERT INTO [format_table_name("library")] (author, title, content, category, ckey, flagged)
|
||||
VALUES (:author, :title, :content, :category, :ckey, 0)"}, list(
|
||||
"author" = scanner.cache.author,
|
||||
"title" = scanner.cache.name,
|
||||
"content" = scanner.cache.dat,
|
||||
"category" = upload_category,
|
||||
"ckey" = usr.ckey
|
||||
))
|
||||
|
||||
if(!query.warn_execute())
|
||||
qdel(query)
|
||||
return
|
||||
|
||||
qdel(query)
|
||||
log_admin("[usr.name]/[usr.key] has uploaded the book titled [scanner.cache.name], [length(scanner.cache.dat)] characters in length")
|
||||
message_admins("[key_name_admin(usr)] has uploaded the book titled [scanner.cache.name], [length(scanner.cache.dat)] characters in length")
|
||||
|
||||
if(href_list["id"])
|
||||
if(href_list["id"]=="-1")
|
||||
@@ -400,7 +410,7 @@
|
||||
if(!href_list["id"])
|
||||
return
|
||||
|
||||
if(!GLOB.dbcon.IsConnected())
|
||||
if(!SSdbcore.IsConnected())
|
||||
alert("Connection to Archive has been severed. Aborting.")
|
||||
return
|
||||
|
||||
@@ -423,7 +433,7 @@
|
||||
if(!href_list["manual"]) return
|
||||
var/bookid = href_list["manual"]
|
||||
|
||||
if(!GLOB.dbcon.IsConnected())
|
||||
if(!SSdbcore.IsConnected())
|
||||
alert("Connection to Archive has been severed. Aborting.")
|
||||
return
|
||||
|
||||
|
||||
@@ -26,8 +26,7 @@
|
||||
<A href='?src=[UID()];setauthor=1'>Filter by Author: [query.author]</A><br />
|
||||
<A href='?src=[UID()];search=1'>\[Start Search\]</A><br />"}
|
||||
if(1)
|
||||
establish_db_connection()
|
||||
if(!GLOB.dbcon.IsConnected())
|
||||
if(!SSdbcore.IsConnected())
|
||||
dat += "<font color=red><b>ERROR</b>: Unable to contact External Archive. Please contact your system administrator for assistance.</font><br />"
|
||||
else if(num_results == 0)
|
||||
dat += "<em>No results found.</em>"
|
||||
@@ -113,7 +112,7 @@
|
||||
screenstate = 0
|
||||
|
||||
if(href_list["flag"])
|
||||
if(!GLOB.dbcon.IsConnected())
|
||||
if(!SSdbcore.IsConnected())
|
||||
alert("Connection to Archive has been severed. Aborting.")
|
||||
return
|
||||
var/id = href_list["flag"]
|
||||
|
||||
@@ -44,18 +44,6 @@ GLOBAL_LIST_INIT(library_section_names, list("Any", "Fiction", "Non-Fiction", "A
|
||||
var/category
|
||||
var/title
|
||||
|
||||
/datum/library_query/proc/toSQL()
|
||||
var/list/where = list()
|
||||
if(author || title || category)
|
||||
if(author)
|
||||
where.Add("author LIKE '%[sanitizeSQL(author)]%'")
|
||||
if(category)
|
||||
where.Add("category = '[sanitizeSQL(category)]'")
|
||||
if(title)
|
||||
where.Add("title LIKE '%[sanitizeSQL(title)]%'")
|
||||
return " WHERE " + jointext(where, " AND ")
|
||||
return ""
|
||||
|
||||
// So we can have catalogs of books that are programmatic, and ones that aren't.
|
||||
/datum/library_catalog
|
||||
var/list/cached_books = list()
|
||||
@@ -90,11 +78,13 @@ GLOBAL_LIST_INIT(library_section_names, list("Any", "Fiction", "Non-Fiction", "A
|
||||
books_flagged_this_round["[id]"] = 1
|
||||
message_admins("[key_name_admin(user)] has flagged book #[id] as inappropriate.")
|
||||
|
||||
var/sqlid = text2num(id)
|
||||
if(!sqlid)
|
||||
var/datum/db_query/query = SSdbcore.NewQuery("UPDATE [format_table_name("library")] SET flagged = flagged + 1 WHERE id=:id", list(
|
||||
"id" = text2num(id)
|
||||
))
|
||||
if(!query.warn_execute())
|
||||
qdel(query)
|
||||
return
|
||||
var/DBQuery/query = GLOB.dbcon.NewQuery("UPDATE [format_table_name("library")] SET flagged = flagged + 1 WHERE id=[sqlid]")
|
||||
query.Execute()
|
||||
qdel(query)
|
||||
|
||||
/datum/library_catalog/proc/rmBookByID(mob/user, id)
|
||||
if("[id]" in cached_books)
|
||||
@@ -103,21 +93,24 @@ GLOBAL_LIST_INIT(library_section_names, list("Any", "Fiction", "Non-Fiction", "A
|
||||
to_chat(user, "<span class='danger'>That book cannot be removed from the system, as it does not actually exist in the database.</span>")
|
||||
return
|
||||
|
||||
var/sqlid = text2num(id)
|
||||
if(!sqlid)
|
||||
var/datum/db_query/query = SSdbcore.NewQuery("DELETE FROM [format_table_name("library")] WHERE id=:id", list(
|
||||
"id" = text2num(id)
|
||||
))
|
||||
if(!query.warn_execute())
|
||||
qdel(query)
|
||||
return
|
||||
var/DBQuery/query = GLOB.dbcon.NewQuery("DELETE FROM [format_table_name("library")] WHERE id=[sqlid]")
|
||||
query.Execute()
|
||||
qdel(query)
|
||||
|
||||
/datum/library_catalog/proc/getBookByID(id)
|
||||
if("[id]" in cached_books)
|
||||
return cached_books["[id]"]
|
||||
|
||||
var/sqlid = text2num(id)
|
||||
if(!sqlid)
|
||||
var/datum/db_query/query = SSdbcore.NewQuery("SELECT id, author, title, category, content, ckey, flagged FROM [format_table_name("library")] WHERE id=:id", list(
|
||||
"id" = text2num(id)
|
||||
))
|
||||
if(!query.warn_execute())
|
||||
qdel(query)
|
||||
return
|
||||
var/DBQuery/query = GLOB.dbcon.NewQuery("SELECT id, author, title, category, content, ckey, flagged FROM [format_table_name("library")] WHERE id=[sqlid]")
|
||||
query.Execute()
|
||||
|
||||
var/list/results=list()
|
||||
while(query.NextRow())
|
||||
@@ -133,7 +126,9 @@ GLOBAL_LIST_INIT(library_section_names, list("Any", "Fiction", "Non-Fiction", "A
|
||||
))
|
||||
results += CB
|
||||
cached_books["[id]"]=CB
|
||||
qdel(query)
|
||||
return CB
|
||||
qdel(query)
|
||||
return results
|
||||
|
||||
/** Scanner **/
|
||||
|
||||
@@ -36,11 +36,12 @@
|
||||
create_random_books(book_count, src, FALSE, category)
|
||||
update_icon()
|
||||
|
||||
// why is this a global proc
|
||||
/proc/create_random_books(amount = 2, location, fail_loud = FALSE, category = null)
|
||||
. = list()
|
||||
if(!isnum(amount) || amount<1)
|
||||
return
|
||||
if(!GLOB.dbcon.IsConnected())
|
||||
if(!SSdbcore.IsConnected())
|
||||
if(fail_loud || prob(5))
|
||||
var/obj/item/paper/P = new(location)
|
||||
P.info = "There once was a book from Nantucket<br>But the database failed us, so f*$! it.<br>I tried to be good to you<br>Now this is an I.O.U<br>If you're feeling entitled, well, stuff it!<br><br><font color='gray'>~</font>"
|
||||
@@ -48,17 +49,27 @@
|
||||
return
|
||||
if(prob(25))
|
||||
category = null
|
||||
var/c = category? " AND category='[sanitizeSQL(category)]'" :""
|
||||
var/DBQuery/query_get_random_books = GLOB.dbcon.NewQuery("SELECT * FROM [format_table_name("library")] WHERE (isnull(flagged) OR flagged = 0)[c] GROUP BY title ORDER BY rand() LIMIT [amount];")
|
||||
query_get_random_books.Execute()
|
||||
var/c = ""
|
||||
var/list/sql_params = list()
|
||||
if(category)
|
||||
c = " AND category=:category"
|
||||
sql_params["category"] = category
|
||||
|
||||
sql_params["amount"] = amount
|
||||
var/datum/db_query/query_get_random_books = SSdbcore.NewQuery("SELECT author, title, content FROM [format_table_name("library")] WHERE (isnull(flagged) OR flagged = 0)[c] GROUP BY title ORDER BY rand() LIMIT :amount", sql_params)
|
||||
if(!query_get_random_books.warn_execute())
|
||||
qdel(query_get_random_books)
|
||||
return
|
||||
|
||||
while(query_get_random_books.NextRow())
|
||||
var/obj/item/book/B = new(location)
|
||||
. += B
|
||||
B.author = query_get_random_books.item[2]
|
||||
B.title = query_get_random_books.item[3]
|
||||
B.dat = query_get_random_books.item[4]
|
||||
B.author = query_get_random_books.item[1]
|
||||
B.title = query_get_random_books.item[2]
|
||||
B.dat = query_get_random_books.item[3]
|
||||
B.name = "Book: [B.title]"
|
||||
B.icon_state= "book[rand(1,8)]"
|
||||
qdel(query_get_random_books)
|
||||
|
||||
/obj/structure/bookcase/random/fiction
|
||||
name = "bookcase (Fiction)"
|
||||
|
||||
@@ -26,22 +26,6 @@
|
||||
|
||||
new_player_panel()
|
||||
|
||||
spawn(30)
|
||||
// Annoy the player with polls.
|
||||
establish_db_connection()
|
||||
if(GLOB.dbcon.IsConnected() && client && client.can_vote())
|
||||
var/isadmin = 0
|
||||
if(client && client.holder)
|
||||
isadmin = 1
|
||||
var/DBQuery/query = GLOB.dbcon.NewQuery("SELECT id FROM [format_table_name("poll_question")] WHERE [(isadmin ? "" : "adminonly = false AND")] Now() BETWEEN starttime AND endtime AND id NOT IN (SELECT pollid FROM [format_table_name("poll_vote")] WHERE ckey = \"[ckey]\") AND id NOT IN (SELECT pollid FROM [format_table_name("poll_textreply")] WHERE ckey = \"[ckey]\")")
|
||||
query.Execute()
|
||||
var/newpoll = 0
|
||||
while(query.NextRow())
|
||||
newpoll = 1
|
||||
break
|
||||
if(newpoll)
|
||||
client.handle_player_polling()
|
||||
|
||||
if(ckey in GLOB.deadmins)
|
||||
verbs += /client/proc/readmin
|
||||
spawn(40)
|
||||
|
||||
@@ -31,17 +31,25 @@
|
||||
tos_consent = TRUE
|
||||
return TRUE
|
||||
|
||||
establish_db_connection()
|
||||
if(!GLOB.dbcon.IsConnected())
|
||||
if(!SSdbcore.IsConnected())
|
||||
tos_consent = TRUE
|
||||
return TRUE
|
||||
|
||||
var/DBQuery/query = GLOB.dbcon.NewQuery("SELECT * FROM [format_table_name("privacy")] WHERE ckey='[src.ckey]' AND consent=1")
|
||||
query.Execute()
|
||||
var/datum/db_query/query = SSdbcore.NewQuery("SELECT ckey FROM [format_table_name("privacy")] WHERE ckey=:ckey AND consent=1", list(
|
||||
"ckey" = ckey
|
||||
))
|
||||
if(!query.warn_execute())
|
||||
qdel(query)
|
||||
// If our query failed, just assume yes
|
||||
tos_consent = TRUE
|
||||
return TRUE
|
||||
|
||||
while(query.NextRow())
|
||||
qdel(query)
|
||||
tos_consent = TRUE
|
||||
return TRUE
|
||||
|
||||
qdel(query)
|
||||
privacy_consent()
|
||||
return FALSE
|
||||
|
||||
@@ -85,25 +93,6 @@
|
||||
if(GLOB.join_tos)
|
||||
output += "<p><a href='byond://?src=[UID()];tos=1'>Terms of Service</A></p>"
|
||||
|
||||
if(!IsGuestKey(src.key))
|
||||
establish_db_connection()
|
||||
|
||||
if(GLOB.dbcon.IsConnected() && client.can_vote())
|
||||
var/isadmin = 0
|
||||
if(src.client && src.client.holder)
|
||||
isadmin = 1
|
||||
var/DBQuery/query = GLOB.dbcon.NewQuery("SELECT id FROM [format_table_name("poll_question")] WHERE [(isadmin ? "" : "adminonly = false AND")] Now() BETWEEN starttime AND endtime AND id NOT IN (SELECT pollid FROM [format_table_name("poll_vote")] WHERE ckey = \"[ckey]\") AND id NOT IN (SELECT pollid FROM [format_table_name("poll_textreply")] WHERE ckey = \"[ckey]\")")
|
||||
query.Execute()
|
||||
var/newpoll = 0
|
||||
while(query.NextRow())
|
||||
newpoll = 1
|
||||
break
|
||||
|
||||
if(newpoll)
|
||||
output += "<p><b><a href='byond://?showpoll=1'>Show Player Polls</A> (NEW!)</b></p>"
|
||||
else
|
||||
output += "<p><a href='byond://?showpoll=1'>Show Player Polls</A></p>"
|
||||
|
||||
output += "</center>"
|
||||
|
||||
var/datum/browser/popup = new(src, "playersetup", "<div align='center'>New Player Options</div>", 240, 330)
|
||||
@@ -151,18 +140,24 @@
|
||||
return FALSE
|
||||
|
||||
if(href_list["consent_signed"])
|
||||
var/sqltime = time2text(world.realtime, "YYYY-MM-DD hh:mm:ss")
|
||||
var/DBQuery/query = GLOB.dbcon.NewQuery("REPLACE INTO [format_table_name("privacy")] (ckey, datetime, consent) VALUES ('[ckey]', '[sqltime]', 1)")
|
||||
query.Execute()
|
||||
var/datum/db_query/query = SSdbcore.NewQuery("REPLACE INTO [format_table_name("privacy")] (ckey, datetime, consent) VALUES (:ckey, Now(), 1)", list(
|
||||
"ckey" = ckey
|
||||
))
|
||||
// If the query fails we dont want them permenantly stuck on being unable to accept TOS
|
||||
query.warn_execute()
|
||||
qdel(query)
|
||||
src << browse(null, "window=privacy_consent")
|
||||
tos_consent = 1
|
||||
new_player_panel_proc()
|
||||
if(href_list["consent_rejected"])
|
||||
tos_consent = 0
|
||||
to_chat(usr, "<span class='warning'>You must consent to the terms of service before you can join!</span>")
|
||||
var/sqltime = time2text(world.realtime, "YYYY-MM-DD hh:mm:ss")
|
||||
var/DBQuery/query = GLOB.dbcon.NewQuery("REPLACE INTO [format_table_name("privacy")] (ckey, datetime, consent) VALUES ('[ckey]', '[sqltime]', 0)")
|
||||
query.Execute()
|
||||
var/datum/db_query/query = SSdbcore.NewQuery("REPLACE INTO [format_table_name("privacy")] (ckey, datetime, consent) VALUES (:ckey, Now(), 0)", list(
|
||||
"ckey" = ckey
|
||||
))
|
||||
// If the query fails we dont want them permenantly stuck on being unable to accept TOS
|
||||
query.warn_execute()
|
||||
qdel(query)
|
||||
|
||||
if(href_list["show_preferences"])
|
||||
client.prefs.ShowChoices(src)
|
||||
|
||||
@@ -1,661 +0,0 @@
|
||||
/datum/polloption
|
||||
var/optionid
|
||||
var/optiontext
|
||||
|
||||
/client/verb/polls_verb()
|
||||
set name = "Show Player Polls"
|
||||
set category = "OOC"
|
||||
handle_player_polling()
|
||||
|
||||
/client/proc/can_vote()
|
||||
return istext(player_age) || player_age >= 30
|
||||
|
||||
/client/proc/handle_player_polling()
|
||||
establish_db_connection()
|
||||
if(GLOB.dbcon.IsConnected())
|
||||
var/isadmin = 0
|
||||
if(holder)
|
||||
isadmin = 1
|
||||
|
||||
var/DBQuery/select_query = GLOB.dbcon.NewQuery("SELECT id, question, (id IN (SELECT pollid FROM [format_table_name("poll_vote")] WHERE ckey = '[ckey]') OR id IN (SELECT pollid FROM [format_table_name("poll_textreply")] WHERE ckey = '[ckey]')) AS voted FROM [format_table_name("poll_question")] WHERE [(isadmin ? "" : "adminonly = false AND")] Now() BETWEEN starttime AND endtime")
|
||||
select_query.Execute()
|
||||
|
||||
var/output = "<div align='center'><B>Player polls</B>"
|
||||
if(check_rights(R_SERVER))
|
||||
output += "(<a href='?createpollwindow=1'>Create new poll</a>)"
|
||||
output +="<hr>"
|
||||
|
||||
output += "<table>"
|
||||
var/color1 = "#ececec"
|
||||
var/color2 = "#e2e2e2"
|
||||
var/i = 0
|
||||
|
||||
output += "<tr><th>Active Polls</th></tr>"
|
||||
while(select_query.NextRow())
|
||||
var/pollid = select_query.item[1]
|
||||
var/pollquestion = select_query.item[2]
|
||||
var/voted = text2num(select_query.item[3])
|
||||
output += "<tr bgcolor='[(i % 2 == 1) ? color1 : color2 ]'><td><a href=\"byond://?pollid=[pollid]\"><b>[pollquestion]</b></a></td></tr>"
|
||||
if(can_vote() && !voted)
|
||||
output += "<tr><td>[poll_player(pollid, 1)]</tr></td>"
|
||||
i++
|
||||
|
||||
// Show expired polls. Non admins can view admin polls at this stage
|
||||
// (just like tgstation's web interface so don't complain)
|
||||
// (Also why was there no ingame interface? tg not having an ingame
|
||||
// interface is a pain in the neck because it means downstreams have to roll their own)
|
||||
select_query = GLOB.dbcon.NewQuery("SELECT id, question FROM [format_table_name("poll_question")] WHERE Now() > endtime ORDER BY id DESC")
|
||||
select_query.Execute()
|
||||
|
||||
output += "<tr><th>Expired Polls</th></tr>"
|
||||
while(select_query.NextRow())
|
||||
var/pollid = select_query.item[1]
|
||||
var/pollquestion = select_query.item[2]
|
||||
output += "<tr bgcolor='[(i % 2 == 1) ? color1 : color2]'><td><a href=\"byond://?pollresults=[pollid]\"><b>[pollquestion]</b></a></td></tr>"
|
||||
|
||||
output += "</table>"
|
||||
|
||||
src << browse(output,"window=playerpolllist;size=500x300")
|
||||
|
||||
/client/proc/poll_results(var/pollid = -1)
|
||||
if(pollid == -1)
|
||||
return
|
||||
establish_db_connection()
|
||||
if(!GLOB.dbcon.IsConnected())
|
||||
return
|
||||
var/DBQuery/select_query = GLOB.dbcon.NewQuery("SELECT polltype, question, adminonly, multiplechoiceoptions, starttime, endtime FROM [format_table_name("poll_question")] WHERE id = [pollid] AND endtime < Now()")
|
||||
select_query.Execute()
|
||||
var/question = ""
|
||||
var/polltype = ""
|
||||
var/adminonly = 0
|
||||
var/multiplechoiceoptions = 0
|
||||
var/starttime = ""
|
||||
var/endtime = ""
|
||||
var/found = 0
|
||||
while(select_query.NextRow())
|
||||
polltype = select_query.item[1]
|
||||
question = select_query.item[2]
|
||||
adminonly = text2num(select_query.item[3])
|
||||
multiplechoiceoptions = text2num(select_query.item[4])
|
||||
starttime = select_query.item[5]
|
||||
endtime = select_query.item[6]
|
||||
found = 1
|
||||
break
|
||||
if(!found)
|
||||
to_chat(src, "<span class='warning'>Poll question details not found. (Maybe the poll isn't expired yet?)</span>")
|
||||
return
|
||||
|
||||
if(polltype == POLLTYPE_MULTI)
|
||||
question += " (Choose up to [multiplechoiceoptions] options)"
|
||||
if(adminonly)
|
||||
question = "(<font color='#997700'>Admin only poll</font>) " + question
|
||||
|
||||
var/output = "<!DOCTYPE html><html><body>"
|
||||
if(polltype == POLLTYPE_MULTI || polltype == POLLTYPE_OPTION)
|
||||
select_query = GLOB.dbcon.NewQuery("SELECT text, percentagecalc, (SELECT COUNT(optionid) FROM [format_table_name("poll_vote")] WHERE optionid = poll_option.id GROUP BY optionid) AS votecount FROM [format_table_name("poll_option")] WHERE pollid = [pollid]")
|
||||
select_query.Execute()
|
||||
var/list/options = list()
|
||||
var/total_votes = 1
|
||||
var/total_percent_votes = 1
|
||||
var/max_votes = 1
|
||||
while(select_query.NextRow())
|
||||
var/text = select_query.item[1]
|
||||
var/percentagecalc = select_query.item[2]
|
||||
var/votecount = text2num(select_query.item[3])
|
||||
if(percentagecalc)
|
||||
total_percent_votes += votecount
|
||||
total_votes += votecount
|
||||
if(votecount > max_votes)
|
||||
max_votes = votecount
|
||||
options[++options.len] = list(text, percentagecalc, votecount)
|
||||
// fuck ie.
|
||||
output += {"
|
||||
<table width='900' align='center' bgcolor='#eeffee' cellspacing='0' cellpadding='4'>
|
||||
<tr bgcolor='#ddffdd'>
|
||||
<th colspan='4' align='center'>[question]<br><font size='1'><b>[starttime] - [endtime]</b></font></th>
|
||||
</tr>
|
||||
<tr bgcolor='#ddffdd'>
|
||||
<th colspan='4' align='center'><div style='width:700px;position:relative'>"}
|
||||
var/list/colors = list("#66c2a5", "#fc8d62", "#8da0cb", "#e78ac3", "#a6d854", "#ffd92f", "#e5c494", "#b3b3b3")
|
||||
var/color_index = 0
|
||||
for(var/list/option in options)
|
||||
var/bar_width = option[3] * 700 / total_votes
|
||||
var/percentage = option[2] ? "[round(option[3] * 100 / total_percent_votes)]%" : "N/A"
|
||||
color_index++
|
||||
if(color_index > colors.len)
|
||||
color_index = 1
|
||||
output += "<div style='width:[bar_width]px;height:[5]px;background-color:[colors[color_index]];float:left' title='[option[1]] ([percentage])'></div>"
|
||||
output += "</div><br><font size='2'><b>(Hover over the colored bar to read description)</b></font></tr>"
|
||||
for(var/list/option in options)
|
||||
var/bar_width = option[3] * 390 / max_votes
|
||||
var/percentage = option[2] ? "[round(option[3] * 100 / total_percent_votes)]%" : "N/A"
|
||||
output += "<tr><td width='300' align='right'>[option[1]]</td>"
|
||||
output += "<td width='100' align='center'><b>[option[3]]</b></td>"
|
||||
output += "<td width='100' align='center'><b>[percentage]</b></td>"
|
||||
output += "<td width='400' align='left'><div style='width:[bar_width]px;height:10px;display:inline-block;background-color:#08b000'></div></td>"
|
||||
output += "</table>"
|
||||
if(polltype == POLLTYPE_RATING)
|
||||
output += {"
|
||||
<table width='900' align='center' bgcolor='#eeffee' cellspacing='0' cellpadding='4'>
|
||||
<tr bgcolor='#ddffdd'>
|
||||
<th colspan='4' align='center'>[question]<br><font size='1'><b>[starttime] - [endtime]</b></font></th>
|
||||
</tr>"}
|
||||
select_query = GLOB.dbcon.NewQuery("SELECT id, text, (SELECT AVG(rating) FROM [format_table_name("poll_vote")] WHERE optionid = poll_option.id AND rating != 'abstain') AS avgrating, (SELECT COUNT(rating) FROM [format_table_name("poll_vote")] WHERE optionid = poll_option.id AND rating != 'abstain') AS countvotes, minval, maxval FROM [format_table_name("poll_option")] WHERE pollid = [pollid]")
|
||||
select_query.Execute()
|
||||
while(select_query.NextRow())
|
||||
output += {"
|
||||
<tr>
|
||||
<td align='right' width='300'>[select_query.item[2]]</th>
|
||||
<td align='center' width='100'><b>N = [select_query.item[4]]</b></th>
|
||||
<td align='center' width='100'><b>AVG = [select_query.item[3]]</b></th>
|
||||
<td align='left' width='400'><table width='400 style='table-layout: fixed'>"}
|
||||
var/optionid = select_query.item[1]
|
||||
var/totalvotes = text2num(select_query.item[4])
|
||||
var/minval = text2num(select_query.item[5])
|
||||
var/maxval = text2num(select_query.item[6])
|
||||
var/maxvote = 1
|
||||
var/list/votecounts = list()
|
||||
for(var/I in minval to maxval)
|
||||
var/DBQuery/rating_query = GLOB.dbcon.NewQuery("SELECT COUNT(rating) AS countrating FROM [format_table_name("poll_vote")] WHERE optionid = [optionid] AND rating = [I] GROUP BY rating")
|
||||
rating_query.Execute()
|
||||
var/votecount = 0
|
||||
while(rating_query.NextRow())
|
||||
votecount = text2num(rating_query.item[1])
|
||||
votecounts["[I]"] = votecount
|
||||
if(votecount > maxvote)
|
||||
maxvote = votecount
|
||||
for(var/I in minval to maxval)
|
||||
var/votecount = votecounts["[I]"]
|
||||
var/bar_width = votecount * 200 / maxvote
|
||||
output += {"
|
||||
<tr>
|
||||
<td align='center' width='50'><b>[I]</b></td>
|
||||
<td align='center' width='50'>[votecount]</td>
|
||||
<td align='center' width='75'>([votecount / totalvotes]%)</td>
|
||||
<td width='200'><div style='width:[bar_width]px;height:10px;display:inline-block;background-color:#08b000'></div></td>
|
||||
</tr>"}
|
||||
output += "</table></td></tr>"
|
||||
output += "</table>"
|
||||
if(polltype == POLLTYPE_TEXT)
|
||||
select_query = GLOB.dbcon.NewQuery("SELECT replytext, COUNT(replytext) AS countresponse, GROUP_CONCAT(DISTINCT ckey SEPARATOR ', ') as ckeys FROM [format_table_name("poll_textreply")] WHERE pollid = [pollid] GROUP BY replytext ORDER BY countresponse DESC")
|
||||
select_query.Execute()
|
||||
output += {"
|
||||
<table width='900' align='center' bgcolor='#eeffee' cellspacing='0' cellpadding='4'>
|
||||
<tr bgcolor='#ddffdd'>
|
||||
<th colspan='2' align='center'>[question]<br><font size='1'><b>[starttime] - [endtime]</b></font></th>
|
||||
</tr>"}
|
||||
while(select_query.NextRow())
|
||||
var/replytext = select_query.item[1]
|
||||
var/countresponse = select_query.item[2]
|
||||
var/ckeys = select_query.item[3]
|
||||
output += {"
|
||||
<tr>
|
||||
<td>[ckeys] ([countresponse] player\s) responded with:</td>
|
||||
<td style='border:1px solid #888888'>[replytext]</td>
|
||||
</tr>"}
|
||||
output += "</table>"
|
||||
output += "</body></html>"
|
||||
|
||||
src << browse(output,"window=pollresults;size=950x500")
|
||||
|
||||
/client/proc/poll_player(var/pollid = -1, var/inline = 0)
|
||||
if(pollid == -1) return
|
||||
establish_db_connection()
|
||||
if(GLOB.dbcon.IsConnected())
|
||||
|
||||
var/DBQuery/select_query = GLOB.dbcon.NewQuery("SELECT starttime, endtime, question, polltype, multiplechoiceoptions FROM [format_table_name("poll_question")] WHERE id = [pollid] AND Now() BETWEEN starttime AND endtime [holder ? "AND adminonly = 0" : ""]")
|
||||
select_query.Execute()
|
||||
|
||||
var/pollstarttime = ""
|
||||
var/pollendtime = ""
|
||||
var/pollquestion = ""
|
||||
var/polltype = ""
|
||||
var/found = 0
|
||||
var/multiplechoiceoptions = 0
|
||||
var/canvote = can_vote()
|
||||
|
||||
while(select_query.NextRow())
|
||||
pollstarttime = select_query.item[1]
|
||||
pollendtime = select_query.item[2]
|
||||
pollquestion = select_query.item[3]
|
||||
polltype = select_query.item[4]
|
||||
found = 1
|
||||
break
|
||||
|
||||
if(!found)
|
||||
to_chat(usr, "<span class='warning'>Poll question details not found. (Maybe you do not have access?)</span>")
|
||||
return
|
||||
|
||||
switch(polltype)
|
||||
//Polls that have enumerated options
|
||||
if(POLLTYPE_OPTION)
|
||||
var/DBQuery/voted_query = GLOB.dbcon.NewQuery("SELECT optionid FROM [format_table_name("poll_vote")] WHERE pollid = [pollid] AND ckey = '[ckey]'")
|
||||
voted_query.Execute()
|
||||
|
||||
var/voted = 0 // If the can't vote then consider them voted
|
||||
var/votedoptionid = 0
|
||||
while(voted_query.NextRow())
|
||||
votedoptionid = text2num(voted_query.item[1])
|
||||
voted = 1
|
||||
break
|
||||
|
||||
var/list/datum/polloption/options = list()
|
||||
|
||||
var/DBQuery/options_query = GLOB.dbcon.NewQuery("SELECT id, text FROM [format_table_name("poll_option")] WHERE pollid = [pollid]")
|
||||
options_query.Execute()
|
||||
while(options_query.NextRow())
|
||||
var/datum/polloption/PO = new()
|
||||
PO.optionid = text2num(options_query.item[1])
|
||||
PO.optiontext = options_query.item[2]
|
||||
options += PO
|
||||
|
||||
var/output
|
||||
if(!inline)
|
||||
output += "<div align='center'><B>Player poll</B>"
|
||||
output +="<hr>"
|
||||
output += "<b>Question: [pollquestion]</b><br>"
|
||||
output += "<font size='2'>Poll runs from <b>[pollstarttime]</b> until <b>[pollendtime]</b></font><p>"
|
||||
|
||||
if(canvote && !voted) //Only make this a form if we have not voted yet
|
||||
output += "<form name='cardcomp' action='byond://' method='get'>"
|
||||
output += "<input type='hidden' name='votepollid' value='[pollid]'>"
|
||||
output += "<input type='hidden' name='votetype' value='OPTION'>"
|
||||
|
||||
output += "<table><tr><td>"
|
||||
for(var/datum/polloption/O in options)
|
||||
if(O.optionid && O.optiontext)
|
||||
if(voted || !canvote)
|
||||
if(votedoptionid == O.optionid)
|
||||
output += "<b>[O.optiontext]</b><br>"
|
||||
else
|
||||
output += "[O.optiontext]<br>"
|
||||
else
|
||||
output += "<input type='radio' name='voteoptionid' value='[O.optionid]'> [O.optiontext]<br>"
|
||||
output += "</td></tr></table>"
|
||||
|
||||
if(canvote && !voted) //Only make this a form if we have not voted yet
|
||||
output += "<p><input type='submit' value='Vote'>"
|
||||
output += "</form>"
|
||||
|
||||
output += "</div>"
|
||||
|
||||
if(inline)
|
||||
return output
|
||||
else
|
||||
src << browse(output,"window=playerpoll;size=500x250")
|
||||
|
||||
//Polls with a text input
|
||||
if(POLLTYPE_TEXT)
|
||||
var/DBQuery/voted_query = GLOB.dbcon.NewQuery("SELECT replytext FROM [format_table_name("poll_textreply")] WHERE pollid = [pollid] AND ckey = '[ckey]'")
|
||||
voted_query.Execute()
|
||||
|
||||
var/voted = 0
|
||||
var/vote_text = ""
|
||||
while(voted_query.NextRow())
|
||||
vote_text = voted_query.item[1]
|
||||
voted = 1
|
||||
break
|
||||
|
||||
|
||||
var/output
|
||||
if(!inline)
|
||||
output += "<div align='center'><B>Player poll</B>"
|
||||
output +="<hr>"
|
||||
output += "<b>Question: [pollquestion]</b><br>"
|
||||
output += "<font size='2'>Feedback gathering runs from <b>[pollstarttime]</b> until <b>[pollendtime]</b></font><p>"
|
||||
|
||||
if(canvote && !voted) //Only make this a form if we have not voted yet
|
||||
output += "<form name='cardcomp' action='byond://' method='get'>"
|
||||
output += "<input type='hidden' name='votepollid' value='[pollid]'>"
|
||||
output += "<input type='hidden' name='votetype' value='TEXT'>"
|
||||
|
||||
output += "<font size='2'>Please provide feedback below. You can use any letters of the English alphabet, numbers and the symbols: . , ! ? : ; -</font><br>"
|
||||
output += "<textarea name='replytext' cols='50' rows='14'></textarea>"
|
||||
|
||||
output += "<p><input type='submit' value='Submit'>"
|
||||
output += "</form>"
|
||||
|
||||
output += "<form name='cardcomp' action='byond://' method='get'>"
|
||||
output += "<input type='hidden' name='votepollid' value='[pollid]'>"
|
||||
output += "<input type='hidden' name='votetype' value='TEXT'>"
|
||||
output += "<input type='hidden' name='replytext' value='ABSTAIN'>"
|
||||
output += "<input type='submit' value='Abstain'>"
|
||||
output += "</form>"
|
||||
else
|
||||
output += "[vote_text]"
|
||||
|
||||
if(inline)
|
||||
return output
|
||||
else
|
||||
src << browse(output,"window=playerpoll;size=500x500")
|
||||
|
||||
//Polls with a text input
|
||||
if(POLLTYPE_RATING)
|
||||
var/DBQuery/voted_query = GLOB.dbcon.NewQuery("SELECT o.text, v.rating FROM [format_table_name("poll_option")] o, erro_poll_vote v WHERE o.pollid = [pollid] AND v.ckey = '[ckey]' AND o.id = v.optionid")
|
||||
voted_query.Execute()
|
||||
|
||||
var/output
|
||||
if(!inline)
|
||||
output += "<div align='center'><B>Player poll</B>"
|
||||
output +="<hr>"
|
||||
output += "<b>Question: [pollquestion]</b><br>"
|
||||
output += "<font size='2'>Poll runs from <b>[pollstarttime]</b> until <b>[pollendtime]</b></font><p>"
|
||||
|
||||
var/voted = 0
|
||||
while(voted_query.NextRow())
|
||||
voted = 1
|
||||
|
||||
var/optiontext = voted_query.item[1]
|
||||
var/rating = voted_query.item[2]
|
||||
|
||||
output += "<br><b>[optiontext] - [rating]</b>"
|
||||
|
||||
if(canvote && !voted) //Only make this a form if we have not voted yet
|
||||
output += "<form name='cardcomp' action='byond://' method='get'>"
|
||||
output += "<input type='hidden' name='votepollid' value='[pollid]'>"
|
||||
output += "<input type='hidden' name='votetype' value='NUMVAL'>"
|
||||
|
||||
var/minid = 999999
|
||||
var/maxid = 0
|
||||
|
||||
var/DBQuery/option_query = GLOB.dbcon.NewQuery("SELECT id, text, minval, maxval, descmin, descmid, descmax FROM [format_table_name("poll_option")] WHERE pollid = [pollid]")
|
||||
option_query.Execute()
|
||||
while(option_query.NextRow())
|
||||
var/optionid = text2num(option_query.item[1])
|
||||
var/optiontext = option_query.item[2]
|
||||
var/minvalue = text2num(option_query.item[3])
|
||||
var/maxvalue = text2num(option_query.item[4])
|
||||
var/descmin = option_query.item[5]
|
||||
var/descmid = option_query.item[6]
|
||||
var/descmax = option_query.item[7]
|
||||
|
||||
if(optionid < minid)
|
||||
minid = optionid
|
||||
if(optionid > maxid)
|
||||
maxid = optionid
|
||||
|
||||
var/midvalue = round( (maxvalue + minvalue) / 2)
|
||||
|
||||
if(isnull(minvalue) || isnull(maxvalue) || (minvalue == maxvalue))
|
||||
continue
|
||||
|
||||
output += "<br>[optiontext]: <select name='o[optionid]'>"
|
||||
output += "<option value='abstain'>abstain</option>"
|
||||
for(var/j = minvalue; j <= maxvalue; j++)
|
||||
if(j == minvalue && descmin)
|
||||
output += "<option value='[j]'>[j] ([descmin])</option>"
|
||||
else if(j == midvalue && descmid)
|
||||
output += "<option value='[j]'>[j] ([descmid])</option>"
|
||||
else if(j == maxvalue && descmax)
|
||||
output += "<option value='[j]'>[j] ([descmax])</option>"
|
||||
else
|
||||
output += "<option value='[j]'>[j]</option>"
|
||||
|
||||
output += "</select>"
|
||||
|
||||
output += "<input type='hidden' name='minid' value='[minid]'>"
|
||||
output += "<input type='hidden' name='maxid' value='[maxid]'>"
|
||||
|
||||
output += "<p><input type='submit' value='Submit'>"
|
||||
output += "</form>"
|
||||
|
||||
if(inline)
|
||||
return output
|
||||
else
|
||||
src << browse(output,"window=playerpoll;size=500x500")
|
||||
if(POLLTYPE_MULTI)
|
||||
var/DBQuery/voted_query = GLOB.dbcon.NewQuery("SELECT optionid FROM [format_table_name("poll_vote")] WHERE pollid = [pollid] AND ckey = '[ckey]'")
|
||||
voted_query.Execute()
|
||||
|
||||
var/list/votedfor = list()
|
||||
var/voted = 0
|
||||
while(voted_query.NextRow())
|
||||
votedfor.Add(text2num(voted_query.item[1]))
|
||||
voted = 1
|
||||
|
||||
var/list/datum/polloption/options = list()
|
||||
var/maxoptionid = 0
|
||||
var/minoptionid = 0
|
||||
|
||||
var/DBQuery/options_query = GLOB.dbcon.NewQuery("SELECT id, text FROM [format_table_name("poll_option")] WHERE pollid = [pollid]")
|
||||
options_query.Execute()
|
||||
while(options_query.NextRow())
|
||||
var/datum/polloption/PO = new()
|
||||
PO.optionid = text2num(options_query.item[1])
|
||||
PO.optiontext = options_query.item[2]
|
||||
if(PO.optionid > maxoptionid)
|
||||
maxoptionid = PO.optionid
|
||||
if(PO.optionid < minoptionid || !minoptionid)
|
||||
minoptionid = PO.optionid
|
||||
options += PO
|
||||
|
||||
|
||||
if(select_query.item[5])
|
||||
multiplechoiceoptions = text2num(select_query.item[5])
|
||||
|
||||
var/output
|
||||
if(!inline)
|
||||
output += "<div align='center'><B>Player poll</B>"
|
||||
output +="<hr>"
|
||||
output += "<b>Question: [pollquestion]</b><br>You can select up to [multiplechoiceoptions] options. If you select more, the first [multiplechoiceoptions] will be saved.<br>"
|
||||
output += "<font size='2'>Poll runs from <b>[pollstarttime]</b> until <b>[pollendtime]</b></font><p>"
|
||||
|
||||
if(canvote && !voted) //Only make this a form if we have not voted yet
|
||||
output += "<form name='cardcomp' action='byond://' method='get'>"
|
||||
output += "<input type='hidden' name='votepollid' value='[pollid]'>"
|
||||
output += "<input type='hidden' name='votetype' value='MULTICHOICE'>"
|
||||
output += "<input type='hidden' name='maxoptionid' value='[maxoptionid]'>"
|
||||
output += "<input type='hidden' name='minoptionid' value='[minoptionid]'>"
|
||||
|
||||
output += "<table><tr><td>"
|
||||
for(var/datum/polloption/O in options)
|
||||
if(O.optionid && O.optiontext)
|
||||
if(canvote && voted)
|
||||
if(O.optionid in votedfor)
|
||||
output += "<b>[O.optiontext]</b><br>"
|
||||
else
|
||||
output += "[O.optiontext]<br>"
|
||||
else
|
||||
output += "<input type='checkbox' name='option_[O.optionid]' value='[O.optionid]'> [O.optiontext]<br>"
|
||||
output += "</td></tr></table>"
|
||||
|
||||
if(canvote && !voted) //Only make this a form if we have not voted yet
|
||||
output += "<p><input type='submit' value='Vote'>"
|
||||
output += "</form>"
|
||||
|
||||
output += "</div>"
|
||||
|
||||
if(inline)
|
||||
return output
|
||||
else
|
||||
src << browse(output,"window=playerpoll;size=600x250")
|
||||
return
|
||||
|
||||
/client/proc/vote_on_poll(var/pollid = -1, var/optionid = -1, var/multichoice = 0)
|
||||
if(pollid == -1 || optionid == -1)
|
||||
return
|
||||
|
||||
if(!isnum(pollid) || !isnum(optionid))
|
||||
return
|
||||
establish_db_connection()
|
||||
if(GLOB.dbcon.IsConnected())
|
||||
|
||||
var/DBQuery/select_query = GLOB.dbcon.NewQuery("SELECT starttime, endtime, question, polltype, multiplechoiceoptions FROM [format_table_name("poll_question")] WHERE id = [pollid] AND Now() BETWEEN starttime AND endtime [holder ? "AND adminonly = 0" : ""]")
|
||||
select_query.Execute()
|
||||
|
||||
var/validpoll = 0
|
||||
var/multiplechoiceoptions = 0
|
||||
|
||||
while(select_query.NextRow())
|
||||
if(select_query.item[4] != POLLTYPE_OPTION && select_query.item[4] != POLLTYPE_MULTI)
|
||||
return
|
||||
validpoll = 1
|
||||
if(select_query.item[5])
|
||||
multiplechoiceoptions = text2num(select_query.item[5])
|
||||
break
|
||||
|
||||
if(!validpoll)
|
||||
to_chat(usr, "<span class='warning'>Poll is not valid.</span>")
|
||||
return
|
||||
|
||||
var/DBQuery/select_query2 = GLOB.dbcon.NewQuery("SELECT id FROM [format_table_name("poll_option")] WHERE id = [optionid] AND pollid = [pollid]")
|
||||
select_query2.Execute()
|
||||
|
||||
var/validoption = 0
|
||||
|
||||
while(select_query2.NextRow())
|
||||
validoption = 1
|
||||
break
|
||||
|
||||
if(!validoption)
|
||||
to_chat(usr, "<span class='warning'>Poll option is not valid.</span>")
|
||||
return
|
||||
|
||||
var/alreadyvoted = 0
|
||||
|
||||
var/DBQuery/voted_query = GLOB.dbcon.NewQuery("SELECT id FROM [format_table_name("poll_vote")] WHERE pollid = [pollid] AND ckey = '[ckey]'")
|
||||
voted_query.Execute()
|
||||
|
||||
while(voted_query.NextRow())
|
||||
alreadyvoted += 1
|
||||
if(!multichoice)
|
||||
break
|
||||
|
||||
if(!multichoice && alreadyvoted)
|
||||
to_chat(usr, "<span class='warning'>You already voted in this poll.</span>")
|
||||
return
|
||||
|
||||
if(multichoice && (alreadyvoted >= multiplechoiceoptions))
|
||||
to_chat(usr, "<span class='warning'>You already have more than [multiplechoiceoptions] logged votes on this poll. Enough is enough. Contact the database admin if this is an error.</span>")
|
||||
return
|
||||
|
||||
var/adminrank = "Player"
|
||||
if(usr && usr.client && usr.client.holder)
|
||||
adminrank = usr.client.holder.rank
|
||||
|
||||
|
||||
var/DBQuery/insert_query = GLOB.dbcon.NewQuery("INSERT INTO [format_table_name("poll_vote")] (id ,datetime ,pollid ,optionid ,ckey ,ip ,adminrank) VALUES (null, Now(), [pollid], [optionid], '[ckey]', '[usr.client.address]', '[adminrank]')")
|
||||
insert_query.Execute()
|
||||
|
||||
to_chat(usr, "<span class='notice'>Vote successful.</span>")
|
||||
usr << browse(null,"window=playerpoll")
|
||||
|
||||
|
||||
/client/proc/log_text_poll_reply(var/pollid = -1, var/replytext = "")
|
||||
if(pollid == -1 || replytext == "")
|
||||
return
|
||||
|
||||
if(!isnum(pollid) || !istext(replytext))
|
||||
return
|
||||
establish_db_connection()
|
||||
if(GLOB.dbcon.IsConnected())
|
||||
|
||||
var/DBQuery/select_query = GLOB.dbcon.NewQuery("SELECT starttime, endtime, question, polltype FROM [format_table_name("poll_question")] WHERE id = [pollid] AND Now() BETWEEN starttime AND endtime [holder ? "AND adminonly = 0" : ""]")
|
||||
select_query.Execute()
|
||||
|
||||
var/validpoll = 0
|
||||
|
||||
while(select_query.NextRow())
|
||||
if(select_query.item[4] != POLLTYPE_TEXT)
|
||||
return
|
||||
validpoll = 1
|
||||
break
|
||||
|
||||
if(!validpoll)
|
||||
to_chat(usr, "<span class='warning'>Poll is not valid.</span>")
|
||||
return
|
||||
|
||||
var/alreadyvoted = 0
|
||||
|
||||
var/DBQuery/voted_query = GLOB.dbcon.NewQuery("SELECT id FROM [format_table_name("poll_textreply")] WHERE pollid = [pollid] AND ckey = '[ckey]'")
|
||||
voted_query.Execute()
|
||||
|
||||
while(voted_query.NextRow())
|
||||
alreadyvoted = 1
|
||||
break
|
||||
|
||||
if(alreadyvoted)
|
||||
to_chat(usr, "<span class='warning'>You already sent your feedback for this poll.</span>")
|
||||
return
|
||||
|
||||
var/adminrank = "Player"
|
||||
if(usr && usr.client && usr.client.holder)
|
||||
adminrank = usr.client.holder.rank
|
||||
|
||||
|
||||
replytext = replacetext(replytext, "%BR%", "")
|
||||
replytext = replacetext(replytext, "\n", "%BR%")
|
||||
var/text_pass = reject_bad_text(replytext,8000)
|
||||
replytext = replacetext(replytext, "%BR%", "<BR>")
|
||||
|
||||
if(!text_pass)
|
||||
to_chat(usr, "The text you entered was blank, contained illegal characters or was too long. Please correct the text and submit again.")
|
||||
return
|
||||
|
||||
var/DBQuery/insert_query = GLOB.dbcon.NewQuery("INSERT INTO [format_table_name("poll_textreply")] (id ,datetime ,pollid ,ckey ,ip ,replytext ,adminrank) VALUES (null, Now(), [pollid], '[ckey]', '[usr.client.address]', '[replytext]', '[adminrank]')")
|
||||
insert_query.Execute()
|
||||
|
||||
to_chat(usr, "<span class='notice'>Feedback logging successful.</span>")
|
||||
usr << browse(null,"window=playerpoll")
|
||||
|
||||
|
||||
/client/proc/vote_on_numval_poll(var/pollid = -1, var/optionid = -1, var/rating = null)
|
||||
if(pollid == -1 || optionid == -1)
|
||||
return
|
||||
|
||||
if(!isnum(pollid) || !isnum(optionid))
|
||||
return
|
||||
establish_db_connection()
|
||||
if(GLOB.dbcon.IsConnected())
|
||||
|
||||
var/DBQuery/select_query = GLOB.dbcon.NewQuery("SELECT starttime, endtime, question, polltype FROM [format_table_name("poll_question")] WHERE id = [pollid] AND Now() BETWEEN starttime AND endtime [holder ? "AND adminonly = 0" : ""]")
|
||||
select_query.Execute()
|
||||
|
||||
var/validpoll = 0
|
||||
|
||||
while(select_query.NextRow())
|
||||
if(select_query.item[4] != POLLTYPE_RATING)
|
||||
return
|
||||
validpoll = 1
|
||||
break
|
||||
|
||||
if(!validpoll)
|
||||
to_chat(usr, "<span class='warning'>Poll is not valid.</span>")
|
||||
return
|
||||
|
||||
var/DBQuery/select_query2 = GLOB.dbcon.NewQuery("SELECT id FROM [format_table_name("poll_option")] WHERE id = [optionid] AND pollid = [pollid]")
|
||||
select_query2.Execute()
|
||||
|
||||
var/validoption = 0
|
||||
|
||||
while(select_query2.NextRow())
|
||||
validoption = 1
|
||||
break
|
||||
|
||||
if(!validoption)
|
||||
to_chat(usr, "<span class='warning'>Poll option is not valid.</span>")
|
||||
return
|
||||
|
||||
var/alreadyvoted = 0
|
||||
|
||||
var/DBQuery/voted_query = GLOB.dbcon.NewQuery("SELECT id FROM [format_table_name("poll_vote")] WHERE optionid = [optionid] AND ckey = '[ckey]'")
|
||||
voted_query.Execute()
|
||||
|
||||
while(voted_query.NextRow())
|
||||
alreadyvoted = 1
|
||||
break
|
||||
|
||||
if(alreadyvoted)
|
||||
to_chat(usr, "<span class='warning'>You already voted in this poll.</span>")
|
||||
return
|
||||
|
||||
var/adminrank = "Player"
|
||||
if(usr && usr.client && usr.client.holder)
|
||||
adminrank = usr.client.holder.rank
|
||||
|
||||
|
||||
var/DBQuery/insert_query = GLOB.dbcon.NewQuery("INSERT INTO [format_table_name("poll_vote")] (id ,datetime ,pollid ,optionid ,ckey ,ip ,adminrank, rating) VALUES (null, Now(), [pollid], [optionid], '[ckey]', '[usr.client.address]', '[adminrank]', [(isnull(rating)) ? "null" : rating])")
|
||||
insert_query.Execute()
|
||||
|
||||
to_chat(usr, "<span class='notice'>Vote successful.</span>")
|
||||
usr << browse(null,"window=playerpoll")
|
||||
@@ -315,23 +315,36 @@ GLOBAL_DATUM(blackbox, /obj/machinery/blackbox_recorder)
|
||||
if(!feedback) return
|
||||
|
||||
round_end_data_gathering() //round_end time logging and some other data processing
|
||||
establish_db_connection()
|
||||
if(!GLOB.dbcon.IsConnected()) return
|
||||
|
||||
if(!SSdbcore.IsConnected())
|
||||
return
|
||||
var/round_id
|
||||
|
||||
var/DBQuery/query = GLOB.dbcon.NewQuery("SELECT MAX(round_id) AS round_id FROM [format_table_name("feedback")]")
|
||||
query.Execute()
|
||||
while(query.NextRow())
|
||||
round_id = query.item[1]
|
||||
var/datum/db_query/query_roundid = SSdbcore.NewQuery("SELECT MAX(round_id) AS round_id FROM [format_table_name("feedback")]")
|
||||
if(!query_roundid.warn_execute())
|
||||
qdel(query_roundid)
|
||||
return
|
||||
while(query_roundid.NextRow())
|
||||
round_id = query_roundid.item[1]
|
||||
|
||||
if(!isnum(round_id))
|
||||
round_id = text2num(round_id)
|
||||
round_id++
|
||||
|
||||
qdel(query_roundid)
|
||||
|
||||
for(var/datum/feedback_variable/FV in feedback)
|
||||
var/sql = "INSERT INTO [format_table_name("feedback")] VALUES (null, Now(), [round_id], \"[FV.get_variable()]\", [FV.get_value()], \"[FV.get_details()]\")"
|
||||
var/DBQuery/query_insert = GLOB.dbcon.NewQuery(sql)
|
||||
query_insert.Execute()
|
||||
var/sql = "INSERT INTO [format_table_name("feedback")] VALUES (null, Now(), :rid, :var, :val, :details)"
|
||||
var/datum/db_query/query_insert = SSdbcore.NewQuery(sql, list(
|
||||
"rid" = text2num(round_id),
|
||||
"var" = FV.get_variable(),
|
||||
"val" = FV.get_value(),
|
||||
"details" = FV.get_details()
|
||||
))
|
||||
if(!query_insert.warn_execute())
|
||||
qdel(query_insert)
|
||||
return
|
||||
qdel(query_insert)
|
||||
|
||||
/obj/machinery/blackbox_recorder/vv_edit_var(var_name, var_value)
|
||||
return FALSE // don't fuck with the stupid blackbox shit
|
||||
@@ -345,8 +358,6 @@ GLOBAL_DATUM(blackbox, /obj/machinery/blackbox_recorder)
|
||||
return
|
||||
if(!GLOB.blackbox) return
|
||||
|
||||
variable = sanitizeSQL(variable)
|
||||
|
||||
var/datum/feedback_variable/FV = GLOB.blackbox.find_feedback_datum(variable)
|
||||
|
||||
if(!FV) return
|
||||
@@ -361,8 +372,6 @@ GLOBAL_DATUM(blackbox, /obj/machinery/blackbox_recorder)
|
||||
return
|
||||
if(!GLOB.blackbox) return
|
||||
|
||||
variable = sanitizeSQL(variable)
|
||||
|
||||
var/datum/feedback_variable/FV = GLOB.blackbox.find_feedback_datum(variable)
|
||||
|
||||
if(!FV) return
|
||||
@@ -377,8 +386,6 @@ GLOBAL_DATUM(blackbox, /obj/machinery/blackbox_recorder)
|
||||
return
|
||||
if(!GLOB.blackbox) return
|
||||
|
||||
variable = sanitizeSQL(variable)
|
||||
|
||||
var/datum/feedback_variable/FV = GLOB.blackbox.find_feedback_datum(variable)
|
||||
|
||||
if(!FV) return
|
||||
@@ -393,9 +400,6 @@ GLOBAL_DATUM(blackbox, /obj/machinery/blackbox_recorder)
|
||||
return
|
||||
if(!GLOB.blackbox) return
|
||||
|
||||
variable = sanitizeSQL(variable)
|
||||
details = sanitizeSQL(details)
|
||||
|
||||
var/datum/feedback_variable/FV = GLOB.blackbox.find_feedback_datum(variable)
|
||||
|
||||
if(!FV) return
|
||||
@@ -410,9 +414,6 @@ GLOBAL_DATUM(blackbox, /obj/machinery/blackbox_recorder)
|
||||
return
|
||||
if(!GLOB.blackbox) return
|
||||
|
||||
variable = sanitizeSQL(variable)
|
||||
details = sanitizeSQL(details)
|
||||
|
||||
var/datum/feedback_variable/FV = GLOB.blackbox.find_feedback_datum(variable)
|
||||
|
||||
if(!FV) return
|
||||
|
||||
@@ -39,4 +39,7 @@
|
||||
if(example_db_version != SQL_VERSION)
|
||||
Fail("SQL version error: Game is running V[SQL_VERSION] but config/example/dbconfig.txt is V[example_db_version].")
|
||||
|
||||
if(SSdbcore.total_errors > 0)
|
||||
Fail("SQL errors occured on startup. Please fix them.")
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user