diff --git a/baystation12.dme b/baystation12.dme index aede49368ad..7b37efa3483 100644 --- a/baystation12.dme +++ b/baystation12.dme @@ -1715,6 +1715,7 @@ #include "code\modules\virus2\helpers.dm" #include "code\modules\virus2\isolator.dm" #include "code\modules\virus2\items_devices.dm" +#include "code\modules\web_interface\webint_procs.dm" #include "code\TriDimension\controller.dm" #include "code\TriDimension\controller_presets.dm" #include "code\TriDimension\Movement.dm" diff --git a/code/controllers/configuration.dm b/code/controllers/configuration.dm index 4b00ae7af1c..ec7719154c9 100644 --- a/code/controllers/configuration.dm +++ b/code/controllers/configuration.dm @@ -209,6 +209,9 @@ var/list/gamemode_cache = list() var/aggressive_changelog = 0 + //Web interface settings + var/webint_url = "" + /datum/configuration/New() var/list/L = typesof(/datum/game_mode) - /datum/game_mode for (var/T in L) @@ -278,7 +281,7 @@ var/list/gamemode_cache = list() config.log_access = 1 if ("sql_enabled") - config.sql_enabled = text2num(value) + config.sql_enabled = 1 if ("log_say") config.log_say = 1 @@ -678,6 +681,9 @@ var/list/gamemode_cache = list() if("show_auxiliary_roles") config.show_auxiliary_roles = 1 + if("webint_url") + config.webint_url = value + else log_misc("Unknown setting in configuration: '[name]'") @@ -741,88 +747,6 @@ var/list/gamemode_cache = list() else log_misc("Unknown setting in configuration: '[name]'") -/datum/configuration/proc/loadsql(filename) // -- TLE - var/list/Lines = file2list(filename) - for(var/t in Lines) - if(!t) continue - - t = trim(t) - if (length(t) == 0) - continue - else if (copytext(t, 1, 2) == "#") - continue - - var/pos = findtext(t, " ") - var/name = null - var/value = null - - if (pos) - name = lowertext(copytext(t, 1, pos)) - value = copytext(t, pos + 1) - else - name = lowertext(t) - - if (!name) - continue - - switch (name) - if ("address") - sqladdress = value - if ("port") - sqlport = value - if ("database") - sqldb = value - if ("login") - sqllogin = value - if ("password") - sqlpass = value - if ("enable_stat_tracking") - sqllogging = 1 - else - log_misc("Unknown setting in configuration: '[name]'") - -/datum/configuration/proc/loadforumsql(filename) // -- TLE - var/list/Lines = file2list(filename) - for(var/t in Lines) - if(!t) continue - - t = trim(t) - if (length(t) == 0) - continue - else if (copytext(t, 1, 2) == "#") - continue - - var/pos = findtext(t, " ") - var/name = null - var/value = null - - if (pos) - name = lowertext(copytext(t, 1, pos)) - value = copytext(t, pos + 1) - else - name = lowertext(t) - - if (!name) - continue - - switch (name) - if ("address") - forumsqladdress = value - if ("port") - forumsqlport = value - if ("database") - forumsqldb = value - if ("login") - forumsqllogin = value - if ("password") - forumsqlpass = value - if ("activatedgroup") - forum_activated_group = value - if ("authenticatedgroup") - forum_authenticated_group = value - else - log_misc("Unknown setting in configuration: '[name]'") - /datum/configuration/proc/pick_mode(mode_name) // I wish I didn't have to instance the game modes in order to look up // their information, but it is the only way (at least that I know of). diff --git a/code/controllers/news_controller.dm b/code/controllers/news_controller.dm index 1598fc8a226..f8d9ce3c808 100644 --- a/code/controllers/news_controller.dm +++ b/code/controllers/news_controller.dm @@ -27,7 +27,7 @@ var/global/datum/news_controller/news_controller //Stores a new article for publishing. /datum/news_controller/proc/update() - establish_db_connection() + establish_db_connection(dbcon) if(!dbcon.IsConnected()) error("SQL database connection failed. News_controller failed to retreive information.") fails++ @@ -52,7 +52,7 @@ var/global/datum/news_controller/news_controller //Publish the stored article. /datum/news_controller/proc/publish() - establish_db_connection() + establish_db_connection(dbcon) if(!dbcon.IsConnected()) error("SQL database connection failed. News_controller failed to retreive information.") fails++ diff --git a/code/defines/procs/dbcore.dm b/code/defines/procs/dbcore.dm index cd5f5dcdbd9..166896587cf 100644 --- a/code/defines/procs/dbcore.dm +++ b/code/defines/procs/dbcore.dm @@ -31,45 +31,47 @@ #define BLOB 14 // TODO: Investigate more recent type additions and see if I can handle them. - Nadrew - -// Deprecated! See global.dm for new configuration vars -/* -var/DB_SERVER = "" // This is the location of your MySQL server (localhost is USUALLY fine) -var/DB_PORT = 3306 // This is the port your MySQL server is running on (3306 is the default) -*/ - DBConnection var/_db_con // This variable contains a reference to the actual database connection. - var/dbi // This variable is a string containing the DBI MySQL requires. - var/user // This variable contains the username data. - var/password // This variable contains the password data. - var/default_cursor // This contains the default database cursor data. - // - var/server = "" - var/port = 3306 + var/con_dbi // This variable is a string containing the DBI MySQL requires. + var/con_user // This variable contains the username data. + var/con_password // This variable contains the password data. + var/con_cursor // This contains the default database cursor data. + var/con_server = "" + var/con_port = 3306 + var/con_database = "" + var/failed_connections = 0 + +DBConnection/New(server, port = 3306, database, username, password_handler, cursor_handler = Default_Cursor, dbi_handler) + con_user = username + con_password = password_handler + con_cursor = cursor_handler + con_server = server + con_port = port + con_database = database + + if (dbi_handler) + con_dbi = dbi_handler + else + con_dbi = "dbi:mysql:[database]:[server]:[port]" -DBConnection/New(dbi_handler, username, password_handler, cursor_handler) - dbi = dbi_handler - user = username - password = password_handler - default_cursor = cursor_handler _db_con = _dm_db_new_con() -DBConnection/proc/Connect(dbi_handler = dbi, user_handler = user, password_handler = password, cursor_handler) - if (!sqllogging) +DBConnection/proc/Connect(dbi_handler = con_dbi, user_handler = con_user, password_handler = con_password, cursor_handler) + if (!config.sql_enabled) return 0 if (!src) return 0 - cursor_handler = default_cursor + cursor_handler = con_cursor if (!cursor_handler) cursor_handler = Default_Cursor - return _dm_db_connect(_db_con,dbi_handler, user_handler, password_handler, cursor_handler, null) + return _dm_db_connect(_db_con, dbi_handler, user_handler, password_handler, cursor_handler, null) DBConnection/proc/Disconnect() return _dm_db_close(_db_con) DBConnection/proc/IsConnected() - if(!sqllogging) + if(!config.sql_enabled) return 0 var/success = _dm_db_is_connected(_db_con) return success @@ -80,12 +82,13 @@ DBConnection/proc/Quote(str) DBConnection/proc/ErrorMsg() return _dm_db_error_msg(_db_con) -DBConnection/proc/SelectDB(database_name,dbi) - if(IsConnected()) Disconnect() - //return Connect("[dbi?"[dbi]":"dbi:mysql:[database_name]:[DB_SERVER]:[DB_PORT]"]",user,password) - return Connect("[dbi?"[dbi]":"dbi:mysql:[database_name]:[sqladdress]:[sqlport]"]", user, password) +DBConnection/proc/SelectDB(database_name, new_dbi) + if (IsConnected()) + Disconnect() + con_database = database_name + return Connect(new_dbi ? new_dbi : "dbi:mysql:[database_name]:[con_server]:[con_port]", con_user, con_password) -DBConnection/proc/NewQuery(sql_query, cursor_handler = default_cursor) +DBConnection/proc/NewQuery(sql_query, cursor_handler = con_cursor) return new/DBQuery(sql_query, src, cursor_handler) DBQuery @@ -194,12 +197,12 @@ DBQuery/proc/parseArguments(var/query_to_parse = null, var/list/argument_list, v var/argument = argument_list[placeholder] - if (isnull(argument)) - argument = "NULL" - else if (istext(argument)) + if (istext(argument)) argument = dbcon.Quote(argument) else if (isnum(argument)) - argument = "'[argument]'" + argument = "[argument]" + else if (isnull(argument)) + argument = "NULL" else log_debug("parseArguments() failed! Cannot identify argument!") return 0 diff --git a/code/defines/procs/statistics.dm b/code/defines/procs/statistics.dm index 01c97f4fcfc..e807e4cbbce 100644 --- a/code/defines/procs/statistics.dm +++ b/code/defines/procs/statistics.dm @@ -1,12 +1,12 @@ proc/sql_poll_population() - if(!sqllogging) + if(!config.sql_enabled) return var/admincount = admins.len var/playercount = 0 for(var/mob/M in player_list) if(M.client) playercount += 1 - establish_db_connection() + establish_db_connection(dbcon) if(!dbcon.IsConnected()) log_game("SQL ERROR during population polling. Failed to connect.") else @@ -18,15 +18,15 @@ proc/sql_poll_population() proc/sql_report_round_start() // TODO - if(!sqllogging) + if(!config.sql_enabled) return proc/sql_report_round_end() // TODO - if(!sqllogging) + if(!config.sql_enabled) return proc/sql_report_death(var/mob/living/carbon/human/H) - if(!sqllogging) + if(!config.sql_enabled) return if(!H) return @@ -49,7 +49,7 @@ proc/sql_report_death(var/mob/living/carbon/human/H) var/sqltime = time2text(world.realtime, "YYYY-MM-DD hh:mm:ss") var/coord = "[H.x], [H.y], [H.z]" //world << "INSERT INTO death (name, byondkey, job, special, pod, tod, laname, lakey, gender, bruteloss, fireloss, brainloss, oxyloss) VALUES ('[sqlname]', '[sqlkey]', '[sqljob]', '[sqlspecial]', '[sqlpod]', '[sqltime]', '[laname]', '[lakey]', '[H.gender]', [H.bruteloss], [H.getFireLoss()], [H.brainloss], [H.getOxyLoss()])" - establish_db_connection() + establish_db_connection(dbcon) if(!dbcon.IsConnected()) log_game("SQL ERROR during death reporting. Failed to connect.") else @@ -60,7 +60,7 @@ proc/sql_report_death(var/mob/living/carbon/human/H) proc/sql_report_cyborg_death(var/mob/living/silicon/robot/H) - if(!sqllogging) + if(!config.sql_enabled) return if(!H) return @@ -83,7 +83,7 @@ proc/sql_report_cyborg_death(var/mob/living/silicon/robot/H) var/sqltime = time2text(world.realtime, "YYYY-MM-DD hh:mm:ss") var/coord = "[H.x], [H.y], [H.z]" //world << "INSERT INTO death (name, byondkey, job, special, pod, tod, laname, lakey, gender, bruteloss, fireloss, brainloss, oxyloss) VALUES ('[sqlname]', '[sqlkey]', '[sqljob]', '[sqlspecial]', '[sqlpod]', '[sqltime]', '[laname]', '[lakey]', '[H.gender]', [H.bruteloss], [H.getFireLoss()], [H.brainloss], [H.getOxyLoss()])" - establish_db_connection() + establish_db_connection(dbcon) if(!dbcon.IsConnected()) log_game("SQL ERROR during death reporting. Failed to connect.") else @@ -94,7 +94,7 @@ proc/sql_report_cyborg_death(var/mob/living/silicon/robot/H) proc/statistic_cycle() - if(!sqllogging) + if(!config.sql_enabled) return while(1) sql_poll_population() @@ -113,7 +113,7 @@ proc/sql_commit_feedback() log_game("Round ended without any feedback being generated. No feedback was sent to the database.") return - establish_db_connection() + establish_db_connection(dbcon) if(!dbcon.IsConnected()) log_game("SQL ERROR during feedback reporting. Failed to connect.") else diff --git a/code/game/antagonist/outsider/raider.dm b/code/game/antagonist/outsider/raider.dm index fcb0e1d2b73..1e4a481e4dc 100644 --- a/code/game/antagonist/outsider/raider.dm +++ b/code/game/antagonist/outsider/raider.dm @@ -220,6 +220,11 @@ var/datum/antagonist/raider/raiders player.equip_to_slot_or_del(new new_suit(player),slot_wear_suit) equip_weapons(player) + //Try to equip it, del if we fail. + var/obj/item/device/contract_uplink/new_uplink = new() + if (!player.equip_to_appropriate_slot(new_uplink)) + qdel(new_uplink) + var/obj/item/weapon/card/id/id = create_id("Visitor", player, equip = 0) id.name = "[player.real_name]'s Passport" id.assignment = "Visitor" @@ -311,4 +316,3 @@ var/datum/antagonist/raider/raiders player.internals.icon_state = "internal1" return 1 - diff --git a/code/game/jobs/whitelist.dm b/code/game/jobs/whitelist.dm index b6f16388be7..28b216654d3 100644 --- a/code/game/jobs/whitelist.dm +++ b/code/game/jobs/whitelist.dm @@ -9,7 +9,7 @@ var/list/whitelist = list() /proc/load_whitelist() if (config.sql_whitelists) - establish_db_connection() + establish_db_connection(dbcon) if (!dbcon.IsConnected()) //Continue with the old code if we have no database. @@ -43,7 +43,7 @@ var/list/whitelist = list() /proc/load_alienwhitelist() if (config.sql_whitelists) - establish_db_connection() + establish_db_connection(dbcon) if (!dbcon.IsConnected()) //Continue with the old code if we have no database. diff --git a/code/game/machinery/requests_console.dm b/code/game/machinery/requests_console.dm index d4beeb78ea1..c3f9ee71080 100644 --- a/code/game/machinery/requests_console.dm +++ b/code/game/machinery/requests_console.dm @@ -211,7 +211,7 @@ var/list/obj/machinery/requests_console/allConsoles = list() if(11) //form database dat += text("NanoTrasen Corporate Forms

