diff --git a/SQL/paradise_schema.sql b/SQL/paradise_schema.sql index eccd2190793..deb2ae8d7f9 100644 --- a/SQL/paradise_schema.sql +++ b/SQL/paradise_schema.sql @@ -478,3 +478,20 @@ CREATE TABLE `erro_notes` ( PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1; /*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `memo` +-- + +DROP TABLE IF EXISTS `erro_memo`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `erro_memo` ( + `ckey` varchar(32) NOT NULL, + `memotext` text NOT NULL, + `timestamp` datetime NOT NULL, + `last_editor` varchar(32), + `edits` text, + PRIMARY KEY (`ckey`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1; +/*!40101 SET character_set_client = @saved_cs_client */; diff --git a/code/modules/admin/admin_memo.dm b/code/modules/admin/admin_memo.dm index 4a5f2eac73a..03fc3767b8e 100644 --- a/code/modules/admin/admin_memo.dm +++ b/code/modules/admin/admin_memo.dm @@ -1,55 +1,134 @@ -#define MEMOFILE "data/memo.sav" //where the memos are saved -#define ENABLE_MEMOS 1 //using a define because screw making a config variable for it. This is more efficient and purty. - -//switch verb so we don't spam up the verb lists with like, 3 verbs for this feature. -/client/proc/admin_memo(task in list("write","show","delete")) +/client/proc/admin_memo() set name = "Memo" set category = "Server" - if(!ENABLE_MEMOS) return - if(!check_rights(0)) return + if(!check_rights(R_SERVER)) + return + if(!dbcon.IsConnected()) + src << "Failed to establish database connection." + return + var/memotask = input(usr,"Choose task.","Memo") in list("Show","Write","Edit","Remove") + if(!memotask) + return + admin_memo_output(memotask) + +/client/proc/admin_memo_output(task, checkrights = 1) + if(checkrights && !check_rights(R_SERVER)) + return + if(!task) + return + if(!dbcon.IsConnected()) + src << "Failed to establish database connection." + return + var/sql_ckey = sanitizeSQL(src.ckey) switch(task) - if("write") admin_memo_write() - if("show") admin_memo_show() - if("delete") admin_memo_delete() - -//write a message -/client/proc/admin_memo_write() - var/savefile/F = new(MEMOFILE) - if(F) - var/memo = input(src,"Type your memo\n(Leaving it blank will delete your current memo):","Write Memo",null) as null|message - switch(memo) - if(null) + if("Write") + var/DBQuery/query_memocheck = 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") return - if("") - F.dir.Remove(ckey) - src << "Memo removed" + if(query_memocheck.NextRow()) + src << "You already have set a memo." return - if( findtext(memo,"[memo]" - log_admin("[key_name(usr)] set an admin memo:
[memo]") - message_admins("[key_name_admin(usr)] set an admin memo:
[memo]") - -//show all memos -/client/proc/admin_memo_show() - if(ENABLE_MEMOS) - var/savefile/F = new(MEMOFILE) - if(F) - for(var/ckey in F.dir) - src << "
Admin Memo by [F[ckey]]
" - -//delete your own or somebody else's memo -/client/proc/admin_memo_delete() - var/savefile/F = new(MEMOFILE) - if(F) - var/ckey - if(check_rights(R_SERVER,0)) //high ranking admins can delete other admin's memos - ckey = input(src,"Whose memo shall we remove?","Remove Memo",null) as null|anything in F.dir - else - ckey = src.ckey - if(ckey) - F.dir.Remove(ckey) - src << "Removed Memo created by [ckey]." - -#undef MEMOFILE -#undef ENABLE_MEMOS \ No newline at end of file + var/memotext = input(src,"Write your Memo","Memo") as message + if(!memotext) + return + memotext = sanitizeSQL(memotext) + var/timestamp = SQLtime() + var/DBQuery/query_memoadd = 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") + return + log_admin("[key_name(src)] has set a memo: [memotext]") + message_admins("[key_name_admin(src)] has set a memo:
[memotext]") + if("Edit") + var/DBQuery/query_memolist = 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") + return + var/list/memolist = list() + while(query_memolist.NextRow()) + var/lkey = query_memolist.item[1] + memolist += "[lkey]" + if(!memolist.len) + 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 = 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") + 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) + return + new_memo = sanitizeSQL(new_memo) + var/edit_text = "Edited by [sql_ckey] on [SQLtime()] from
[old_memo]
to
[new_memo]
" + edit_text = sanitizeSQL(edit_text) + var/DBQuery/update_query = 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") + return + if(target_sql_ckey == sql_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]\"") + if("Show") + var/DBQuery/query_memoshow = 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") + return + var/output = null + while(query_memoshow.NextRow()) + var/ckey = query_memoshow.item[1] + var/memotext = query_memoshow.item[2] + var/timestamp = query_memoshow.item[3] + var/last_editor = query_memoshow.item[4] + output += "Memo by [ckey] on [timestamp]" + if(last_editor) + output += "
Last edit by [last_editor] (Click here to see edit log)" + output += "
[memotext]

" + if(!output) + src << "No memos found in database." + return + src << output + if("Remove") + var/DBQuery/query_memodellist = 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") + return + var/list/memolist = list() + while(query_memodellist.NextRow()) + var/ckey = query_memodellist.item[1] + memolist += "[ckey]" + if(!memolist.len) + 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 = 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") + return + if(target_sql_ckey == sql_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.") + \ No newline at end of file diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm index c48041774bd..cec4950a942 100644 --- a/code/modules/admin/topic.dm +++ b/code/modules/admin/topic.dm @@ -2157,6 +2157,18 @@ log_admin("[key_name(usr)] has kicked [afkonly ? "all AFK" : "all"] clients from the lobby. [length(listkicked)] clients kicked: [strkicked ? strkicked : "--"]") else usr << "You may only use this when the game is running." + + else if(href_list["memoeditlist"]) + if(!check_rights(R_SERVER)) return + var/sql_key = sanitizeSQL("[href_list["memoeditlist"]]") + var/DBQuery/query_memoedits = 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") + return + if(query_memoedits.NextRow()) + var/edit_log = query_memoedits.item[1] + usr << browse(edit_log,"window=memoeditlist") else if(href_list["secretsfun"]) if(!check_rights(R_SERVER|R_EVENT)) return diff --git a/code/modules/client/client procs.dm b/code/modules/client/client procs.dm index a66b3c3698b..5212d6e84e8 100644 --- a/code/modules/client/client procs.dm +++ b/code/modules/client/client procs.dm @@ -272,7 +272,7 @@ if(holder) add_admin_verbs() - admin_memo_show() + admin_memo_output("Show", 0) // 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) diff --git a/code/stylesheet.dm b/code/stylesheet.dm index 6cd6c266e5e..6cbe8200766 100644 --- a/code/stylesheet.dm +++ b/code/stylesheet.dm @@ -99,6 +99,9 @@ h1.alert, h2.alert {color: #000000;} .greentext {color: #00FF00; font-size: 3;} .redtext {color: #FF0000; font-size: 3;} +.memo {color: #638500; text-align: center;} +.memoedit {text-align: center; font-size: 2;} + BIG IMG.icon {width: 32px; height: 32px;} "}