Player Polls Revamp

This commit is contained in:
monster860
2017-02-25 18:54:06 -05:00
parent df1a5ef111
commit c044f0aa44
5 changed files with 526 additions and 198 deletions
+191 -73
View File
@@ -1,89 +1,206 @@
/client/proc/create_poll()
set name = "Create Server Poll"
set category = "Server"
if(!check_rights(R_PERMISSIONS))
if(!check_rights(R_SERVER))
return
if(!dbcon.IsConnected())
to_chat(src, "<span class='danger'>Failed to establish database connection.</span>")
return
var/returned = create_poll_function()
if(returned)
var/DBQuery/query_check_option = dbcon.NewQuery("SELECT id FROM [format_table_name("poll_option")] WHERE pollid = [returned]")
if(!query_check_option.Execute())
var/err = query_check_option.ErrorMsg()
log_game("SQL ERROR obtaining id from poll_option table. Error : \[[err]\]\n")
return
if(query_check_option.NextRow())
var/DBQuery/query_log_get = dbcon.NewQuery("SELECT polltype, question, adminonly FROM [format_table_name("poll_question")] WHERE id = [returned]")
if(!query_log_get.Execute())
var/err = query_log_get.ErrorMsg()
log_game("SQL ERROR obtaining polltype, question, adminonly from poll_question table. Error : \[[err]\]\n")
return
if(query_log_get.NextRow())
var/polltype = query_log_get.item[1]
var/question = query_log_get.item[2]
var/adminonly = query_log_get.item[3]
log_admin("[key_name(usr)] has created a new server poll. Poll Type: [polltype] - Admin Only: [adminonly ? "Yes" : "No"] - Question: [question]")
message_admins("[key_name_admin(usr)] has created a new server poll. Poll Type: [polltype] - Admin Only: [adminonly ? "Yes" : "No"]<br>Question: [question]")
else
to_chat(src, "Poll question created without any options, poll will be deleted.")
var/DBQuery/query_del_poll = dbcon.NewQuery("DELETE FROM [format_table_name("poll_question")] WHERE id = [returned]")
if(!query_del_poll.Execute())
var/err = query_del_poll.ErrorMsg()
log_game("SQL ERROR deleting poll question [returned]. Error : \[[err]\]\n")
return
create_poll_window()
/client/proc/create_poll_function()
if(!check_rights(R_PERMISSIONS))
/client/proc/create_poll_window(var/errormessage = "")
if(!check_rights(R_SERVER))
return
var/output={"<!DOCTYPE html>
<html>
<head>
<script>
var numoptions = 0;
function update_vis() {
var polloptions = document.getElementById("polloptions");
var polltype = document.getElementById("polltype").value;
if(polltype == "[POLLTYPE_TEXT]") {
polloptions.style.display = "none";
} else {
polloptions.style.display = "block";
}
if(polltype == "[POLLTYPE_RATING]") {
for(var i = 0; i < numoptions; i++) {
document.getElementById("ratingoption" + i).style.display = "block";
}
} else {
for(var i = 0; i < numoptions; i++) {
document.getElementById("ratingoption" + i).style.display = "none";
}
}
if(polltype == "[POLLTYPE_MULTI]") {
document.getElementById("choiceamount").style.display = "block";
} else {
document.getElementById("choiceamount").style.display = "none";
}
}
function add_option() {
document.getElementById("polloptionsinner").innerHTML += "<div id='polloption"+numoptions+"' style='border:1px solid black;padding:10px'>"+
"Option name: <input type='text' name='createpolloption"+numoptions+"option' value='' style='width:300px'></input><br>"+
"<label><input type='checkbox' name='createpolloption"+numoptions+"percentagecalc' value='1' checked>Calculate options results as percentage?</label><br>"+
"<div id='ratingoption"+numoptions+"'>"+
"Minimum rating value: <input type='text' name='createpolloption"+numoptions+"minval' value='1'></input><br>"+
"Maximum rating value: <input type='text' name='createpolloption"+numoptions+"maxval' value='5'></input><br>"+
"Minimum rating description: <input type='text' name='createpolloption"+numoptions+"descmin' value='Terrible'></input><br>"+
"Median rating description: <input type='text' name='createpolloption"+numoptions+"descmid' value=''></input><br>"+
"Maximum rating description: <input type='text' name='createpolloption"+numoptions+"descmax' value='Great'></input>"+
"</div>";
numoptions++;
document.getElementById("createpollnumoptions").value = numoptions+"";
update_vis();
}
function del_option() {
if(numoptions <= 1) {
return;
}
numoptions--;
document.getElementById("polloptionsinner").removeChild(document.getElementById("polloption"+numoptions));
document.getElementById("createpollnumoptions").value = numoptions+"";
update_vis();
}
function onload() {
update_vis();
add_option();
}
</script>
</head>
<body onload="onload()">
<div style='text-align:center'><b>Create Player Poll</b></div><hr>
<div style='text-align:center'>[errormessage]</div>
<form name='createpoll' action='byond://' method='post' style='padding-left:30px;padding-right:30px;padding-top:10px'>
<input type='hidden' name='createpollnumoptions' id='createpollnumoptions' value='0'>
<table><tr><td style='width:50%' style="vertical-align:top"><div id='polloptions'><div id='polloptionsinner'>
</div>
<input type='button' onclick='add_option()' value="Add Option"></input>
<input type='button' onclick='del_option()' value="Delete Option"></input>
</div></td><td style="vertical-align:top">
Select a poll type: <select name='createpoll' id='polltype' onchange="update_vis()">
<option value='[POLLTYPE_OPTION]'>POLLTYPE_OPTION</option>
<option value='[POLLTYPE_TEXT]'>POLLTYPE_TEXT</option>
<option value='[POLLTYPE_RATING]'>POLLTYPE_RATING</option>
<option value='[POLLTYPE_MULTI]'>POLLTYPE_MULTI</option>
</select><br>
For how many days should this poll run? <input type='text' name='createpollduration' value='7' style='width:50px'></input><br>
Enter your question: <input type='text' name='createpollquestion' value='' style='width:300px'></input><br>
<div id='choiceamount'>Up to how many options should be chosen? <input name='choiceamount' value='2' style='width:30px'></div>
<label><input type='checkbox' name='createpolladminonly' value='1'>Admin only?</label><br>
</td></tr><tr><td colspan=2 style='text-align:center'>
<input type='submit' value='Create poll'>
</td></tr></table>
</form>
</body>
</html>"}
src << browse(output, "window=createplayerpoll;size=950x500")
/client/proc/create_poll_function(href_list)
if(!check_rights(R_SERVER))
return
var/polltype = href_list["createpoll"]
if(polltype != POLLTYPE_OPTION && polltype != POLLTYPE_TEXT && polltype != POLLTYPE_RATING && polltype != POLLTYPE_MULTI)
create_poll_window("<font color='red'>Invalid poll type</font>")
return
var/polltype = input("Choose poll type.","Poll Type") in list("Single Option","Text Reply","Rating","Multiple Choice")
var/choice_amount = 0
switch(polltype)
if("Single Option")
polltype = POLLTYPE_OPTION
if("Text Reply")
polltype = POLLTYPE_TEXT
if("Rating")
polltype = POLLTYPE_RATING
if("Multiple Choice")
polltype = POLLTYPE_MULTI
choice_amount = input("How many choices should be allowed?","Select choice amount") as num|null
if(!choice_amount)
return
var/starttime = SQLtime()
var/endtime = input("Set end time for poll as format YYYY-MM-DD HH:MM:SS. All times in server time. HH:MM:SS is optional and 24-hour. Must be later than starting time for obvious reasons.", "Set end time", SQLtime()) as text
if(!endtime)
return
endtime = sanitizeSQL(endtime)
var/DBQuery/query_validate_time = dbcon.NewQuery("SELECT STR_TO_DATE('[endtime]','%Y-%c-%d %T')")
if(!query_validate_time.Execute())
var/err = query_validate_time.ErrorMsg()
log_game("SQL ERROR validating endtime. Error : \[[err]\]\n")
return
if(query_validate_time.NextRow())
endtime = query_validate_time.item[1]
if(!endtime)
to_chat(src, "Datetime entered is invalid.")
if(polltype == POLLTYPE_MULTI)
choice_amount = text2num(href_list["choiceamount"])
if(!isnum(choice_amount) || choice_amount < 1)
create_poll_window("<font color='red'>Invalid choice amount. Must be at least 1.</font>")
return
var/DBQuery/query_time_later = dbcon.NewQuery("SELECT TIMESTAMP('[endtime]') < NOW()")
if(!query_time_later.Execute())
var/err = query_time_later.ErrorMsg()
log_game("SQL ERROR comparing endtime to NOW(). Error : \[[err]\]\n")
var/poll_len = text2num(href_list["createpollduration"])
if(!isnum(poll_len) || poll_len < 1)
create_poll_window("<font color='red'>Invalid poll duration. Must be at least 1.</font>")
return
if(query_time_later.NextRow())
var/checklate = text2num(query_time_later.item[1])
if(checklate)
to_chat(src, "Datetime entered is not later than current server time.")
return
var/adminonly
switch(alert("Admin only poll?",,"Yes","No","Cancel"))
if("Yes")
adminonly = 1
if("No")
adminonly = 0
else
return
var/adminonly = text2num(href_list["createpolladminonly"]) ? 1 : 0
var/sql_ckey = sanitizeSQL(ckey)
var/question = href_list["createpollquestion"]
if(!question)
create_poll_window("<font color='red'>Question cannot be blank.</font>")
return
question = sanitizeSQL(question)
var/starttime
var/endtime
var/DBQuery/query = dbcon.NewQuery("SELECT Now() AS starttime, ADDDATE(Now(), INTERVAL [poll_len] DAY) AS endtime")
query.Execute()
while(query.NextRow())
starttime = query.item[1]
endtime = query.item[2]
var/pollquery = "INSERT INTO [format_table_name("poll_question")] (polltype, starttime, endtime, question, adminonly, multiplechoiceoptions, createdby_ckey, createdby_ip) VALUES ('[polltype]', '[starttime]', '[endtime]', '[question]', '[adminonly]', '[choice_amount]', '[sql_ckey]', '[address]')"
var/idquery = "SELECT id FROM [format_table_name("poll_question")] WHERE question = '[question]' AND starttime = '[starttime]' AND endtime = '[endtime]' AND createdby_ckey = '[sql_ckey]' AND createdby_ip = '[address]'"
var/list/option_queries = list()
if(polltype == POLLTYPE_MULTI || polltype == POLLTYPE_RATING || polltype == POLLTYPE_OPTION)
var/numoptions = text2num(href_list["createpollnumoptions"])
if(!numoptions)
create_poll_window("<font color='red'>Invalid number of options</font>")
return
for(var/I in 1 to numoptions)
var/option = href_list["createpolloption[I]option"]
if(!option)
create_poll_window("<font color='red'>Invalid option name for option [I]</font>")
return
option = sanitizeSQL(option)
var/percentagecalc = 0
if(text2num(href_list["createpolloption[I]percentagecalc"]))
percentagecalc = 1
var/minval = 0
var/maxval = 0
var/descmin = ""
var/descmid = ""
var/descmax = ""
if(polltype == POLLTYPE_RATING)
minval = text2num(href_list["createpolloption[I]minval"])
if(!minval)
create_poll_window("<font color='red'>Invalid minimum value for option [I]</font>")
return
maxval = text2num(href_list["createpolloption[I]maxval"])
if(!maxval)
create_poll_window("<font color='red'>Invalid maximum value for option [I]</font>")
return
if(minval >= maxval)
create_poll_window("<font color='red'>Minimum rating value can't be more than maximum rating value</font>")
return
descmin = href_list["createpolloption[I]descmin"]
if(descmin)
descmin = sanitizeSQL(descmin)
descmid = href_list["createpolloption[I]descmid"]
if(descmid)
descmid = sanitizeSQL(descmid)
descmax = href_list["createpolloption[I]descmax"]
if(descmax)
descmax = sanitizeSQL(descmax)
option_queries += "INSERT INTO [format_table_name("poll_option")] (pollid, text, percentagecalc, minval, maxval, descmin, descmid, descmax) VALUES ('{POLLID}', '[option]', '[percentagecalc]', '[minval]', '[maxval]', '[descmin]', '[descmid]', '[descmax]')"
query = dbcon.NewQuery(pollquery)
if(!query.Execute())
var/err = query.ErrorMsg()
create_poll_window("<font color='red'>An SQL error has occured while creating your poll</font>")
log_game("SQL ERROR adding new poll question to table. Error : \[[err]\]\n")
return
var/pollid = 0
query = dbcon.NewQuery(idquery)
if(!query.Execute())
var/err = query.ErrorMsg()
create_poll_window("<font color='red'>An SQL error has occured while creating your poll</font>")
log_game("SQL ERROR obtaining id from poll_question table. Error : \[[err]\]\n")
return
if(query.NextRow())
pollid = text2num(query.item[1])
for(var/querytext in option_queries)
query = dbcon.NewQuery(replacetext(idquery, "{POLLID}", pollid))
if(!query.Execute())
var/err = query.ErrorMsg()
create_poll_window("<font color='red'>An SQL error has occured while creating your poll</font>")
log_game("SQL ERROR obtaining id from poll_question table. Error : \[[err]\]\n")
return
create_poll_window("<font color='#008800'>Your poll has been successfully created</font>")
return pollid
/*
var/question = input("Write your question","Question") as message|null
if(!question)
return
@@ -159,4 +276,5 @@
add_option = 1
if("Finish")
add_option = 0
*/
return pollid
+69
View File
@@ -219,7 +219,76 @@
if("usr") hsrc = mob
if("prefs") return prefs.process_link(usr,href_list)
if("vars") return view_var_Topic(href,href_list,hsrc)
//Polls and shit
if(href_list["showpoll"])
handle_player_polling()
return
if(href_list["createpollwindow"])
create_poll_window()
return
if(href_list["createpoll"])
create_poll_function(href_list)
return
if(href_list["pollid"])
var/pollid = href_list["pollid"]
if(istext(pollid))
pollid = text2num(pollid)
if(isnum(pollid))
poll_player(pollid)
return
if(href_list["pollresults"])
var/pollid = href_list["pollresults"]
if(istext(pollid))
pollid = text2num(pollid)
if(isnum(pollid))
poll_results(pollid)
if(href_list["votepollid"] && href_list["votetype"])
if(!can_vote())
return // No voting.
var/pollid = text2num(href_list["votepollid"])
var/votetype = href_list["votetype"]
switch(votetype)
if("OPTION")
var/optionid = text2num(href_list["voteoptionid"])
vote_on_poll(pollid, optionid)
if("TEXT")
var/replytext = href_list["replytext"]
log_text_poll_reply(pollid, replytext)
if("NUMVAL")
var/id_min = text2num(href_list["minid"])
var/id_max = text2num(href_list["maxid"])
if( (id_max - id_min) > 100 ) //Basic exploit prevention
to_chat(usr, "The option ID difference is too big. Please contact administration or the database admin.")
return
for(var/optionid = id_min; optionid <= id_max; optionid++)
if(!isnull(href_list["o[optionid]"])) //Test if this optionid was replied to
var/rating
if(href_list["o[optionid]"] == "abstain")
rating = null
else
rating = text2num(href_list["o[optionid]"])
if(!isnum(rating))
return
vote_on_numval_poll(pollid, optionid, rating)
if("MULTICHOICE")
var/id_min = text2num(href_list["minoptionid"])
var/id_max = text2num(href_list["maxoptionid"])
if( (id_max - id_min) > 100 ) //Basic exploit prevention
to_chat(usr, "The option ID difference is too big. Please contact administration or the database admin.")
return
for(var/optionid = id_min; optionid <= id_max; optionid++)
if(!isnull(href_list["option_[optionid]"])) //Test if this optionid was selected
vote_on_poll(pollid, optionid, 1)
src << browse(null, "window=playerpoll")
handle_player_polling()
switch(href_list["action"])
if("openLink")
+17
View File
@@ -30,6 +30,23 @@
callHook("mob_login", list("client" = client, "mob" = src))
new_player_panel()
spawn(30)
// Annoy the player with polls.
establish_db_connection()
if(dbcon.IsConnected() && client.can_vote())
var/isadmin = 0
if(client && client.holder)
isadmin = 1
var/DBQuery/query = dbcon.NewQuery("SELECT id FROM [format_table_name("poll_question")] WHERE [(isadmin ? "" : "adminonly = false AND")] Now() BETWEEN starttime AND endtime AND id NOT IN (SELECT pollid FROM [format_table_name("poll_vote")] WHERE ckey = \"[ckey]\") AND id NOT IN (SELECT pollid FROM [format_table_name("poll_textreply")] WHERE ckey = \"[ckey]\")")
query.Execute()
var/newpoll = 0
while(query.NextRow())
newpoll = 1
break
if(newpoll)
client.handle_player_polling()
if(ckey in deadmins)
verbs += /client/proc/readmin
spawn(40)
+3 -58
View File
@@ -42,7 +42,7 @@
if(!IsGuestKey(src.key))
establish_db_connection()
if(dbcon.IsConnected())
if(dbcon.IsConnected() && client.can_vote())
var/isadmin = 0
if(src.client && src.client.holder)
isadmin = 1
@@ -54,9 +54,9 @@
break
if(newpoll)
output += "<p><b><a href='byond://?src=[UID()];showpoll=1'>Show Player Polls</A> (NEW!)</b></p>"
output += "<p><b><a href='byond://?showpoll=1'>Show Player Polls</A> (NEW!)</b></p>"
else
output += "<p><a href='byond://?src=[UID()];showpoll=1'>Show Player Polls</A></p>"
output += "<p><a href='byond://?showpoll=1'>Show Player Polls</A></p>"
output += "</center>"
@@ -188,61 +188,6 @@
else if(!href_list["late_join"])
new_player_panel()
if(href_list["showpoll"])
handle_player_polling()
return
if(href_list["pollid"])
var/pollid = href_list["pollid"]
if(istext(pollid))
pollid = text2num(pollid)
if(isnum(pollid))
src.poll_player(pollid)
return
if(href_list["votepollid"] && href_list["votetype"])
var/pollid = text2num(href_list["votepollid"])
var/votetype = href_list["votetype"]
switch(votetype)
if("OPTION")
var/optionid = text2num(href_list["voteoptionid"])
vote_on_poll(pollid, optionid)
if("TEXT")
var/replytext = href_list["replytext"]
log_text_poll_reply(pollid, replytext)
if("NUMVAL")
var/id_min = text2num(href_list["minid"])
var/id_max = text2num(href_list["maxid"])
if( (id_max - id_min) > 100 ) //Basic exploit prevention
to_chat(usr, "The option ID difference is too big. Please contact administration or the database admin.")
return
for(var/optionid = id_min; optionid <= id_max; optionid++)
if(!isnull(href_list["o[optionid]"])) //Test if this optionid was replied to
var/rating
if(href_list["o[optionid]"] == "abstain")
rating = null
else
rating = text2num(href_list["o[optionid]"])
if(!isnum(rating))
return
vote_on_numval_poll(pollid, optionid, rating)
if("MULTICHOICE")
var/id_min = text2num(href_list["minoptionid"])
var/id_max = text2num(href_list["maxoptionid"])
if( (id_max - id_min) > 100 ) //Basic exploit prevention
to_chat(usr, "The option ID difference is too big. Please contact administration or the database admin.")
return
for(var/optionid = id_min; optionid <= id_max; optionid++)
if(!isnull(href_list["option_[optionid]"])) //Test if this optionid was selected
vote_on_poll(pollid, optionid, 1)
/mob/new_player/proc/IsJobAvailable(rank)
var/datum/job/job = job_master.GetJob(rank)
if(!job) return 0
+246 -67
View File
@@ -2,45 +2,208 @@
var/optionid
var/optiontext
/mob/new_player/proc/handle_player_polling()
/client/verb/polls_verb()
set name = "Show Player Polls"
set category = "OOC"
handle_player_polling()
/client/proc/can_vote()
return player_age >= 30
/client/proc/handle_player_polling()
establish_db_connection()
if(dbcon.IsConnected())
var/isadmin = 0
if(src.client && src.client.holder)
if(holder)
isadmin = 1
var/DBQuery/select_query = dbcon.NewQuery("SELECT id, question FROM [format_table_name("poll_question")] WHERE [(isadmin ? "" : "adminonly = false AND")] Now() BETWEEN starttime AND endtime")
var/DBQuery/select_query = dbcon.NewQuery("SELECT id, question, (id IN (SELECT pollid FROM [format_table_name("poll_vote")] WHERE ckey = '[ckey]') OR id IN (SELECT pollid FROM [format_table_name("poll_textreply")] WHERE ckey = '[ckey]')) AS voted FROM [format_table_name("poll_question")] WHERE [(isadmin ? "" : "adminonly = false AND")] Now() BETWEEN starttime AND endtime")
select_query.Execute()
var/output = "<div align='center'><B>Player polls</B>"
if(check_rights(R_SERVER))
output += "(<a href='?createpollwindow=1'>Create new poll</a>)"
output +="<hr>"
var/pollid
var/pollquestion
output += "<table>"
var/color1 = "#ececec"
var/color2 = "#e2e2e2"
var/i = 0
output += "<tr><th>Active Polls</th></tr>"
while(select_query.NextRow())
pollid = select_query.item[1]
pollquestion = select_query.item[2]
output += "<tr bgcolor='[ (i % 2 == 1) ? color1 : color2 ]'><td><a href=\"byond://?src=[UID()];pollid=[pollid]\"><b>[pollquestion]</b></a></td></tr>"
var/pollid = select_query.item[1]
var/pollquestion = select_query.item[2]
var/voted = text2num(select_query.item[3])
output += "<tr bgcolor='[(i % 2 == 1) ? color1 : color2 ]'><td><a href=\"byond://?pollid=[pollid]\"><b>[pollquestion]</b></a></td></tr>"
if(can_vote() && !voted)
output += "<tr><td>[poll_player(pollid, 1)]</tr></td>"
i++
// Show expired polls. Non admins can view admin polls at this stage
// (just like tgstation's web interface so don't complain)
// (Also why was there no ingame interface tg not having an ingame
// interface is retarded because it cucks downstreams)
select_query = dbcon.NewQuery("SELECT id, question FROM [format_table_name("poll_question")] WHERE Now() > endtime ORDER BY id DESC")
select_query.Execute()
output += "<tr><th>Expired Polls</th></tr>"
while(select_query.NextRow())
var/pollid = select_query.item[1]
var/pollquestion = select_query.item[2]
output += "<tr bgcolor='[(i % 2 == 1) ? color1 : color2]'><td><a href=\"byond://?pollresults=[pollid]\"><b>[pollquestion]</b></a></td></tr>"
output += "</table>"
src << browse(output,"window=playerpolllist;size=500x300")
/client/proc/poll_results(var/pollid = -1)
if(pollid == -1)
return
establish_db_connection()
if(!dbcon.IsConnected())
return
var/DBQuery/select_query = dbcon.NewQuery("SELECT polltype, question, adminonly, multiplechoiceoptions, starttime, endtime FROM [format_table_name("poll_question")] WHERE id = [pollid] AND endtime < Now()")
select_query.Execute()
var/question = ""
var/polltype = ""
var/adminonly = 0
var/multiplechoiceoptions = 0
var/starttime = ""
var/endtime = ""
var/found = 0
while(select_query.NextRow())
polltype = select_query.item[1]
question = select_query.item[2]
adminonly = text2num(select_query.item[3])
multiplechoiceoptions = text2num(select_query.item[4])
starttime = select_query.item[5]
endtime = select_query.item[6]
found = 1
break
if(!found)
to_chat(src, "<span class='warning'>Poll question details not found. (Maybe the poll isn't expired yet?)</span>")
return
if(polltype == POLLTYPE_MULTI)
question += " (Choose up to [multiplechoiceoptions] options)"
if(adminonly)
question = "(<font color='#997700'>Admin only poll</font>) " + question
var output = "<!DOCTYPE html><html><body>"
if(polltype == POLLTYPE_MULTI || polltype == POLLTYPE_OPTION)
select_query = dbcon.NewQuery("SELECT text, percentagecalc, (SELECT COUNT(optionid) FROM [format_table_name("poll_vote")] WHERE optionid = poll_option.id GROUP BY optionid) AS votecount FROM [format_table_name("poll_option")] WHERE pollid = [pollid]");
select_query.Execute()
var/list/options = list()
var/total_votes = 1
var/total_percent_votes = 1
var/max_votes = 1
while(select_query.NextRow())
var/text = select_query.item[1]
var/percentagecalc = select_query.item[2]
var/votecount = text2num(select_query.item[3])
if(percentagecalc)
total_percent_votes += votecount
total_votes += votecount
if(votecount > max_votes)
max_votes = votecount
options[++options.len] = list(text, percentagecalc, votecount)
// fuck ie.
output += {"
<table width='900' align='center' bgcolor='#eeffee' cellspacing='0' cellpadding='4'>
<tr bgcolor='#ddffdd'>
<th colspan='4' align='center'>[question]<br><font size='1'><b>[starttime] - [endtime]</b></font></th>
</tr>
<tr bgcolor='#ddffdd'>
<th colspan='4' align='center'><div style='width:700px;position:relative'>"}
var/list/colors = list("#66c2a5", "#fc8d62", "#8da0cb", "#e78ac3", "#a6d854", "#ffd92f", "#e5c494", "#b3b3b3")
var/color_index = 0
for(var/list/option in options)
var/bar_width = option[3] * 700 / total_votes
var/percentage = option[2] ? "[round(option[3] * 100 / total_percent_votes)]%" : "N/A"
color_index++
if(color_index > colors.len)
color_index = 1
output += "<div style='width:[bar_width]px;height:[5]px;background-color:[colors[color_index]];float:left' title='[option[1]] ([percentage])'></div>"
output += "</div><br><font size='2'><b>(Hover over the colored bar to read description)</b></font></tr>"
for(var/list/option in options)
var/bar_width = option[3] * 390 / max_votes
var/percentage = option[2] ? "[round(option[3] * 100 / total_percent_votes)]%" : "N/A"
output += "<tr><td width='300' align='right'>[option[1]]</td>"
output += "<td width='100' align='center'><b>[option[3]]</b></td>"
output += "<td width='100' align='center'><b>[percentage]</b></td>"
output += "<td width='400' align='left'><div style='width:[bar_width]px;height:10px;display:inline-block;background-color:#08b000'></div></td>"
output += "</table>"
if(polltype == POLLTYPE_RATING)
output += {"
<table width='900' align='center' bgcolor='#eeffee' cellspacing='0' cellpadding='4'>
<tr bgcolor='#ddffdd'>
<th colspan='4' align='center'>[question]<br><font size='1'><b>[starttime] - [endtime]</b></font></th>
</tr>"}
select_query = dbcon.NewQuery("SELECT id, text, (SELECT AVG(rating) FROM [format_table_name("poll_vote")] WHERE optionid = poll_option.id AND rating != 'abstain') AS avgrating, (SELECT COUNT(rating) FROM [format_table_name("poll_vote")] WHERE optionid = poll_option.id AND rating != 'abstain') AS countvotes, minval, maxval FROM [format_table_name("poll_option")] WHERE pollid = [pollid]")
select_query.Execute()
while(select_query.NextRow())
output += {"
<tr>
<td align='right' width='300'>[select_query.item[2]]</th>
<td align='center' width='100'><b>N = [select_query.item[4]]</b></th>
<td align='center' width='100'><b>AVG = [select_query.item[3]]</b></th>
<td align='left' width='400'><table width='400 style='table-layout: fixed'>"}
var/optionid = select_query.item[1]
var/totalvotes = text2num(select_query.item[4])
var/minval = text2num(select_query.item[5])
var/maxval = text2num(select_query.item[6])
var/maxvote = 1
var/list/votecounts = list()
for(var/I in minval to maxval)
var/DBQuery/rating_query = dbcon.NewQuery("SELECT COUNT(rating) AS countrating FROM [format_table_name("poll_vote")] WHERE optionid = [optionid] AND rating = [I] GROUP BY rating")
rating_query.Execute()
var/votecount = 0
while(rating_query.NextRow())
votecount = text2num(rating_query.item[1])
votecounts["[I]"] = votecount
if(votecount > maxvote)
maxvote = votecount
for(var/I in minval to maxval)
var/votecount = votecounts["[I]"]
var/bar_width = votecount * 200 / maxvote
output += {"
<tr>
<td align='center' width='50'><b>[I]</b></td>
<td align='center' width='50'>[votecount]</td>
<td align='center' width='75'>([votecount / totalvotes]%)</td>
<td width='200'><div style='width:[bar_width]px;height:10px;display:inline-block;background-color:#08b000'></div></td>
</tr>"}
output += "</table></td></tr>"
output += "</table>"
if(polltype == POLLTYPE_TEXT)
select_query = dbcon.NewQuery("SELECT replytext, COUNT(replytext) AS countresponse, GROUP_CONCAT(DISTINCT ckey SEPARATOR ', ') as ckeys FROM [format_table_name("poll_textreply")] WHERE pollid = [pollid] GROUP BY replytext ORDER BY countresponse DESC");
select_query.Execute()
output += {"
<table width='900' align='center' bgcolor='#eeffee' cellspacing='0' cellpadding='4'>
<tr bgcolor='#ddffdd'>
<th colspan='2' align='center'>[question]<br><font size='1'><b>[starttime] - [endtime]</b></font></th>
</tr>"}
while(select_query.NextRow())
var/replytext = select_query.item[1]
var/countresponse = select_query.item[2]
var/ckeys = select_query.item[3]
output += {"
<tr>
<td>[ckeys] ([countresponse] player\s) responded with:</td>
<td style='border:1px solid #888888'>[replytext]</td>
</tr>"}
output += "</table>"
output += "</body></html>"
src << browse(output,"window=pollresults;size=950x500")
/mob/new_player/proc/poll_player(var/pollid = -1)
/client/proc/poll_player(var/pollid = -1, var/inline = 0)
if(pollid == -1) return
establish_db_connection()
if(dbcon.IsConnected())
var/DBQuery/select_query = dbcon.NewQuery("SELECT starttime, endtime, question, polltype, multiplechoiceoptions FROM [format_table_name("poll_question")] WHERE id = [pollid]")
var/DBQuery/select_query = dbcon.NewQuery("SELECT starttime, endtime, question, polltype, multiplechoiceoptions FROM [format_table_name("poll_question")] WHERE id = [pollid] AND Now() BETWEEN starttime AND endtime [holder ? "AND adminonly = 0" : ""]")
select_query.Execute()
var/pollstarttime = ""
@@ -49,6 +212,7 @@
var/polltype = ""
var/found = 0
var/multiplechoiceoptions = 0
var/canvote = can_vote()
while(select_query.NextRow())
pollstarttime = select_query.item[1]
@@ -59,16 +223,16 @@
break
if(!found)
to_chat(usr, "\red Poll question details not found.")
to_chat(usr, "<span class='warning'>Poll question details not found. (Maybe you do not have access?)</span>")
return
switch(polltype)
//Polls that have enumerated options
if(POLLTYPE_OPTION)
var/DBQuery/voted_query = dbcon.NewQuery("SELECT optionid FROM [format_table_name("poll_vote")] WHERE pollid = [pollid] AND ckey = '[usr.ckey]'")
var/DBQuery/voted_query = dbcon.NewQuery("SELECT optionid FROM [format_table_name("poll_vote")] WHERE pollid = [pollid] AND ckey = '[ckey]'")
voted_query.Execute()
var/voted = 0
var/voted = 0 // If the can't vote then consider them voted
var/votedoptionid = 0
while(voted_query.NextRow())
votedoptionid = text2num(voted_query.item[1])
@@ -84,22 +248,23 @@
PO.optionid = text2num(options_query.item[1])
PO.optiontext = options_query.item[2]
options += PO
var/output = "<div align='center'><B>Player poll</B>"
output +="<hr>"
var/output
if(!inline)
output += "<div align='center'><B>Player poll</B>"
output +="<hr>"
output += "<b>Question: [pollquestion]</b><br>"
output += "<font size='2'>Poll runs from <b>[pollstarttime]</b> until <b>[pollendtime]</b></font><p>"
if(!voted) //Only make this a form if we have not voted yet
output += "<form name='cardcomp' action='?src=[UID()]' method='get'>"
output += "<input type='hidden' name='src' value='[UID()]'>"
if(canvote && !voted) //Only make this a form if we have not voted yet
output += "<form name='cardcomp' action='byond://' method='get'>"
output += "<input type='hidden' name='votepollid' value='[pollid]'>"
output += "<input type='hidden' name='votetype' value='OPTION'>"
output += "<table><tr><td>"
for(var/datum/polloption/O in options)
if(O.optionid && O.optiontext)
if(voted)
if(voted || !canvote)
if(votedoptionid == O.optionid)
output += "<b>[O.optiontext]</b><br>"
else
@@ -108,17 +273,20 @@
output += "<input type='radio' name='voteoptionid' value='[O.optionid]'> [O.optiontext]<br>"
output += "</td></tr></table>"
if(!voted) //Only make this a form if we have not voted yet
if(canvote && !voted) //Only make this a form if we have not voted yet
output += "<p><input type='submit' value='Vote'>"
output += "</form>"
output += "</div>"
src << browse(output,"window=playerpoll;size=500x250")
if(inline)
return output
else
src << browse(output,"window=playerpoll;size=500x250")
//Polls with a text input
if(POLLTYPE_TEXT)
var/DBQuery/voted_query = dbcon.NewQuery("SELECT replytext FROM [format_table_name("poll_textreply")] WHERE pollid = [pollid] AND ckey = '[usr.ckey]'")
var/DBQuery/voted_query = dbcon.NewQuery("SELECT replytext FROM [format_table_name("poll_textreply")] WHERE pollid = [pollid] AND ckey = '[ckey]'")
voted_query.Execute()
var/voted = 0
@@ -128,15 +296,16 @@
voted = 1
break
var/output = "<div align='center'><B>Player poll</B>"
output +="<hr>"
var/output
if(!inline)
output += "<div align='center'><B>Player poll</B>"
output +="<hr>"
output += "<b>Question: [pollquestion]</b><br>"
output += "<font size='2'>Feedback gathering runs from <b>[pollstarttime]</b> until <b>[pollendtime]</b></font><p>"
if(!voted) //Only make this a form if we have not voted yet
output += "<form name='cardcomp' action='?src=[UID()]' method='get'>"
output += "<input type='hidden' name='src' value='[UID()]'>"
if(canvote && !voted) //Only make this a form if we have not voted yet
output += "<form name='cardcomp' action='byond://' method='get'>"
output += "<input type='hidden' name='votepollid' value='[pollid]'>"
output += "<input type='hidden' name='votetype' value='TEXT'>"
@@ -146,8 +315,7 @@
output += "<p><input type='submit' value='Submit'>"
output += "</form>"
output += "<form name='cardcomp' action='?src=[UID()]' method='get'>"
output += "<input type='hidden' name='src' value='[UID()]'>"
output += "<form name='cardcomp' action='byond://' method='get'>"
output += "<input type='hidden' name='votepollid' value='[pollid]'>"
output += "<input type='hidden' name='votetype' value='TEXT'>"
output += "<input type='hidden' name='replytext' value='ABSTAIN'>"
@@ -155,16 +323,21 @@
output += "</form>"
else
output += "[vote_text]"
src << browse(output,"window=playerpoll;size=500x500")
if(inline)
return output
else
src << browse(output,"window=playerpoll;size=500x500")
//Polls with a text input
if(POLLTYPE_RATING)
var/DBQuery/voted_query = dbcon.NewQuery("SELECT o.text, v.rating FROM [format_table_name("poll_option")] o, erro_poll_vote v WHERE o.pollid = [pollid] AND v.ckey = '[usr.ckey]' AND o.id = v.optionid")
var/DBQuery/voted_query = dbcon.NewQuery("SELECT o.text, v.rating FROM [format_table_name("poll_option")] o, erro_poll_vote v WHERE o.pollid = [pollid] AND v.ckey = '[ckey]' AND o.id = v.optionid")
voted_query.Execute()
var/output = "<div align='center'><B>Player poll</B>"
output +="<hr>"
var/output
if(!inline)
output += "<div align='center'><B>Player poll</B>"
output +="<hr>"
output += "<b>Question: [pollquestion]</b><br>"
output += "<font size='2'>Poll runs from <b>[pollstarttime]</b> until <b>[pollendtime]</b></font><p>"
@@ -177,9 +350,8 @@
output += "<br><b>[optiontext] - [rating]</b>"
if(!voted) //Only make this a form if we have not voted yet
output += "<form name='cardcomp' action='?src=[UID()]' method='get'>"
output += "<input type='hidden' name='src' value='[UID()]'>"
if(canvote && !voted) //Only make this a form if we have not voted yet
output += "<form name='cardcomp' action='byond://' method='get'>"
output += "<input type='hidden' name='votepollid' value='[pollid]'>"
output += "<input type='hidden' name='votetype' value='NUMVAL'>"
@@ -227,9 +399,12 @@
output += "<p><input type='submit' value='Submit'>"
output += "</form>"
src << browse(output,"window=playerpoll;size=500x500")
if(inline)
return output
else
src << browse(output,"window=playerpoll;size=500x500")
if(POLLTYPE_MULTI)
var/DBQuery/voted_query = dbcon.NewQuery("SELECT optionid FROM [format_table_name("poll_vote")] WHERE pollid = [pollid] AND ckey = '[usr.ckey]'")
var/DBQuery/voted_query = dbcon.NewQuery("SELECT optionid FROM [format_table_name("poll_vote")] WHERE pollid = [pollid] AND ckey = '[ckey]'")
voted_query.Execute()
var/list/votedfor = list()
@@ -258,14 +433,15 @@
if(select_query.item[5])
multiplechoiceoptions = text2num(select_query.item[5])
var/output = "<div align='center'><B>Player poll</B>"
output +="<hr>"
var/output
if(!inline)
output += "<div align='center'><B>Player poll</B>"
output +="<hr>"
output += "<b>Question: [pollquestion]</b><br>You can select up to [multiplechoiceoptions] options. If you select more, the first [multiplechoiceoptions] will be saved.<br>"
output += "<font size='2'>Poll runs from <b>[pollstarttime]</b> until <b>[pollendtime]</b></font><p>"
if(!voted) //Only make this a form if we have not voted yet
output += "<form name='cardcomp' action='?src=[UID()]' method='get'>"
output += "<input type='hidden' name='src' value='[UID()]'>"
if(canvote && !voted) //Only make this a form if we have not voted yet
output += "<form name='cardcomp' action='byond://' method='get'>"
output += "<input type='hidden' name='votepollid' value='[pollid]'>"
output += "<input type='hidden' name='votetype' value='MULTICHOICE'>"
output += "<input type='hidden' name='maxoptionid' value='[maxoptionid]'>"
@@ -274,7 +450,7 @@
output += "<table><tr><td>"
for(var/datum/polloption/O in options)
if(O.optionid && O.optiontext)
if(voted)
if(canvote && voted)
if(O.optionid in votedfor)
output += "<b>[O.optiontext]</b><br>"
else
@@ -283,16 +459,19 @@
output += "<input type='checkbox' name='option_[O.optionid]' value='[O.optionid]'> [O.optiontext]<br>"
output += "</td></tr></table>"
if(!voted) //Only make this a form if we have not voted yet
if(canvote && !voted) //Only make this a form if we have not voted yet
output += "<p><input type='submit' value='Vote'>"
output += "</form>"
output += "</div>"
src << browse(output,"window=playerpoll;size=600x250")
if(inline)
return output
else
src << browse(output,"window=playerpoll;size=600x250")
return
/mob/new_player/proc/vote_on_poll(var/pollid = -1, var/optionid = -1, var/multichoice = 0)
/client/proc/vote_on_poll(var/pollid = -1, var/optionid = -1, var/multichoice = 0)
if(pollid == -1 || optionid == -1)
return
@@ -301,7 +480,7 @@
establish_db_connection()
if(dbcon.IsConnected())
var/DBQuery/select_query = dbcon.NewQuery("SELECT starttime, endtime, question, polltype, multiplechoiceoptions FROM [format_table_name("poll_question")] WHERE id = [pollid] AND Now() BETWEEN starttime AND endtime")
var/DBQuery/select_query = dbcon.NewQuery("SELECT starttime, endtime, question, polltype, multiplechoiceoptions FROM [format_table_name("poll_question")] WHERE id = [pollid] AND Now() BETWEEN starttime AND endtime [holder ? "AND adminonly = 0" : ""]")
select_query.Execute()
var/validpoll = 0
@@ -334,7 +513,7 @@
var/alreadyvoted = 0
var/DBQuery/voted_query = dbcon.NewQuery("SELECT id FROM [format_table_name("poll_vote")] WHERE pollid = [pollid] AND ckey = '[usr.ckey]'")
var/DBQuery/voted_query = dbcon.NewQuery("SELECT id FROM [format_table_name("poll_vote")] WHERE pollid = [pollid] AND ckey = '[ckey]'")
voted_query.Execute()
while(voted_query.NextRow())
@@ -355,14 +534,14 @@
adminrank = usr.client.holder.rank
var/DBQuery/insert_query = dbcon.NewQuery("INSERT INTO [format_table_name("poll_vote")] (id ,datetime ,pollid ,optionid ,ckey ,ip ,adminrank) VALUES (null, Now(), [pollid], [optionid], '[usr.ckey]', '[usr.client.address]', '[adminrank]')")
var/DBQuery/insert_query = dbcon.NewQuery("INSERT INTO [format_table_name("poll_vote")] (id ,datetime ,pollid ,optionid ,ckey ,ip ,adminrank) VALUES (null, Now(), [pollid], [optionid], '[ckey]', '[usr.client.address]', '[adminrank]')")
insert_query.Execute()
to_chat(usr, "\blue Vote successful.")
usr << browse(null,"window=playerpoll")
/mob/new_player/proc/log_text_poll_reply(var/pollid = -1, var/replytext = "")
/client/proc/log_text_poll_reply(var/pollid = -1, var/replytext = "")
if(pollid == -1 || replytext == "")
return
@@ -371,7 +550,7 @@
establish_db_connection()
if(dbcon.IsConnected())
var/DBQuery/select_query = dbcon.NewQuery("SELECT starttime, endtime, question, polltype FROM [format_table_name("poll_question")] WHERE id = [pollid] AND Now() BETWEEN starttime AND endtime")
var/DBQuery/select_query = dbcon.NewQuery("SELECT starttime, endtime, question, polltype FROM [format_table_name("poll_question")] WHERE id = [pollid] AND Now() BETWEEN starttime AND endtime [holder ? "AND adminonly = 0" : ""]")
select_query.Execute()
var/validpoll = 0
@@ -388,7 +567,7 @@
var/alreadyvoted = 0
var/DBQuery/voted_query = dbcon.NewQuery("SELECT id FROM [format_table_name("poll_textreply")] WHERE pollid = [pollid] AND ckey = '[usr.ckey]'")
var/DBQuery/voted_query = dbcon.NewQuery("SELECT id FROM [format_table_name("poll_textreply")] WHERE pollid = [pollid] AND ckey = '[ckey]'")
voted_query.Execute()
while(voted_query.NextRow())
@@ -413,14 +592,14 @@
to_chat(usr, "The text you entered was blank, contained illegal characters or was too long. Please correct the text and submit again.")
return
var/DBQuery/insert_query = dbcon.NewQuery("INSERT INTO [format_table_name("poll_textreply")] (id ,datetime ,pollid ,ckey ,ip ,replytext ,adminrank) VALUES (null, Now(), [pollid], '[usr.ckey]', '[usr.client.address]', '[replytext]', '[adminrank]')")
var/DBQuery/insert_query = dbcon.NewQuery("INSERT INTO [format_table_name("poll_textreply")] (id ,datetime ,pollid ,ckey ,ip ,replytext ,adminrank) VALUES (null, Now(), [pollid], '[ckey]', '[usr.client.address]', '[replytext]', '[adminrank]')")
insert_query.Execute()
to_chat(usr, "\blue Feedback logging successful.")
usr << browse(null,"window=playerpoll")
/mob/new_player/proc/vote_on_numval_poll(var/pollid = -1, var/optionid = -1, var/rating = null)
/client/proc/vote_on_numval_poll(var/pollid = -1, var/optionid = -1, var/rating = null)
if(pollid == -1 || optionid == -1)
return
@@ -429,7 +608,7 @@
establish_db_connection()
if(dbcon.IsConnected())
var/DBQuery/select_query = dbcon.NewQuery("SELECT starttime, endtime, question, polltype FROM [format_table_name("poll_question")] WHERE id = [pollid] AND Now() BETWEEN starttime AND endtime")
var/DBQuery/select_query = dbcon.NewQuery("SELECT starttime, endtime, question, polltype FROM [format_table_name("poll_question")] WHERE id = [pollid] AND Now() BETWEEN starttime AND endtime [holder ? "AND adminonly = 0" : ""]")
select_query.Execute()
var/validpoll = 0
@@ -459,7 +638,7 @@
var/alreadyvoted = 0
var/DBQuery/voted_query = dbcon.NewQuery("SELECT id FROM [format_table_name("poll_vote")] WHERE optionid = [optionid] AND ckey = '[usr.ckey]'")
var/DBQuery/voted_query = dbcon.NewQuery("SELECT id FROM [format_table_name("poll_vote")] WHERE optionid = [optionid] AND ckey = '[ckey]'")
voted_query.Execute()
while(voted_query.NextRow())
@@ -475,7 +654,7 @@
adminrank = usr.client.holder.rank
var/DBQuery/insert_query = dbcon.NewQuery("INSERT INTO [format_table_name("poll_vote")] (id ,datetime ,pollid ,optionid ,ckey ,ip ,adminrank, rating) VALUES (null, Now(), [pollid], [optionid], '[usr.ckey]', '[usr.client.address]', '[adminrank]', [(isnull(rating)) ? "null" : rating])")
var/DBQuery/insert_query = dbcon.NewQuery("INSERT INTO [format_table_name("poll_vote")] (id ,datetime ,pollid ,optionid ,ckey ,ip ,adminrank, rating) VALUES (null, Now(), [pollid], [optionid], '[ckey]', '[usr.client.address]', '[adminrank]', [(isnull(rating)) ? "null" : rating])")
insert_query.Execute()
to_chat(usr, "\blue Vote successful.")