") - establish_db_connection() + establish_db_connection(dbcon) if(!dbcon.IsConnected()) dat += text("ERROR: Unable to contact external database. Please contact your system administrator for assistance.") log_game("SQL database connection failed. Attempted to fetch form information.") @@ -377,7 +377,7 @@ var/list/obj/machinery/requests_console/allConsoles = list() if(href_list["print"]) var/printid = sanitizeSQL(href_list["print"]) - establish_db_connection() + establish_db_connection(dbcon) if(!dbcon.IsConnected()) alert("Connection to the database lost. Aborting.") @@ -405,7 +405,7 @@ var/list/obj/machinery/requests_console/allConsoles = list() if(href_list["whatis"]) var/whatisid = sanitizeSQL(href_list["whatis"]) - establish_db_connection() + establish_db_connection(dbcon) if(!dbcon.IsConnected()) alert("Connection to the database lost. Aborting.") if(!whatisid) diff --git a/code/game/objects/items/devices/scanners.dm b/code/game/objects/items/devices/scanners.dm index c0275461962..691f56de1b3 100644 --- a/code/game/objects/items/devices/scanners.dm +++ b/code/game/objects/items/devices/scanners.dm @@ -178,9 +178,9 @@ REAGENT SCANNER user.show_message(text("\red Warning: [D.form] Detected\nName: [D.name].\nType: [D.spread].\nStage: [D.stage]/[D.max_stages].\nPossible Cure: [D.cure]")) // if (M.reagents && M.reagents.get_reagent_amount("inaprovaline")) // user.show_message("\blue Bloodstream Analysis located [M.reagents:get_reagent_amount("inaprovaline")] units of rejuvenation chemicals.") - if (M.has_brain_worms()) - user.show_message("\red Subject suffering from aberrant brain activity. Recommend further scanning.") - else if (M.getBrainLoss() >= 100 || !M.has_brain()) +// if (M.has_brain_worms()) +// user.show_message("\red Subject suffering from aberrant brain activity. Recommend further scanning.") //Cortical borer disable + if (M.getBrainLoss() >= 100 || !M.has_brain()) user.show_message("\red Subject is brain dead.") else if (M.getBrainLoss() >= 60) user.show_message("\red Severe brain damage detected. Subject likely to have mental retardation.") diff --git a/code/game/objects/items/devices/uplinks.dm b/code/game/objects/items/devices/uplinks.dm index c8f23054e4d..2fbf1f99732 100644 --- a/code/game/objects/items/devices/uplinks.dm +++ b/code/game/objects/items/devices/uplinks.dm @@ -213,6 +213,9 @@ datum/nano_item_lists data["welcome"] = welcome data["crystals"] = uses data["menu"] = nanoui_menu + //Small hack for the contract_uplink device, to make sure the data is initialized properly. + if(nanoui_menu == 2) + update_nano_data() if(!nanoui_items) generate_items() data["nano_items"] = nanoui_items @@ -257,6 +260,16 @@ datum/nano_item_lists if(href_list["menu"]) nanoui_menu = text2num(href_list["menu"]) update_nano_data(href_list["id"]) + if(href_list["contract_interact"]) + var/list/params = list("location" = "contract_details", "contract" = href_list["contract_interact"]) + usr.client.process_webint_link("interface/login/sso_server", list2params(params)) + if(href_list["contract_page"]) + nanoui_data["contracts_current_page"] = text2num(href_list["contract_page"]) + update_nano_data() + if(href_list["contract_view"]) + nanoui_data["contracts_view"] = text2num(href_list["contract_view"]) + nanoui_data["contracts_current_page"] = 1 + update_nano_data() interact(usr) return 1 @@ -292,6 +305,108 @@ datum/nano_item_lists nanoui_data["exploit_exists"] = 1 break + if(nanoui_menu == 2) + nanoui_data["contracts_found"] = 0 + + establish_db_connection(dbcon) + + if (dbcon.IsConnected()) + nanoui_data["contracts"] = list() + + if (!nanoui_data["contracts_current_page"]) + nanoui_data["contracts_current_page"] = 1 + + if (!nanoui_data["contracts_view"]) + nanoui_data["contracts_view"] = 1 + + var/query_details[0] + + switch (nanoui_data["contracts_view"]) + if (1) + query_details[":status"] = "open" + if (2) + query_details[":status"] = "closed" + else + nanoui_data["contracts_view"] = 1 + query_details[":status"] = "open" + + var/DBQuery/index_query = dbcon.NewQuery("SELECT count(*) as Total_Contracts FROM ss13_syndie_contracts WHERE deleted_at IS NULL AND status = :status") + index_query.Execute(query_details) + + var/pages = 0 + + if (index_query.NextRow()) + var/total_contracts = text2num(index_query.item[1]) + + pages = total_contracts / 10 + + if (total_contracts % 10) + pages++ + + pages = round(pages) + + var/list/contracts_pages = list() + + for (var/i = 1, i <= pages, i++) + contracts_pages.Add(i) + + for (var/a in contracts_pages) + + nanoui_data["contracts_pages"] = contracts_pages + + if (nanoui_data["contracts_current_page"] > pages) + return + + query_details[":offset"] = (nanoui_data["contracts_current_page"] - 1) * 10 + + var/DBQuery/list_query = dbcon.NewQuery("SELECT contract_id, contractee_name, title FROM ss13_syndie_contracts WHERE deleted_at IS NULL AND status = :status LIMIT 10 OFFSET :offset") + list_query.Execute(query_details) + + var/list/contracts = list() + while (list_query.NextRow()) + contracts.Add(list(list("id" = list_query.item[1], + "contractee" = list_query.item[2], + "title" = list_query.item[3]))) + + nanoui_data["contracts"] = contracts + + nanoui_data["contracts_found"] = 1 + + if(nanoui_menu == 21) + nanoui_data["contracts_found"] = 0 + + establish_db_connection(dbcon) + + if (dbcon.IsConnected()) + var/query_details[0] + query_details[":contract_id"] = text2num(id) + + var/DBQuery/select_query = dbcon.NewQuery("SELECT contract_id, contractee_name, status, title, description, reward_other FROM ss13_syndie_contracts WHERE contract_id = :contract_id") + select_query.Execute(query_details) + + if (select_query.NextRow()) + nanoui_data["contracts_found"] = 1 + + var/contract[0] + contract["id"] = select_query.item[1] + contract["contractee"] = select_query.item[2] + + switch (select_query.item[3]) + if ("open") + contract["status"] = "1" + else + contract["status"] = "0" + + contract["title"] = html_encode(select_query.item[4]) + contract["description"] = select_query.item[5] + + contract["description"] = html_encode(contract["description"]) + contract["description"] = replacetext(contract["description"], "\n", "
") + contract["description"] = replacetext(contract["description"], ascii2text(13), "") + contract["reward_other"] = select_query.item[6] + + nanoui_data["contract"] = contract + // I placed this here because of how relevant it is. // You place this in your uplinkable item to check if an uplink is active or not. // If it is, it will display the uplink menu and return 1, else it'll return false. @@ -332,3 +447,25 @@ datum/nano_item_lists ..() hidden_uplink = new(src) hidden_uplink.uses = 10 + +/* + * A simple device for accessing the SQL based contract database + */ + +/obj/item/device/contract_uplink + name = "contract uplink" + desc = "A small device used for access restricted sites in the remote corners of the Extranet." + icon = 'icons/obj/radio.dmi' + icon_state = "radio" + flags = CONDUCT + w_class = 2 + +/obj/item/device/contract_uplink/New() + ..() + hidden_uplink = new(src) + hidden_uplink.uses = 0 + hidden_uplink.nanoui_menu = 2 + +/obj/item/device/contract_uplink/attack_self(mob/user as mob) + if (hidden_uplink) + hidden_uplink.trigger(user) diff --git a/code/global.dm b/code/global.dm index 626960698b1..ccb57713b0e 100644 --- a/code/global.dm +++ b/code/global.dm @@ -187,32 +187,14 @@ var/datum/subsystem/alarm/alarm_manager = new() // Alarm Manager, the manager fo var/list/awaydestinations = list() // Away missions. A list of landmarks that the warpgate can take you to. -// MySQL configuration -var/sqladdress = "localhost" -var/sqlport = "3306" -var/sqldb = "tgstation" -var/sqllogin = "root" -var/sqlpass = "" -var/sqllogging = 0 // Should we log deaths, population stats, etc.? - -// Forum MySQL configuration. (for use with forum account/key authentication) -// These are all default values that will load should the forumdbconfig.txt file fail to read for whatever reason. -var/forumsqladdress = "localhost" -var/forumsqlport = "3306" -var/forumsqldb = "tgstation" -var/forumsqllogin = "root" -var/forumsqlpass = "" -var/forum_activated_group = "2" -var/forum_authenticated_group = "10" - // For FTP requests. (i.e. downloading runtime logs.) // However it'd be ok to use for accessing attack logs and such too, which are even laggier. var/fileaccess_timer = 0 var/custom_event_msg = null -// Database connections. A connection is established on world creation. +// Database connections. A connection is established along with /hook/startup/proc/load_databases(). // Ideally, the connection dies when the server restarts (After feedback logging.). -var/DBConnection/dbcon = new() // Feedback database (New database) +var/DBConnection/dbcon // Reference list for disposal sort junctions. Filled up by sorting junction's New() /var/list/tagger_locations = list() diff --git a/code/modules/admin/DB ban/ban_mirroring.dm b/code/modules/admin/DB ban/ban_mirroring.dm index 588acbdfccb..d6af7bafbba 100644 --- a/code/modules/admin/DB ban/ban_mirroring.dm +++ b/code/modules/admin/DB ban/ban_mirroring.dm @@ -6,7 +6,7 @@ if (!ckey || !address || !computer_id || !ban_id) return - establish_db_connection() + establish_db_connection(dbcon) if (!dbcon.IsConnected()) error("Ban database connection failure while attempting to mirror. Key passed for mirror handling: [ckey].") diff --git a/code/modules/admin/DB ban/functions.dm b/code/modules/admin/DB ban/functions.dm index e36fc4ff21f..d266eaf7295 100644 --- a/code/modules/admin/DB ban/functions.dm +++ b/code/modules/admin/DB ban/functions.dm @@ -4,7 +4,7 @@ datum/admins/proc/DB_ban_record(var/bantype, var/mob/banned_mob, var/duration = if(!check_rights(R_MOD,0) && !check_rights(R_BAN)) return - establish_db_connection() + establish_db_connection(dbcon) if(!dbcon.IsConnected()) return @@ -122,7 +122,7 @@ datum/admins/proc/DB_ban_unban(var/ckey, var/bantype, var/job = "") if(job) sql += " AND job = '[job]'" - establish_db_connection() + establish_db_connection(dbcon) if(!dbcon.IsConnected()) return @@ -217,7 +217,7 @@ datum/admins/proc/DB_ban_unban_by_id(var/id) var/sql = "SELECT ckey FROM ss13_ban WHERE id = [id]" - establish_db_connection() + establish_db_connection(dbcon) if(!dbcon.IsConnected()) return @@ -269,7 +269,7 @@ datum/admins/proc/DB_ban_unban_by_id(var/id) if(!check_rights(R_BAN)) return - establish_db_connection() + establish_db_connection(dbcon) if(!dbcon.IsConnected()) usr << "\red Failed to establish database connection" return diff --git a/code/modules/admin/IsBanned.dm b/code/modules/admin/IsBanned.dm index da4f2af534b..37eb7cc691b 100644 --- a/code/modules/admin/IsBanned.dm +++ b/code/modules/admin/IsBanned.dm @@ -34,7 +34,7 @@ world/IsBanned(key,address,computer_id) var/ckeytext = ckey(key) - if(!establish_db_connection()) + if(!establish_db_connection(dbcon)) error("Ban database connection failure. Key [ckeytext] not checked") log_misc("Ban database connection failure. Key [ckeytext] not checked") return diff --git a/code/modules/admin/admin_ranks.dm b/code/modules/admin/admin_ranks.dm index 27eb8b6d3f3..3049976dfad 100644 --- a/code/modules/admin/admin_ranks.dm +++ b/code/modules/admin/admin_ranks.dm @@ -102,7 +102,7 @@ var/list/admin_ranks = list() //list of all ranks with associated rights else //The current admin system uses SQL - establish_db_connection() + establish_db_connection(dbcon) if(!dbcon.IsConnected()) error("Failed to connect to database in load_admins(). Reverting to legacy system.") log_misc("Failed to connect to database in load_admins(). Reverting to legacy system.") diff --git a/code/modules/admin/banjob.dm b/code/modules/admin/banjob.dm index ae04799354c..96899fc6d9c 100644 --- a/code/modules/admin/banjob.dm +++ b/code/modules/admin/banjob.dm @@ -65,7 +65,7 @@ DEBUG jobban_keylist=list() log_admin("jobban_keylist was empty") else - if(!establish_db_connection()) + if(!establish_db_connection(dbcon)) error("Database connection failed. Reverting to the legacy ban system.") log_misc("Database connection failed. Reverting to the legacy ban system.") config.ban_legacy_system = 1 diff --git a/code/modules/admin/permissionverbs/permissionedit.dm b/code/modules/admin/permissionverbs/permissionedit.dm index 0969fa35d88..1af56750311 100644 --- a/code/modules/admin/permissionverbs/permissionedit.dm +++ b/code/modules/admin/permissionverbs/permissionedit.dm @@ -54,7 +54,7 @@ usr << "\red You do not have permission to do this!" return - establish_db_connection() + establish_db_connection(dbcon) if(!dbcon.IsConnected()) usr << "\red Failed to establish database connection" @@ -104,7 +104,7 @@ usr << "\red You do not have permission to do this!" return - establish_db_connection() + establish_db_connection(dbcon) if(!dbcon.IsConnected()) usr << "\red Failed to establish database connection" return diff --git a/code/modules/admin/player_notes_sql.dm b/code/modules/admin/player_notes_sql.dm index 1d447110771..cfd42df4b7c 100644 --- a/code/modules/admin/player_notes_sql.dm +++ b/code/modules/admin/player_notes_sql.dm @@ -12,7 +12,7 @@ else query_details[":a_ckey"] = user.ckey - establish_db_connection() + establish_db_connection(dbcon) if (!dbcon.IsConnected()) alert("SQL connection failed while trying to add a note!") return @@ -36,7 +36,7 @@ if (!note_id || !note_edit) return - establish_db_connection() + establish_db_connection(dbcon) if (!dbcon.IsConnected()) error("SQL connection failed while attempting to delete a note!") return @@ -93,7 +93,7 @@ player_ckey = ckey(player_ckey) admin_ckey = ckey(admin_ckey) - establish_db_connection() + establish_db_connection(dbcon) if (!dbcon.IsConnected()) error("SQL connection failed while attempting to view a player's notes!") return @@ -187,7 +187,7 @@ if (!ckey) return "No ckey given!" - establish_db_connection() + establish_db_connection(dbcon) if (!dbcon.IsConnected()) return "Unable to establish database connection! Aborting!" @@ -231,7 +231,7 @@ note_list >> note_keys msg_scopes("Establishing DB connection!") - establish_db_connection() + establish_db_connection(dbcon) if(!dbcon.IsConnected()) msg_scopes("No DB connection!") return diff --git a/code/modules/admin/verbs/check_customitem_activity.dm b/code/modules/admin/verbs/check_customitem_activity.dm index 8d701e26734..e9bbaded60b 100644 --- a/code/modules/admin/verbs/check_customitem_activity.dm +++ b/code/modules/admin/verbs/check_customitem_activity.dm @@ -29,7 +29,7 @@ var/inactive_keys = "None
" if(checked_for_inactives) return - establish_db_connection() + establish_db_connection(dbcon) if(!dbcon.IsConnected()) return diff --git a/code/modules/admin/verbs/warning.dm b/code/modules/admin/verbs/warning.dm index b19454d04de..3ad7a81bfff 100644 --- a/code/modules/admin/verbs/warning.dm +++ b/code/modules/admin/verbs/warning.dm @@ -9,7 +9,7 @@ if (!warned_ckey || !istext(warned_ckey)) return - establish_db_connection() + establish_db_connection(dbcon) if (!dbcon.IsConnected()) usr << "Error: warn(): Database Connection failed, reverting to legacy systems." usr.client.warn_legacy(warned_ckey) @@ -110,7 +110,7 @@ var/dcolor = "#ffaaaa" //dark colour, severity = 1 var/ecolor = "#e3e3e3" //gray colour, expired = 1 - establish_db_connection() + establish_db_connection(dbcon) if (!dbcon.IsConnected()) alert("Connection to the SQL database lost. Aborting. Please alert an Administrator or a member of staff.") return @@ -172,7 +172,7 @@ if (!warning_id) return - establish_db_connection() + establish_db_connection(dbcon) if (!dbcon.IsConnected()) alert("Connection to SQL database failed while attempting to update your warning's status!") return @@ -191,7 +191,7 @@ var/count = 0 var/count_expire = 0 - establish_db_connection() + establish_db_connection(dbcon) if (!dbcon.IsConnected()) return @@ -239,7 +239,7 @@ var/dcolor = "#ffdddd" //dark colour, severity = 1 var/ecolor = "#e3e3e3" //gray colour, expired = 1 - establish_db_connection() + establish_db_connection(dbcon) if (!dbcon.IsConnected()) alert("Connection to the SQL database lost. Aborting. Please alert the database admin!") return @@ -342,7 +342,7 @@ if(!warning_id || !warning_edit) return - establish_db_connection() + establish_db_connection(dbcon) if(!dbcon.IsConnected()) alert("Connection to the SQL database lost. Aborting. Please alert the database admin!") return diff --git a/code/modules/client/client procs.dm b/code/modules/client/client procs.dm index 09127b10095..3a936f7eb0c 100644 --- a/code/modules/client/client procs.dm +++ b/code/modules/client/client procs.dm @@ -74,7 +74,68 @@ if(href_list["warnview"]) warnings_check() - ..() //redirect to hsrc.Topic() + if(href_list["linkingrequest"]) + if (!config.webint_url) + return + + if (!href_list["linkingaction"]) + return + + var/request_id = text2num(href_list["linkingrequest"]) + + establish_db_connection(dbcon) + if (!dbcon.IsConnected()) + src << "\red Action failed! Database link could not be established!" + return + + + var/DBQuery/check_query = dbcon.NewQuery("SELECT player_ckey, status FROM ss13_player_linking WHERE id = :id") + check_query.Execute(list(":id" = request_id)) + + if (!check_query.NextRow()) + src << "\red No request found!" + return + + if (ckey(check_query.item[1]) != ckey || check_query.item[2] != "new") + src << "\red Request authentication failed!" + return + + var/query_contents = "" + var/list/query_details = list(":new_status", ":id") + var/feedback_message = "" + switch (href_list["linkingaction"]) + if ("accept") + query_contents = "UPDATE ss13_player_linking SET status = :new_status, updated_at = NOW() WHERE id = :id" + query_details[":new_status"] = "confirmed" + query_details[":id"] = request_id + + feedback_message = "Account successfully linked!" + if ("deny") + query_contents = "UPDATE ss13_player_linking SET status = :new_status, deleted_at = NOW() WHERE id = :id" + query_details[":new_status"] = "rejected" + query_details[":id"] = request_id + + feedback_message = "Link request rejected!" + else + src << "\red Invalid command sent." + return + + var/DBQuery/update_query = dbcon.NewQuery(query_contents) + update_query.Execute(query_details) + + if (href_list["linkingaction"] == "accept" && alert("To complete the process, you have to visit the website. Do you want to do so now?",,"Yes","No") == "Yes") + process_webint_link("interface/user/link") + + src << feedback_message + check_linking_requests() + return + + if (href_list["routeWebInt"]) + process_webint_link(href_list["routeWebInt"], href_list["routeAttributes"]) + + return + + ..() //redirect to hsrc.() /client/proc/handle_spam_prevention(var/message, var/mute_type) if(config.automute_on && !holder && src.last_message == message) @@ -175,6 +236,8 @@ log_client_to_db() + check_linking_requests() + send_resources() nanomanager.send_resources(src) @@ -203,7 +266,7 @@ // Returns null if no DB connection can be established, or -1 if the requested key was not found in the database /proc/get_player_age(key) - establish_db_connection() + establish_db_connection(dbcon) if(!dbcon.IsConnected()) return null @@ -223,7 +286,7 @@ if ( IsGuestKey(src.key) ) return - establish_db_connection() + establish_db_connection(dbcon) if(!dbcon.IsConnected()) return @@ -344,12 +407,101 @@ ) -mob/proc/MayRespawn() +/mob/proc/MayRespawn() return 0 -client/proc/MayRespawn() +/client/proc/MayRespawn() if(mob) return mob.MayRespawn() // Something went wrong, client is usually kicked or transfered to a new mob at this point return 0 + +//I honestly can't find a good place for this atm. +//If the webint interaction gets more features, I'll move it. - Skull132 +/client/verb/view_linking_requests() + set name = "View Linking Requests" + set category = "OOC" + + check_linking_requests() + +/client/proc/check_linking_requests() + if (!config.webint_url || !config.sql_enabled) + return + + establish_db_connection(dbcon) + if (!dbcon.IsConnected()) + return + + var/list/requests = list() + var/list/query_details = list(":ckey" = ckey) + + var/DBQuery/select_query = dbcon.NewQuery("SELECT id, forum_id, forum_username, datediff(Now(), created_at) as request_age FROM ss13_player_linking WHERE status = 'new' AND player_ckey = :ckey AND deleted_at IS NULL") + select_query.Execute(query_details) + + while (select_query.NextRow()) + requests.Add(list(list("id" = text2num(select_query.item[1]), "forum_id" = text2num(select_query.item[2]), "forum_username" = select_query.item[3], "request_age" = select_query.item[4]))) + + if (!requests.len) + return + + var/dat = "
You have active requests to check!
" + var/i = 0 + for (var/list/request in requests) + i++ + + var/linked_forum_name = null + if (config.forumurl) + var/route_attributes = list2params(list("mode" = "viewprofile", "u" = request["forum_id"])) + linked_forum_name = "[request["forum_username"]]" + + dat += "
" + dat += "#[i] - Request to link your current key ([key]) to a forum account with the username of: [linked_forum_name ? linked_forum_name : request["forum_username"]].
" + dat += "The request is [request["request_age"]] days old.
" + dat += "OPTIONS: Accept Request | Deny Request" + + src << browse(dat, "window=LinkingRequests") + return + +/client/proc/process_webint_link(var/route, var/attributes) + if (!route) + return + + var/linkURL = "" + + switch (route) + if ("forums/members") + if (!webint_validate_attributes(list("mode", "u"), attributes_text = attributes)) + return + + if (!config.forumurl) + return + + linkURL = "[config.forumurl]memberlist.php?" + + linkURL += attributes + + if ("interface/user/link") + if (!config.webint_url) + return + + linkURL = "[config.webint_url]user/link" + + if ("interface/login/sso_server") + //This also validates the attributes as it runs + var/new_attributes = webint_start_singlesignon(src, attributes) + if (!new_attributes) + return + + if (!config.webint_url) + return + + linkURL = "[config.webint_url]login/sso_server?" + linkURL += new_attributes + + else + log_debug("Unrecognized process_webint_link() call used. Route sent: '[route]'.") + return + + src << link(linkURL) + return diff --git a/code/modules/clothing/glasses/glasses.dm b/code/modules/clothing/glasses/glasses.dm index c9de540257d..22537d7b183 100644 --- a/code/modules/clothing/glasses/glasses.dm +++ b/code/modules/clothing/glasses/glasses.dm @@ -110,6 +110,24 @@ prescription = 1 body_parts_covered = 0 +/obj/item/clothing/glasses/regular/attackby(obj/item/weapon/W as obj, mob/user as mob) + if(istype(W, /obj/item/clothing/glasses/hud/health)) + user.drop_item() + del(W) + user << "You attach a set of medical HUDs to your glasses." + var/turf/T = get_turf(src) + new /obj/item/clothing/glasses/hud/health/prescription(T) + user.drop_from_inventory(src) + del(src) + if(istype(W, /obj/item/clothing/glasses/hud/security)) + user.drop_item() + del(W) + user << "You attach a set of security HUDs to your glasses." + var/turf/T = get_turf(src) + new /obj/item/clothing/glasses/hud/security/prescription(T) + user.drop_from_inventory(src) + del(src) + /obj/item/clothing/glasses/regular/scanners name = "Scanning Goggles" desc = "A very oddly shaped pair of goggles with bits of wire poking out the sides. A soft humming sound emanates from it." diff --git a/code/modules/clothing/glasses/hud.dm b/code/modules/clothing/glasses/hud.dm index fb3d94ee89d..d775891d287 100644 --- a/code/modules/clothing/glasses/hud.dm +++ b/code/modules/clothing/glasses/hud.dm @@ -20,6 +20,21 @@ /obj/item/clothing/glasses/hud/health/process_hud(var/mob/M) process_med_hud(M, 1) +/obj/item/clothing/glasses/hud/health/prescription + name = "prescription glasses/HUD assembly" + desc = "A medical HUD clipped onto the side of prescription glasses." + prescription = 1 + icon_state = "healthhudpresc" + item_state = "healthhudpresc" + +/obj/item/clothing/glasses/hud/health/prescription/attack_self(mob/user) + user << "You detach a set of medical HUDs form your glasses." + var/turf/T = get_turf(src) + new /obj/item/clothing/glasses/hud/health(T) + new /obj/item/clothing/glasses/regular(T) + user.drop_item(src) + del(src) + /obj/item/clothing/glasses/hud/security name = "Security HUD" desc = "A heads-up display that scans the humans in view and provides accurate data about their ID status and security records." @@ -27,6 +42,21 @@ body_parts_covered = 0 var/global/list/jobs[0] +/obj/item/clothing/glasses/hud/security/prescription + name = "prescription glasses/HUD assembly" + desc = "A security HUD clipped onto the side of prescription glasses." + prescription = 1 + icon_state = "sechudpresc" + item_state = "sechudpresc" + +/obj/item/clothing/glasses/hud/security/prescription/attack_self(mob/user) + user << "You detach a set of security HUDs form your glasses." + var/turf/T = get_turf(src) + new /obj/item/clothing/glasses/hud/health(T) + new /obj/item/clothing/glasses/regular(T) + user.drop_item(src) + del(src) + /obj/item/clothing/glasses/hud/security/jensenshades name = "Augmented shades" desc = "Polarized bioneural eyewear, designed to augment your vision." diff --git a/code/modules/library/lib_machines.dm b/code/modules/library/lib_machines.dm index 224a051d95f..87977708e2d 100644 --- a/code/modules/library/lib_machines.dm +++ b/code/modules/library/lib_machines.dm @@ -43,7 +43,7 @@ datum/borrowbook // Datum used to keep track of who has borrowed what when and f Filter by Author: [author]
\[Start Search\]
"} if(1) - establish_db_connection() + establish_db_connection(dbcon) if(!dbcon.IsConnected()) dat += "ERROR: Unable to contact External Archive. Please contact your system administrator for assistance.
" else if(!SQLquery) @@ -189,7 +189,7 @@ datum/borrowbook // Datum used to keep track of who has borrowed what when and f (Return to main menu)
"} if(4) dat += "

