mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-01-07 07:22:56 +00:00
Exempt playtime by job basis (#1135)
<!-- Write **BELOW** The Headers and **ABOVE** The comments else it may not be viewable. --> <!-- You can view Contributing.MD for a detailed description of the pull request process. --> ## About The Pull Request Adds functionality for administrators to toggle playtime job exemption for ckeys on a job basis Admins go through player panel to access the menu and they can toggle that with just one click The action is logged, announced to all admins, and if the player is logged on with that ckey, it is announced to him aswell The exemption status is saved on the DB, a new `bubber_schema.sql` needs to be ran to add the new table to the DB     <!-- Describe The Pull Request. Please be sure every change is documented or this can delay review and even discourage maintainers from merging your PR! --> <!-- Please make sure to actually test your PRs. If you have not tested your PR mention it. --> ## Why It's Good For The Game It was requested <!-- Argue for the merits of your changes and how they benefit the game, especially if they are controversial and/or far reaching. If you can't actually explain WHY what you are doing will improve the game, then it probably isn't good for the game in the first place. --> ## Proof Of Testing Included screenshots in the About section <!-- Compile and run your code locally. Make sure it works. This is the place to show off your changes! We are not responsible for testing your features. --> ## Changelog <!-- If your PR modifies aspects of the game that can be concretely observed by players or admins you should add a changelog. If your change does NOT meet this description, remove this section. Be sure to properly mark your PRs to prevent unnecessary GBP loss. You can read up on GBP and it's effects on PRs in the tgstation guides for contributors. Please note that maintainers freely reserve the right to remove and add tags should they deem it appropriate. You can attempt to finagle the system all you want, but it's best to shoot for clear communication right off the bat. --> 🆑 admin: administrators can now toggle job playtime exemption by job basis for players /🆑 <!-- Both 🆑's are required for the changelog to work! You can put your name to the right of the first 🆑 if you want to overwrite your GitHub username as author ingame. --> <!-- You can use multiple of the same prefix (they're only used for the icon ingame) and delete the unneeded ones. Despite some of the tags, changelogs should generally represent how a player might be affected by the changes rather than a summary of the PR's contents. --> <!-- By opening a pull request. You have read and understood the repository rules located on the main README.md on this project. --> --------- Co-authored-by: Waterpig <49160555+Majkl-J@users.noreply.github.com>
This commit is contained in:
24
SQL/bubber_schema.sql
Normal file
24
SQL/bubber_schema.sql
Normal file
@@ -0,0 +1,24 @@
|
||||
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
|
||||
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
|
||||
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
|
||||
/*!40101 SET NAMES utf8 */;
|
||||
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
|
||||
/*!40103 SET TIME_ZONE='+00:00' */;
|
||||
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
|
||||
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
|
||||
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
|
||||
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
|
||||
|
||||
--
|
||||
-- Table structure for table `jobexempt`
|
||||
--
|
||||
|
||||
DROP TABLE IF EXISTS `jobexempt`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8 */;
|
||||
CREATE TABLE `jobexempt` (
|
||||
`ckey` varchar(32) NOT NULL,
|
||||
`jobs` VARCHAR(2048) DEFAULT NULL,
|
||||
PRIMARY KEY (`ckey`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
@@ -48,6 +48,15 @@
|
||||
return
|
||||
cmd_show_exp_panel(M.client)
|
||||
|
||||
// BUBBER EDIT START - Job exemption
|
||||
else if (href_list["getjobexemptwindow"])
|
||||
var/target_ckey = href_list["getjobexemptwindow"]
|
||||
show_job_exempt_menu(usr, target_ckey)
|
||||
else if (href_list["getjobexempttask"])
|
||||
var/target_ckey = href_list["getjobexempttask"]
|
||||
handle_job_exempt_menu_topic(usr, href, href_list, target_ckey)
|
||||
// BUBBER EDIT END
|
||||
|
||||
// SKYRAT EDIT BEGIN -- ONE CLICK ANTAG
|
||||
else if(href_list["makeAntag"])
|
||||
|
||||
|
||||
@@ -21,6 +21,9 @@
|
||||
body += "\[<A href='?_src_=holder;[HrefToken()];editrights=[(GLOB.admin_datums[M.client.ckey] || GLOB.deadmins[M.client.ckey]) ? "rank" : "add"];key=[M.key]'>[M.client.holder ? M.client.holder.rank_names() : "Player"]</A>\]"
|
||||
if(CONFIG_GET(flag/use_exp_tracking))
|
||||
body += "\[<A href='?_src_=holder;[HrefToken()];getplaytimewindow=[REF(M)]'>" + M.client.get_exp_living(FALSE) + "</a>\]"
|
||||
// BUBBERS EDIT START - Job exemption
|
||||
body += "<br>\[<a href='?_src_=holder;[HrefToken()];getjobexemptwindow=[M.ckey]'>Job Exemption Menu</a>\]"
|
||||
// BUBBERS EDIT END
|
||||
|
||||
if(isnewplayer(M))
|
||||
body += " <B>Hasn't Entered Game</B> "
|
||||
|
||||
@@ -17,6 +17,10 @@ GLOBAL_PROTECT(exp_to_update)
|
||||
var/isexempt = C.prefs.db_flags & DB_FLAG_EXEMPT
|
||||
if(isexempt)
|
||||
return 0
|
||||
// BUBBER EDIT START - Job exemption
|
||||
if(is_job_exempt_from(C.ckey, title))
|
||||
return 0
|
||||
// BUBBER EDIT END
|
||||
var/my_exp = C.calc_exp_type(get_exp_req_type())
|
||||
var/job_requirement = get_exp_req_amount()
|
||||
if(my_exp >= job_requirement)
|
||||
|
||||
149
modular_zubbers/modules/job_exempt/job_exempt.dm
Normal file
149
modular_zubbers/modules/job_exempt/job_exempt.dm
Normal file
@@ -0,0 +1,149 @@
|
||||
// Global cached list of job exemption to lower stress on the database
|
||||
// Associative list of ckey to associative list of job titles which were granted the exemption ex. `job_exempt_cache[ckey][job_title]` being null is no exemption and being TRUE is an exemption
|
||||
GLOBAL_LIST_INIT(job_exempt_cache, list())
|
||||
|
||||
/**
|
||||
* Returns whether a ckey has the job exemption for a job
|
||||
*
|
||||
* Arguments:
|
||||
* * ckey - The ckey you're checking, both key and ckey work
|
||||
* * job_title - The `job.title` of the job you're checking
|
||||
*/
|
||||
/proc/is_job_exempt_from(ckey, job_title)
|
||||
if(!SSdbcore.Connect())
|
||||
return FALSE
|
||||
// Convert to ckey just in case we get called with player 'key'
|
||||
var/player_ckey = ckey(ckey)
|
||||
// Load the ckey cache if it is not present
|
||||
load_job_exempt_cache(player_ckey)
|
||||
return GLOB.job_exempt_cache[player_ckey][job_title]
|
||||
|
||||
/**
|
||||
* Loads job exempt cache for ckey, for internal use
|
||||
*
|
||||
* Arguments:
|
||||
* * ckey - The ckey to load the cache for
|
||||
*/
|
||||
/proc/load_job_exempt_cache(ckey)
|
||||
if(GLOB.job_exempt_cache[ckey])
|
||||
return
|
||||
GLOB.job_exempt_cache[ckey] = list()
|
||||
// Load list from DB
|
||||
var/datum/db_query/get_query = SSdbcore.NewQuery(
|
||||
"SELECT jobs FROM [format_table_name("jobexempt")] WHERE ckey = :ckey",
|
||||
list("ckey" = ckey)
|
||||
)
|
||||
if(!get_query.warn_execute())
|
||||
qdel(get_query)
|
||||
return
|
||||
// Get first row value
|
||||
if(!get_query.NextRow())
|
||||
// If there's none then that means we havent inserted anything, so do that
|
||||
var/datum/db_query/insert_query = SSdbcore.NewQuery(
|
||||
"INSERT INTO [format_table_name("jobexempt")] (ckey, jobs) VALUES(:ckey, :jobs)",
|
||||
list("ckey" = ckey, "jobs" = "")
|
||||
)
|
||||
insert_query.Execute()
|
||||
qdel(insert_query)
|
||||
qdel(get_query)
|
||||
return
|
||||
// We got a value, split the string and set the job titles to TRUE in our cache
|
||||
var/list/string_list = splittext(get_query.item[1], ";")
|
||||
for(var/job_title in string_list)
|
||||
if(job_title == "")
|
||||
continue
|
||||
GLOB.job_exempt_cache[ckey][job_title] = TRUE
|
||||
qdel(get_query)
|
||||
|
||||
/**
|
||||
* Sets the job exempt state of a ckey to desired state
|
||||
*
|
||||
* Arguments:
|
||||
* * ckey - The ckey to set the state for
|
||||
* * job_title - The `job.title` of the state
|
||||
* * state - New TRUE or FALSE state to set it to
|
||||
*/
|
||||
/proc/set_job_exempt_state(ckey, job_title, state)
|
||||
if(!SSdbcore.Connect())
|
||||
return
|
||||
// Convert to ckey just in case we get called with player 'key'
|
||||
var/player_ckey = ckey(ckey)
|
||||
load_job_exempt_cache(player_ckey)
|
||||
// Set cache
|
||||
if(state)
|
||||
GLOB.job_exempt_cache[player_ckey][job_title] = TRUE
|
||||
else
|
||||
GLOB.job_exempt_cache[player_ckey] -= job_title
|
||||
// Set state in DB
|
||||
var/joined_string = ""
|
||||
for(var/title in GLOB.job_exempt_cache[player_ckey])
|
||||
if(joined_string == "")
|
||||
joined_string = title
|
||||
else
|
||||
joined_string += ";[title]"
|
||||
var/datum/db_query/query = SSdbcore.NewQuery(
|
||||
"UPDATE [format_table_name("jobexempt")] SET jobs = :jobs WHERE ckey = :ckey",
|
||||
list("jobs" = joined_string, "ckey" = player_ckey)
|
||||
)
|
||||
query.Execute(FALSE)
|
||||
qdel(query)
|
||||
|
||||
#define JOBS_PER_COLUMN 20
|
||||
|
||||
/**
|
||||
* Displays the job exempt menu UI to target admin user
|
||||
*
|
||||
* Arguments:
|
||||
* * user - The administrator mob to display the UI to
|
||||
* * target_ckey - The ckey to inspect and possibly modify the job exemption statuses
|
||||
*/
|
||||
/proc/show_job_exempt_menu(mob/user, target_ckey)
|
||||
if(!check_rights(R_ADMIN))
|
||||
return
|
||||
var/list/dat = list()
|
||||
if(!SSdbcore.Connect())
|
||||
dat += "Can't connect to the database"
|
||||
else
|
||||
dat += "Toggle playtime exemption for specific jobs for the ckey: [target_ckey]<HR>"
|
||||
var/job_count = 0
|
||||
dat += "<table width='100%'><tr><td width='33%' valign='top'>"
|
||||
for(var/datum/job_department/department as anything in SSjob.joinable_departments)
|
||||
if(job_count >= JOBS_PER_COLUMN)
|
||||
job_count -= JOBS_PER_COLUMN
|
||||
dat += "</td><td width='33%' valign='top'>"
|
||||
dat += "<b>[department.department_name]</b><br>"
|
||||
for(var/datum/job/job as anything in department.department_jobs)
|
||||
job_count++
|
||||
dat += "<a [is_job_exempt_from(target_ckey, job.title) ? "class='linkOn'" : ""] href='?_src_=holder;[HrefToken()];getjobexempttask=[target_ckey];task=togglejob;job=[job.title]'>[job.title]</a><br>"
|
||||
dat += "</tr></td></table>"
|
||||
var/datum/browser/popup = new(user, "job_exempt_menu", "Job Exemption Menu", 730, 650)
|
||||
popup.set_content(dat.Join())
|
||||
popup.open()
|
||||
|
||||
#undef JOBS_PER_COLUMN
|
||||
|
||||
/**
|
||||
* Topic handler for the job exempt menu
|
||||
*
|
||||
* Arguments:
|
||||
* * user - The administrator mob invoking the Topic
|
||||
* * href - The href token
|
||||
* * href_list - The href list
|
||||
* * target_ckey - The ckey to edit
|
||||
*/
|
||||
/proc/handle_job_exempt_menu_topic(mob/user, href, href_list, target_ckey)
|
||||
if(!check_rights(R_ADMIN))
|
||||
return
|
||||
switch(href_list["task"])
|
||||
if("togglejob")
|
||||
var/job_title = href_list["job"]
|
||||
var/newstate = !is_job_exempt_from(target_ckey, job_title)
|
||||
set_job_exempt_state(target_ckey, job_title, newstate)
|
||||
// Announce to admins which admin is modifying whose exemptions
|
||||
message_admins("[key_name_admin(user)] has [newstate ? "activated" : "deactivated"] job exp exempt status on ckey [target_ckey] for job: [job_title]")
|
||||
log_admin("[key_name(user)] has [newstate ? "activated" : "deactivated"] job exp exempt status on ckey [target_ckey] for job: [job_title]")
|
||||
// If a client whose job exemption is being modified, announce it to the player aswell
|
||||
var/client/client = GLOB.directory[target_ckey]
|
||||
if(client)
|
||||
to_chat(client, span_boldnotice("Job exemption status for [job_title] has been [newstate ? "activated" : "deactivated"]"))
|
||||
show_job_exempt_menu(user, target_ckey)
|
||||
@@ -8579,6 +8579,7 @@
|
||||
#include "modular_zubbers\modules\hydroponics\code\grown\rocks.dm"
|
||||
#include "modular_zubbers\modules\hydroponics\code\plantgenes\hydroponics.dm"
|
||||
#include "modular_zubbers\modules\hydroponics\code\vending\megaseed.dm"
|
||||
#include "modular_zubbers\modules\job_exempt\job_exempt.dm"
|
||||
#include "modular_zubbers\modules\jobs\code\job_types\quartermaster.dm"
|
||||
#include "modular_zubbers\modules\jobs\code\job_types\warden.dm"
|
||||
#include "modular_zubbers\modules\jobs\code\trims\jobs.dm"
|
||||
|
||||
Reference in New Issue
Block a user