diff --git a/SQL/database_changelog.txt b/SQL/database_changelog.txt index e75ec546930..9a56620e157 100644 --- a/SQL/database_changelog.txt +++ b/SQL/database_changelog.txt @@ -1,3 +1,15 @@ +19 July 2015, by Jordie0608 + +Added new table 'memo' for use with admin memos. + +To create this new table run the following command: + +CREATE TABLE `memo` (`id` int(11) NOT NULL AUTO_INCREMENT, `ckey` varchar(32) NOT NULL, `memotext` text NOT NULL, `timestamp` datetime NOT NULL, `last_editor` varchar(32), `edits` text, PRIMARY KEY (`id`)) + +Remember to add prefix to the table name if you use them. + +---------------------------------------------------- + 7 July 2015, by MrStonedOne Removed the privacy poll and related table. Existing codebases may safely delete the privacy table after updating: diff --git a/SQL/tgstation_schema.sql b/SQL/tgstation_schema.sql index bfac8fd54d0..b6797101692 100644 --- a/SQL/tgstation_schema.sql +++ b/SQL/tgstation_schema.sql @@ -321,4 +321,23 @@ CREATE TABLE `watch` ( ) ENGINE=InnoDB DEFAULT CHARSET=latin1; /*!40101 SET character_set_client = @saved_cs_client */; +-- +-- Table structure for table `memo` +-- + +DROP TABLE IF EXISTS `memo`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `memo` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `ckey` varchar(32) NOT NULL, + `memotext` text NOT NULL, + `timestamp` datetime NOT NULL, + `last_editor` varchar(32), + `edits` text, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1; +/*!40101 SET character_set_client = @saved_cs_client */; + + -- Dump completed on 2013-03-24 18:02:35 diff --git a/SQL/tgstation_schema_prefixed.sql b/SQL/tgstation_schema_prefixed.sql index 9724a3edd68..70e02e2c304 100644 --- a/SQL/tgstation_schema_prefixed.sql +++ b/SQL/tgstation_schema_prefixed.sql @@ -316,4 +316,23 @@ CREATE TABLE `SS13_watch` ( ) ENGINE=InnoDB DEFAULT CHARSET=latin1; /*!40101 SET character_set_client = @saved_cs_client */; +-- +-- Table structure for table `SS13_memo` +-- + +DROP TABLE IF EXISTS `SS13_memo`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `SS13_memo` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `ckey` varchar(32) NOT NULL, + `memotext` text NOT NULL, + `timestamp` datetime NOT NULL, + `last_editor` varchar(32), + `edits` text, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1; +/*!40101 SET character_set_client = @saved_cs_client */; + + -- Dump completed on 2013-03-24 18:02:35 diff --git a/code/__HELPERS/time.dm b/code/__HELPERS/time.dm index c297d043a30..d3f9b6c1868 100644 --- a/code/__HELPERS/time.dm +++ b/code/__HELPERS/time.dm @@ -33,3 +33,7 @@ proc/time_stamp() // Uncomment this out when debugging! //else //return 1 + +//returns time in a sql and ISO 8601 friendly format +/proc/SQLtime() + return time2text(world.realtime, "YYYY-MM-DD hh:mm:ss") \ No newline at end of file diff --git a/code/modules/admin/admin_memo.dm b/code/modules/admin/admin_memo.dm index 89f9116aeaf..64ede615a6c 100644 --- a/code/modules/admin/admin_memo.dm +++ b/code/modules/admin/admin_memo.dm @@ -1,58 +1,92 @@ -#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(task in list("Show","Write","Edit","Remove")) set name = "Memo" set category = "Server" - if(!ENABLE_MEMOS) return if(!check_rights(0)) return + if(!dbcon.IsConnected()) + usr << "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/memotext = input(src,"Write your Memo","Memo") as text|null + if(!memotext) return - if("") - message_admins("[src.ckey] removed their own Memo") - log_admin("[src.ckey] removed their own Memo") - F.dir.Remove(ckey) + 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 - if( findtext(memo,"[memo]" - message_admins("[key] set an admin memo:
[memo]") - log_admin("[key] 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) - message_admins("[src.ckey] removed [ckey]'s Memo.") - log_admin("[src.ckey] removed Memo created by [ckey].") - for(var/memo in F.dir) - F.dir.Remove(ckey) - -#undef MEMOFILE -#undef ENABLE_MEMOS + 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")])") //should select all memos there are + query_memolist.Execute() + var/list/memolist = list() + while(query_memolist.NextRow()) + var/ckey = query_memolist.item[2] + memolist += "[ckey]" + 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 ckey, memotext FROM [format_table_name("memo")] WHERE (ckey = '[target_sql_ckey]')") + query_memofind.Execute() + if(query_memofind.NextRow()) + var/old_memo = query_memofind.item[3] + var/new_memo = input("Input new memo", "New Memo", "[old_memo]", null) as null|text + 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(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 id, ckey, memotext, timestamp, last_editor FROM [format_table_name("memo")])") + while(query_memoshow.NextRow()) + var/output + var/id = query_memoshow.item[1] + var/ckey = query_memoshow.item[2] + var/memotext = query_memoshow.item[3] + var/timestamp = query_memoshow.item[4] + var/last_editor = query_memoshow.item[5] + output += "Memo by [ckey] on [timestamp]:" + if(last_editor) + output += "
Last edit by [last_editor] (Click here to see edit log)" + output += "
[memotext]
" + src << output + if("Remove") + var/DBQuery/query_memolist = dbcon.NewQuery("SELECT ckey FROM [format_table_name("memo")])") //should select all memos there are + query_memolist.Execute() + if(!query_memolist.NextRow()) + src << "No memos found in database." + return + var/target_ckey = input(src, "Select whose memo to delete", "Select memo") as null|anything in query_memolist //does this work? it's not initialized as an actual list + 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 062cc7f9378..969c95dd758 100644 --- a/code/modules/admin/topic.dm +++ b/code/modules/admin/topic.dm @@ -2056,3 +2056,10 @@ var/datum/newscaster/feed_message/FM = locate(href_list["ac_lock_comment"]) FM.locked ^= 1 src.access_news_network() + + else if(href_list["memoeditlist"]) + var/DBQuery/query_memoedits = dbcon.NewQuery("SELECT edits FROM [format_table_name("memo")] WHERE (id = '[href_list["id"]]") + query_memoedits.Execute() + if(query_memoedits.NextRow()) + var/edit_log = query_memoedits.item[6] + usr << browse(edit_log,"window=memoeditlist") \ No newline at end of file diff --git a/code/modules/client/client procs.dm b/code/modules/client/client procs.dm index c574816af2a..4e07e0d8a3c 100644 --- a/code/modules/client/client procs.dm +++ b/code/modules/client/client procs.dm @@ -128,7 +128,7 @@ var/next_external_rsc = 0 if(holder) add_admin_verbs() - admin_memo_show() + admin_memo("Show") if((global.comms_key == "default_pwd" || length(global.comms_key) <= 6) && global.comms_allowed) //It's the default value or less than 6 characters long, but it somehow didn't disable comms. src << "The server's API key is either too short or is the default value! Consider changing it immediately!" diff --git a/interface/stylesheet.dm b/interface/stylesheet.dm index 4c480642b46..800beb52069 100644 --- a/interface/stylesheet.dm +++ b/interface/stylesheet.dm @@ -84,4 +84,7 @@ h1.alert, h2.alert {color: #000000;} BIG IMG.icon {width: 32px; height: 32px;} +.memo {color: #638500; text-align: center;} +.memoedit {text-align: center; font-size: 2;} + "}