External Archive

" - establish_db_connection() + establish_db_connection(dbcon) if(!dbcon.IsConnected()) dat += "ERROR: Unable to contact External Archive. Please contact your system administrator for assistance." else @@ -332,7 +332,7 @@ datum/borrowbook // Datum used to keep track of who has borrowed what when and f if(scanner.cache.unique) alert("This book has been rejected from the database. Aborting!") else - establish_db_connection() + establish_db_connection(dbcon) if(!dbcon.IsConnected()) alert("Connection to Archive has been severed. Aborting.") else @@ -356,7 +356,7 @@ datum/borrowbook // Datum used to keep track of who has borrowed what when and f if(href_list["targetid"]) var/sqlid = sanitizeSQL(href_list["targetid"]) - establish_db_connection() + establish_db_connection(dbcon) if(!dbcon.IsConnected()) alert("Connection to Archive has been severed. Aborting.") if(bibledelay) diff --git a/code/modules/mob/language/monkey.dm b/code/modules/mob/language/monkey.dm index ce276a358ab..f41a484cfce 100644 --- a/code/modules/mob/language/monkey.dm +++ b/code/modules/mob/language/monkey.dm @@ -19,4 +19,4 @@ /datum/language/tajaran/monkey name = "Farwa" desc = "Meow meow meow." - key = "9" + key = "^" diff --git a/code/modules/mob/language/station.dm b/code/modules/mob/language/station.dm index 13ca46882c8..990d966c227 100644 --- a/code/modules/mob/language/station.dm +++ b/code/modules/mob/language/station.dm @@ -71,7 +71,7 @@ desc = "Vaurca native language made of clicks and sputters, \"It's a bugs life.\"" speech_verb = "clicks" colour = "vaurca" - key = "m" + key = "9" flags = WHITELISTED syllables = list("kic","klic","\'tic","kit","lit","xic","vil","xrit","tshh","qix","qlit","zix","\'","!") diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm index 51f6a9a04f9..293be2d0dda 100644 --- a/code/modules/mob/living/carbon/human/life.dm +++ b/code/modules/mob/living/carbon/human/life.dm @@ -1635,13 +1635,13 @@ holder2.icon_state = "hudxeno" else if(foundVirus) holder.icon_state = "hudill" - else if(has_brain_worms()) - var/mob/living/simple_animal/borer/B = has_brain_worms() + /* else if(has_brain_worms()) + var/mob/living/simple_animal/borer/B = has_brain_worms() //Cotrical borer disable if(B.controlling) holder.icon_state = "hudbrainworm" else holder.icon_state = "hudhealthy" - holder2.icon_state = "hudbrainworm" + holder2.icon_state = "hudbrainworm" */ else holder.icon_state = "hudhealthy" if(virus2.len) diff --git a/code/modules/mob/living/carbon/metroid/life.dm b/code/modules/mob/living/carbon/metroid/life.dm index 06b4bbae6ca..638137cbd09 100644 --- a/code/modules/mob/living/carbon/metroid/life.dm +++ b/code/modules/mob/living/carbon/metroid/life.dm @@ -52,13 +52,13 @@ //Account for massive pressure differences - if(bodytemperature < (T0C + 5)) // start calculating temperature damage etc + if(bodytemperature < hurt_temperature) // start calculating temperature damage etc - if(bodytemperature <= (T0C - 50)) // hurt temperature - if(bodytemperature <= 50) // sqrting negative numbers is bad + if(bodytemperature <= die_temperature) + if(bodytemperature <= 50) adjustToxLoss(200) else - adjustToxLoss(round(sqrt(bodytemperature)) * 2) + adjustToxLoss(30) updatehealth() @@ -234,7 +234,7 @@ if(issilicon(L) && (rabid || attacked)) // They can't eat silicons, but they can glomp them in defence targets += L // Possible target found! - if(istype(L, /mob/living/carbon/human) && dna) //Ignore slime(wo)men + if(istype(L, /mob/living/carbon/human)) //Ignore slime(wo)men var/mob/living/carbon/human/H = L if(H.species.name == "Slime") continue diff --git a/code/modules/mob/living/carbon/metroid/metroid.dm b/code/modules/mob/living/carbon/metroid/metroid.dm index c2e41118b5a..36ce63cea00 100644 --- a/code/modules/mob/living/carbon/metroid/metroid.dm +++ b/code/modules/mob/living/carbon/metroid/metroid.dm @@ -48,6 +48,8 @@ var/Atkcool = 0 // attack cooldown var/SStun = 0 // NPC stun variable. Used to calm them down when they are attacked while feeding, or they will immediately re-attach var/Discipline = 0 // if a slime has been hit with a freeze gun, or wrestled/attacked off a human, they become disciplined and don't attack anymore for a while. The part about freeze gun is a lie + var/hurt_temperature = T0C-50 // slime keeps taking damage when its bodytemperature is below this + var/die_temperature = 50 // slime dies instantly when its bodytemperature is below this ///////////TIME FOR SUBSPECIES diff --git a/code/modules/mob/living/simple_animal/borer/borer_powers.dm b/code/modules/mob/living/simple_animal/borer/borer_powers.dm index f6b87bfd444..001197d9700 100644 --- a/code/modules/mob/living/simple_animal/borer/borer_powers.dm +++ b/code/modules/mob/living/simple_animal/borer/borer_powers.dm @@ -126,7 +126,7 @@ src << "They are no longer in range!" return -/* + /mob/living/simple_animal/borer/verb/devour_brain() set category = "Abilities" set name = "Devour Brain" @@ -150,7 +150,7 @@ src << "It only takes a few moments to render the dead host brain down into a nutrient-rich slurry..." replace_brain() -*/ + // BRAIN WORM ZOMBIES AAAAH. /mob/living/simple_animal/borer/proc/replace_brain() diff --git a/code/modules/mob/new_player/new_player.dm b/code/modules/mob/new_player/new_player.dm index c5716172a08..ca7d753590c 100644 --- a/code/modules/mob/new_player/new_player.dm +++ b/code/modules/mob/new_player/new_player.dm @@ -41,7 +41,7 @@ output += "

Observe

" if(!IsGuestKey(src.key)) - establish_db_connection() + establish_db_connection(dbcon) if(dbcon.IsConnected()) var/isadmin = 0 @@ -181,7 +181,7 @@ return if(href_list["privacy_poll"]) - establish_db_connection() + establish_db_connection(dbcon) if(!dbcon.IsConnected()) return var/voted = 0 diff --git a/code/modules/mob/new_player/poll.dm b/code/modules/mob/new_player/poll.dm index 953119961e0..6051d178b4b 100644 --- a/code/modules/mob/new_player/poll.dm +++ b/code/modules/mob/new_player/poll.dm @@ -1,6 +1,6 @@ /mob/new_player/proc/handle_privacy_poll() - establish_db_connection() + establish_db_connection(dbcon) if(!dbcon.IsConnected()) return var/voted = 0 @@ -47,7 +47,7 @@ var/optiontext /mob/new_player/proc/handle_player_polling() - establish_db_connection() + establish_db_connection(dbcon) if(dbcon.IsConnected()) var/isadmin = 0 if(src.client && src.client.holder) @@ -81,7 +81,7 @@ /mob/new_player/proc/poll_player(var/pollid = -1) if(pollid == -1) return - establish_db_connection() + establish_db_connection(dbcon) if(dbcon.IsConnected()) var/DBQuery/select_query = dbcon.NewQuery("SELECT starttime, endtime, question, polltype, multiplechoiceoptions FROM ss13_poll_question WHERE id = [pollid]") @@ -342,7 +342,7 @@ if(!isnum(pollid) || !isnum(optionid)) return - establish_db_connection() + establish_db_connection(dbcon) if(dbcon.IsConnected()) var/DBQuery/select_query = dbcon.NewQuery("SELECT starttime, endtime, question, polltype, multiplechoiceoptions FROM ss13_poll_question WHERE id = [pollid] AND Now() BETWEEN starttime AND endtime") @@ -412,7 +412,7 @@ if(!isnum(pollid) || !istext(replytext)) return - establish_db_connection() + establish_db_connection(dbcon) if(dbcon.IsConnected()) var/DBQuery/select_query = dbcon.NewQuery("SELECT starttime, endtime, question, polltype FROM ss13_poll_question WHERE id = [pollid] AND Now() BETWEEN starttime AND endtime") @@ -470,7 +470,7 @@ if(!isnum(pollid) || !isnum(optionid)) return - establish_db_connection() + establish_db_connection(dbcon) if(dbcon.IsConnected()) var/DBQuery/select_query = dbcon.NewQuery("SELECT starttime, endtime, question, polltype FROM ss13_poll_question WHERE id = [pollid] AND Now() BETWEEN starttime AND endtime") diff --git a/code/modules/projectiles/guns/energy/temperature.dm b/code/modules/projectiles/guns/energy/temperature.dm index 47bc2cfc00b..34801b4574b 100644 --- a/code/modules/projectiles/guns/energy/temperature.dm +++ b/code/modules/projectiles/guns/energy/temperature.dm @@ -1,18 +1,18 @@ /obj/item/weapon/gun/energy/temperature - name = "temperature gun" + name = "freeze ray" icon_state = "freezegun" fire_sound = 'sound/weapons/pulse3.ogg' - desc = "A gun that changes temperatures. It has a small label on the side, 'More extreme temperatures will cost more charge!'" - var/temperature = T20C - var/current_temperature = T20C - charge_cost = 100 + desc = "For when somebody won't let it go." + //var/temperature = T20C + //var/current_temperature = T20C + charge_cost = 25 //20 shots, exact replica of old code (WAS 100) origin_tech = "combat=3;materials=4;powerstorage=3;magnets=2" slot_flags = SLOT_BELT|SLOT_BACK projectile_type = /obj/item/projectile/temp - cell_type = /obj/item/weapon/cell/high - + cell_type = /obj/item/weapon/cell/crap //WAS High, but brought down to match energy use +/* /obj/item/weapon/gun/energy/temperature/New() ..() processing_objects.Add(src) @@ -38,7 +38,7 @@ user << browse(dat, "window=freezegun;size=450x300;can_resize=1;can_close=1;can_minimize=1") onclose(user, "window=freezegun", src) - +*/ /obj/item/weapon/gun/energy/temperature/Topic(href, href_list) if (..()) @@ -47,7 +47,7 @@ src.add_fingerprint(usr) - +/* if(href_list["temp"]) var/amount = text2num(href_list["temp"]) if(amount > 0) @@ -77,3 +77,4 @@ temperature += 10 else temperature = current_temperature +*/ \ No newline at end of file diff --git a/code/modules/projectiles/projectile/special.dm b/code/modules/projectiles/projectile/special.dm index f2578d3f60b..bfba9472313 100644 --- a/code/modules/projectiles/projectile/special.dm +++ b/code/modules/projectiles/projectile/special.dm @@ -28,7 +28,7 @@ name ="high-ex round" icon_state= "bolter" damage = 15 - + on_hit(var/atom/target, var/blocked = 0) explosion(target, -1, 0, 2) sleep(0) @@ -44,13 +44,13 @@ damage_type = BURN nodamage = 1 check_armour = "energy" - var/temperature = 300 + //var/temperature = 300 on_hit(var/atom/target, var/blocked = 0)//These two could likely check temp protection on the mob if(istype(target, /mob/living)) var/mob/M = target - M.bodytemperature = temperature + M.bodytemperature = -273 return 1 /obj/item/projectile/meteor diff --git a/code/modules/research/message_server.dm b/code/modules/research/message_server.dm index 9655f3b3dcd..9144cd11d98 100644 --- a/code/modules/research/message_server.dm +++ b/code/modules/research/message_server.dm @@ -297,7 +297,7 @@ var/obj/machinery/blackbox_recorder/blackbox if(!feedback) return round_end_data_gathering() //round_end time logging and some other data processing - establish_db_connection() + establish_db_connection(dbcon) if(!dbcon.IsConnected()) return var/round_id diff --git a/code/modules/web_interface/webint_procs.dm b/code/modules/web_interface/webint_procs.dm new file mode 100644 index 00000000000..332dcf19a54 --- /dev/null +++ b/code/modules/web_interface/webint_procs.dm @@ -0,0 +1,96 @@ +/* + * Contains general purpose procs used with Aurora's web interface and related functions. + */ + +/* + * /proc/validate_webint_attributes() + * Used to validate parametres sent to procs that are meant to communicate with the web interface. + * Most commonly in Topic() calls, so that href tomfoolery is negated. + * + * Arguments: + * - var/list/required_attributes - A list of required attributes. This is what the other arguments will be tested against. Cannot be null. + * - var/list/attributes_list - The attributes to be validated, passed in a list form. Can be null. + * - var/attributes_text - The attributes to be validated, passed in a text form. (Formatted according to list2params() convention.) + * This overrides attributes_list if both are present. Can be null. + * + * Returns: + * 1 - if all required attributes are present, and no erronious ones exist. + * 0 - if certain required attributes are missing, or there are extras. + */ + +/proc/webint_validate_attributes(var/list/required_attributes, var/list/attributes_list, var/attributes_text) + if (!required_attributes || !istype(required_attributes) || !required_attributes.len) + return 0 + + if (attributes_text) + attributes_list = params2list(attributes_text) + + if (!attributes_list || !attributes_list.len) + return 0 + + for (var/attribute in attributes_list) + if (!(attribute in required_attributes)) + return 0 + + if (attributes_list[attribute] && required_attributes[attribute]) + if (istype(required_attributes, /list)) + if (!(attributes_list[attribute] in required_attributes[attribute])) + return 0 + + else + if (attributes_list[attribute] != required_attributes[attribute]) + return 0 + + return 1 + +/* + * /proc/webint_start_singlesignon() + * Used to insert a token into the web_sso database and to enable a user to navigate to a page on the website and be automatically logged in. Hashes the user's save file for a unique token. Additional security managed on the website's end. + * + * Arguments: + * - var/user - Must be a mob or a client. The player object that's going to be using the request. + * - var/list/attributes - The attributes to which we route the URL as we call user.process_webint_link(). + * Validated here with webint_validate_attributes(). + * Must contain the 'location' key. + * + * Returns: + * 0 - if one of the checks is failed and the operation cancelled. + * string - if everything works, it will return the attributes with the added token and ckey value. + */ + +/proc/webint_start_singlesignon(var/client/user, var/attributes) + if (!istype(user)) + return 0 + + var/list/permitted_locations = list("user_dashboard", "contract_overview", "contract_details") + + if (!webint_validate_attributes(list("location" = permitted_locations, "contract"), attributes_text = attributes)) + return 0 + + var/token = "" + var/list/alphabet = alphabet_uppercase + alphabet.Add(list("a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z")) + alphabet.Add(list("1", "2", "3", "4", "5", "6", "7", "8", "9", "0")) + + for (var/i = 0, i <= 24, i++) + token += alphabet[rand(1, alphabet.len)] + + attributes += "&" + attributes += list2params(list("ckey" = user.ckey, "token" = token)) + + establish_db_connection(dbcon) + if (!dbcon.IsConnected()) + alert("An error occured while attempting to connect to the database!") + return 0 + + var/DBQuery/insert_query = dbcon.NewQuery("INSERT INTO ss13_web_sso (ckey, token, ip, created_at) VALUES (:ckey, :token, :ip, NOW())") + insert_query.Execute(list(":ckey" = user.ckey, ":token" = token, ":ip" = user.address)) + + if (insert_query.ErrorMsg()) + alert("An error occured while trying to upload the session data!") + return 0 + + if (alert("This will take you to the webpage and log you in. Do you wish to proceed?",,"Yes","No") == "No") + return 0 + + return attributes diff --git a/code/world.dm b/code/world.dm index 88dea018a5f..6148324b93b 100644 --- a/code/world.dm +++ b/code/world.dm @@ -534,8 +534,6 @@ var/world_topic_spam_protect_time = world.timeofday config = new /datum/configuration() config.load("config/config.txt") config.load("config/game_options.txt","game_options") - config.loadsql("config/dbconfig.txt") - config.loadforumsql("config/forumdbconfig.txt") /hook/startup/proc/loadMods() world.load_mods() @@ -643,47 +641,85 @@ var/world_topic_spam_protect_time = world.timeofday src.status = s #define FAILED_DB_CONNECTION_CUTOFF 5 -var/failed_db_connections = 0 -var/failed_old_db_connections = 0 -/hook/startup/proc/connectDB() - if(!setup_database_connection()) +/hook/startup/proc/load_databases() + //Construct the database object from an init file. + dbcon = initialize_database_object("config/dbconfig.txt") + + if (!setup_database_connection(dbcon)) world.log << "Your server failed to establish a connection with the feedback database." else world.log << "Feedback database connection established." return 1 -proc/setup_database_connection() - - if(failed_db_connections > FAILED_DB_CONNECTION_CUTOFF) //If it failed to establish a connection more than 5 times in a row, don't bother attempting to conenct anymore. +/proc/initialize_database_object(var/filename) + if (!filename) return 0 - if(!dbcon) - dbcon = new() + var/list/data = list("address", "port", "database", "login", "password") - var/user = sqllogin - var/pass = sqlpass - var/db = sqldb - var/address = sqladdress - var/port = sqlport + var/list/Lines = file2list(filename) + for (var/t in Lines) + if (!t) + continue - dbcon.Connect("dbi:mysql:[db]:[address]:[port]","[user]","[pass]") - . = dbcon.IsConnected() + t = trim(t) + if (length(t) == 0) + continue + else if (copytext(t, 1, 2) == "#") + continue + + var/pos = findtext(t, " ") + var/name = null + var/value = null + + name = lowertext(copytext(t, 1, pos)) + value = copytext(t, pos + 1) + + if (!name) + continue + + if (name in data) + data[name] = value + else + log_misc("Unknown setting while setting up database connection. Filename: '[filename]', value: '[value]'.") + + //Validate the data before proceeding. + for (var/d in data) + if (!data[d] || data[d] == null) + return 0 + + return new/DBConnection(data["address"], data["port"], data["database"], data["login"], data["password"]) + +/proc/setup_database_connection(var/DBConnection/con) + if (!con) + error("No DBConnection object passed to setup_database_connection().") + return 0 + + if (con.failed_connections > FAILED_DB_CONNECTION_CUTOFF) //If it failed to establish a connection more than 5 times in a row, don't bother attempting to conenct anymore. + return 0 + + con.Connect() + . = con.IsConnected() if ( . ) - failed_db_connections = 0 //If this connection succeeded, reset the failed connections counter. + con.failed_connections = 0 //If this connection succeeded, reset the failed connections counter. else - failed_db_connections++ //If it failed, increase the failed connections counter. - world.log << dbcon.ErrorMsg() + con.failed_connections++ //If it failed, increase the failed connections counter. + world.log << con.ErrorMsg() return . //This proc ensures that the connection to the feedback database (global variable dbcon) is established -proc/establish_db_connection() - if(failed_db_connections > FAILED_DB_CONNECTION_CUTOFF) +/proc/establish_db_connection(var/DBConnection/con) + if (!con) + error("No DBConnection object passed to establish_db_connection() proc.") return 0 - if(!dbcon || !dbcon.IsConnected()) - return setup_database_connection() + if (con.failed_connections > FAILED_DB_CONNECTION_CUTOFF) + return 0 + + if (!con.IsConnected()) + return setup_database_connection(con) else return 1 diff --git a/config/example/config.txt b/config/example/config.txt index 7f8c3a3ee09..545a62cade1 100644 --- a/config/example/config.txt +++ b/config/example/config.txt @@ -31,7 +31,7 @@ JOBS_HAVE_MINIMAL_ACCESS ## log OOC channel LOG_OOC -## log client Say +## log client Say LOG_SAY ## log admin actions @@ -93,7 +93,7 @@ MOD_JOB_TEMPBAN_MAX 1440 ## probablities for game modes chosen in "secret" and "random" modes -## +## ## default probablity is 1, increase to make that mode more likely to be picked ## set to 0 to disable that mode PROBABILITY EXTENDED 1 @@ -216,7 +216,7 @@ GUEST_BAN ##Remove the # mark infront of this to forbid admins from posssessing the singularity. #FORBID_SINGULO_POSSESSION -## Remove the # to show a popup 'reply to' window to every non-admin that recieves an adminPM. +## Remove the # to show a popup 'reply to' window to every non-admin that recieves an adminPM. ## The intention is to make adminPMs more visible. (although I fnd popups annoying so this defaults to off) #POPUP_ADMIN_PM @@ -258,21 +258,6 @@ USEALIENWHITELIST ## Password used for authorizing ircbot and other external tools. #COMMS_PASSWORD -## Uncomment to enable sending data to the IRC bot. -#USE_IRC_BOT - -## Uncomment if the IRC bot requires using world.Export() instead of nudge.py/libnudge -#IRC_BOT_EXPORT - -## Host where the IRC bot is hosted. Port 45678 needs to be open. -#IRC_BOT_HOST localhost - -## IRC channel to send information to. Leave blank to disable. -#MAIN_IRC #main - -## IRC channel to send adminhelps to. Leave blank to disable adminhelps-to-irc. -#ADMIN_IRC #admin - ## Path to the python2 executable on the system. Leave blank for default. ## Default is "python" on Windows, "/usr/bin/env python2" on UNIX. #PYTHON_PATH @@ -293,7 +278,7 @@ CHARACTER_SLOTS 10 ## Uncomment to use overmap system for zlevel travel #USE_OVERMAP -## Defines which Z-levels the station exists on. +## Defines which Z-levels the station exists on. STATION_LEVELS 1 ## Defines which Z-levels are used for admin functionality, such as Central Command and the Syndicate Shuttle @@ -373,3 +358,18 @@ STARLIGHT 0 ## Uncomment to override default brain health. #DEFAULT_BRAIN_HEALTH 400 + +## Uncomment this to house whitelists on the SQL database. +# SQL_WHITELISTS + +## Uncomment this to use the discord bot. +# USE_DISCORD_BOT + +## The host address of the discord bot. +# DISCORD_BOT_HOST + +## The port number which the discord bot is listening for nudges. +# DISCORD_BOT_PORT + +## Uncomment this and fill in the web interface's URL to use the web interface. +# WEBINT_URL http://www.address.com/ diff --git a/config/example/forumdbconfig.txt b/config/example/forumdbconfig.txt deleted file mode 100644 index 61a2a2d6ecd..00000000000 --- a/config/example/forumdbconfig.txt +++ /dev/null @@ -1,19 +0,0 @@ -# This configuration file is for the forum database, if you need to set up -# population, death, etc. tracking see 'dbconfig.txt' -# The login credentials for this will likely differ from those in dbconfig.txt! - -# Server the MySQL database can be found at -# Examples: localhost, 200.135.5.43, www.mysqldb.com, etc. -ADDRESS localhost - -# MySQL server port (default is 3306) -PORT 3306 - -# Database the forum data may be found in -DATABASE tgstation13 - -# Username/Login used to access the database -LOGIN mylogin - -# Password used to access the database -PASSWORD mypassword \ No newline at end of file diff --git a/html/changelogs/[Lord Lag]-[Adds #183].yml b/html/changelogs/[Lord Lag]-[Adds #183].yml new file mode 100644 index 00000000000..7b85cc94043 --- /dev/null +++ b/html/changelogs/[Lord Lag]-[Adds #183].yml @@ -0,0 +1,8 @@ +author: Lord Lag + +delete-after: True + +changes: + - rscadd: "Glasses may once again be combined with HUDs" + - rscadd: "Borers have a full compliment of abilities once more." + - bugfix: ":9 is the new new Vaurcese hotkey." diff --git a/html/changelogs/[Lord Lag]-[Fixes #120].yml b/html/changelogs/[Lord Lag]-[Fixes #120].yml new file mode 100644 index 00000000000..f14cc1ab746 --- /dev/null +++ b/html/changelogs/[Lord Lag]-[Fixes #120].yml @@ -0,0 +1,7 @@ +author: Lord Lag + +delete-after: True + +changes: + - tweak: "The broken Temperature gun has been replaced with the Freeze ray" + diff --git a/html/changelogs/skull132-webinterface.yml b/html/changelogs/skull132-webinterface.yml new file mode 100644 index 00000000000..a7b6f19766f --- /dev/null +++ b/html/changelogs/skull132-webinterface.yml @@ -0,0 +1,8 @@ +author: Skull132 + +delete-after: True + +changes: + - rscadd: "Integrated the web interface with the game. Players can now create linking requests from the web interface, and accept them ingame. This will be used for more feature integration between the two later." + - rscadd: "Integrated the syndicate contract database with the game. Players can interact with contracts from the web interface (create new ones, post comments, report completion, etcetera), and review the contracts from syndicate uplinks. This means that antags with access to an uplink can now roleplay with contracts, fulfilling missions and so forth." + - rscadd: "Heisters now spawn with contract uplinks, which are effectively syndicate uplinks without the telecrystals, for checking up on the contracts database." diff --git a/icons/mob/eyes.dmi b/icons/mob/eyes.dmi index b68ccd373c5..9c36e5e59c0 100644 Binary files a/icons/mob/eyes.dmi and b/icons/mob/eyes.dmi differ diff --git a/icons/obj/clothing/glasses.dmi b/icons/obj/clothing/glasses.dmi index 43bea2af318..3e20f69244e 100644 Binary files a/icons/obj/clothing/glasses.dmi and b/icons/obj/clothing/glasses.dmi differ diff --git a/nano/templates/uplink.tmpl b/nano/templates/uplink.tmpl index e981155622d..d51aebcbc3a 100644 --- a/nano/templates/uplink.tmpl +++ b/nano/templates/uplink.tmpl @@ -1,5 +1,5 @@ - @@ -13,12 +13,13 @@ Used In File(s): \code\game\objects\items\devices\uplinks.dm
{{:helper.link('Request Items', 'gear', {'menu' : 0}, null, 'fixedLeftWider')}} {{:helper.link('Exploitable Information', 'gear', {'menu' : 1}, null, 'fixedLeftWider')}} + {{:helper.link('Extranet Contract Database', 'gear', {'menu' : 2}, null, 'fixedLeftWider')}} {{:helper.link('Return', 'arrowreturn-1-w', {'return' : 1}, null, 'fixedLeft')}} {{:helper.link('Close', 'gear', {'lock' : "1"}, null, 'fixedLeft')}}

- + {{if data.menu == 0}}

Request items:

Each item costs a number of tele-crystals as indicated by the number following their name. @@ -39,7 +40,7 @@ Used In File(s): \code\game\objects\items\devices\uplinks.dm
{{:helper.link( itemValue.Name, 'gear', {'buy_item' : itemValue.obj_path, 'cost' : itemValue.Cost}, itemValue.Cost > data.crystals ? 'disabled' : null, null)}} - {{:itemValue.Cost}}
- + {{if itemValue.Cost <= data.crystals}}
{{:itemValue.Description}} @@ -52,7 +53,7 @@ Used In File(s): \code\game\objects\items\devices\uplinks.dm
{{:helper.link('Buy Random (??)' , 'gear', {'buy_item' : 'random'}, data.crystals <= 0 ? 'disabled' : null, null)}}
- + {{else data.menu == 1}}

Information Record List:


@@ -65,7 +66,7 @@ Used In File(s): \code\game\objects\items\devices\uplinks.dm {{:helper.link(value.Name, 'gear', {'menu' : 11, 'id' : value.id}, null, null)}}
{{/for}} - + {{else data.menu == 11}}

Information Record:


@@ -96,4 +97,73 @@ Used In File(s): \code\game\objects\items\devices\uplinks.dm + +{{else data.menu == 2}} +

Available Contracts:

+
+ {{if data.contracts_found == 1}} +
+
+ + {{if data.contracts_view == 1}} + + {{else}} + + {{/if}} + {{for data.contracts}} + + {{/for}} +
IDContractorTitle
Available Contracts
Closed Contracts
{{:value.id}}{{:value.contractee}}{{:value.title}}{{:helper.link('View', null, {'menu' : 21, 'id' : value.id}, null, 'fixedLeft')}}
+
+
+ {{for data.contracts_pages}} + {{:helper.link(value, null, {'contract_page' : value}, null, null)}} + {{/for}} +

+ {{if data.contracts_view == 1}} + {{:helper.link('View Expired Contracts', 'gear', {'contract_view' : 2}, null, null)}} + {{else}} + {{:helper.link('View Open Contracts', 'gear', {'contract_view' : 1}, null, null)}} + {{/if}} +
+
+
+
+ {{else}} +
+
No Contracts Available.
+
+ {{/if}} + +{{else data.menu == 21}} +

Viewing Contract:

+
+
+
+
+ {{if data.contracts_found == 1}} + ID: #{{:data.contract.id}}
+ Contractee: {{:data.contract.contractee}}
+ Status: + {{if data.contract.status == 1}} + Open
+ {{else}} + Closed
+ {{/if}} + Title: {{:data.contract.title}}
+
+ Description: {{:data.contract.description}}
+ Reward: {{:data.contract.reward_other}}
+ {{else}} + Failed to retreive contract information! + {{/if}} +
+ +
+
+

+ {{if data.contracts_found == 1}} + {{:helper.link('View Reports And Updates', 'extlink', {'contract_interact' : data.contract.id}, null, null)}} + {{/if}} + {{/if}}