poll.pwn 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398
  1. /*
  2. /$$ /$$ /$$$$$$ /$$$$$$$ /$$$$$$$
  3. | $$$ | $$ /$$__ $$ | $$__ $$| $$__ $$
  4. | $$$$| $$| $$ \__/ | $$ \ $$| $$ \ $$
  5. | $$ $$ $$| $$ /$$$$ /$$$$$$| $$$$$$$/| $$$$$$$/
  6. | $$ $$$$| $$|_ $$|______/| $$__ $$| $$____/
  7. | $$\ $$$| $$ \ $$ | $$ \ $$| $$
  8. | $$ \ $$| $$$$$$/ | $$ | $$| $$
  9. |__/ \__/ \______/ |__/ |__/|__/
  10. Poll System
  11. Jingles
  12. Next Generation Gaming, LLC
  13. (created by Next Generation Gaming Development Team)
  14. * Copyright (c) 2016, Next Generation Gaming, LLC
  15. *
  16. * All rights reserved.
  17. *
  18. * Redistribution and use in source and binary forms, with or without modification,
  19. * are not permitted in any case.
  20. *
  21. *
  22. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  23. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  24. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  25. * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
  26. * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  27. * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  28. * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  29. * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
  30. * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  31. * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  32. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  33. */
  34. #include <YSI\y_hooks>
  35. #define MAX_POLL_OPTIONS 5
  36. enum ePolls {
  37. pol_iPollID,
  38. bool:pol_bFinished,
  39. bool:pol_bActive,
  40. pol_szQuestion[64],
  41. pol_iTypeID,
  42. pol_iHours
  43. }
  44. new arrPolls[ePolls];
  45. new arrPollOption[MAX_POLL_OPTIONS][32];
  46. hook OnGameModeExit() {
  47. Poll_UnloadPolls();
  48. }
  49. Poll_LoadPolls() {
  50. mysql_tquery(MainPipeline, "SELECT * FROM `polls` WHERE `active` = '1' LIMIT 1", true, "Poll_OnLoadPolls", "");
  51. return 1;
  52. }
  53. hook OnDialogResponse(playerid, dialogid, response, listitem, inputtext[]) {
  54. if(arrAntiCheat[playerid][ac_iFlags][AC_DIALOGSPOOFING] > 0) return 1;
  55. szMiscArray[0] = 0;
  56. switch(dialogid) {
  57. case DIALOG_POLLS_VOTE: {
  58. if(!response || !(2 <= listitem <= MAX_POLL_OPTIONS)) return SendClientMessage(playerid, COLOR_WHITE, "You did not cast your vote");
  59. if(strlen(inputtext) < 4) return SendClientMessageEx(playerid, COLOR_GRAD1, "You cannot vote this option.");
  60. PlayerInfo[playerid][pLastPoll] = arrPolls[pol_iPollID];
  61. format(szMiscArray, sizeof(szMiscArray), "UPDATE `polls` SET `OptionV%d` = OptionV%d + '1' WHERE `id` = '%d'", listitem-2, listitem-2, arrPolls[pol_iPollID]);
  62. mysql_tquery(MainPipeline, szMiscArray, false, "Poll_CastVote", "ii", playerid, listitem-2);
  63. }
  64. case DIALOG_POLLS_EDIT: {
  65. if(!response) return 1;
  66. switch(listitem) {
  67. case 0: ShowPlayerDialogEx(playerid, DIALOG_POLLS_QUESTION, DIALOG_STYLE_INPUT, "NGRP Polls | Edit Question", "Please formulate a question for this poll", "Enter", "Cancel");
  68. case 1: {
  69. szMiscArray[0] = 0;
  70. for(new i; i < MAX_POLL_OPTIONS; ++i) {
  71. format(szMiscArray, sizeof(szMiscArray), "%s\n%d. %s", szMiscArray, i+1, arrPollOption[i]);
  72. }
  73. ShowPlayerDialogEx(playerid, DIALOG_POLLS_OPTIONS, DIALOG_STYLE_LIST, "NGRP Polls | Edit Options", szMiscArray, "Edit", "Cancel");
  74. }
  75. case 2: ShowPlayerDialogEx(playerid, DIALOG_POLLS_TYPE, DIALOG_STYLE_LIST, "NG:RP | Polls", "All\nFactions\nGangs\nBusiness\nVIP", "Enter", "Cancel");
  76. case 3: ShowPlayerDialogEx(playerid, DIALOG_POLLS_HOURS, DIALOG_STYLE_INPUT, "NG:RP | Polls", "Enter the minimum amount of playing hours to be able to cast a vote.", "Enter", "Cancel");
  77. case 4: {
  78. if(!arrPolls[pol_bActive]) {
  79. Poll_TogglePoll(playerid, true);
  80. }
  81. else SendClientMessageEx(playerid, COLOR_GRAD1, "This poll is already active.");
  82. }
  83. case 5: {
  84. if(arrPolls[pol_bActive]) {
  85. Poll_TogglePoll(playerid, false);
  86. }
  87. else SendClientMessageEx(playerid, COLOR_GRAD1, "This poll is already inactive.");
  88. }
  89. }
  90. }
  91. case DIALOG_POLLS_QUESTION: {
  92. if(!response || isnull(inputtext)) return 1;
  93. szMiscArray[0] = 0;
  94. new szPoll[64];
  95. mysql_escape_string(inputtext, szPoll);
  96. format(arrPolls[pol_szQuestion], sizeof(arrPolls[pol_szQuestion]), szPoll);
  97. format(szMiscArray, sizeof(szMiscArray), "Poll: Administrator %s set the Poll ID %d's question: %s", GetPlayerNameEx(playerid), arrPolls[pol_iPollID], szPoll);
  98. ABroadCast(COLOR_YELLOW, szMiscArray, 2);
  99. Log("logs/polls.log", szMiscArray);
  100. format(szMiscArray, sizeof(szMiscArray), "UPDATE `polls` SET `Question` = '%s' WHERE `id` = '%d'", szPoll, arrPolls[pol_iPollID]);
  101. mysql_tquery(MainPipeline, szMiscArray, false, "OnQueryFinish", "i", SENDDATA_THREAD);
  102. }
  103. case DIALOG_POLLS_OPTIONS: {
  104. if(!response) return 1;
  105. SetPVarInt(playerid, "EditPoll", listitem);
  106. ShowPlayerDialogEx(playerid, DIALOG_POLLS_OPTIONS2, DIALOG_STYLE_INPUT, "NGRP Polls | Edit", "Please enter an option", "Enter", "Cancel");
  107. }
  108. case DIALOG_POLLS_OPTIONS2: {
  109. if(!response || isnull(inputtext)) return DeletePVar(playerid, "EditPoll");
  110. new iPollOption = GetPVarInt(playerid, "EditPoll"),
  111. szPoll[32];
  112. szMiscArray[0] = 0;
  113. mysql_escape_string(inputtext, szPoll);
  114. format(arrPollOption[iPollOption], 32, szPoll);
  115. format(szMiscArray, sizeof(szMiscArray), "Poll: Administrator %s set the Poll ID %d's option #%d: %s", GetPlayerNameEx(playerid), arrPolls[pol_iPollID], iPollOption, szPoll);
  116. ABroadCast(COLOR_YELLOW, szMiscArray, 2);
  117. Log("logs/polls.log", szMiscArray);
  118. format(szMiscArray, sizeof(szMiscArray), "Option%d", iPollOption);
  119. format(szMiscArray, sizeof(szMiscArray), "UPDATE `polls` SET `%s` = '%s' WHERE `id` = '%d'", szMiscArray, szPoll, arrPolls[pol_iPollID]);
  120. mysql_tquery(MainPipeline, szMiscArray, false, "OnQueryFinish", "i", SENDDATA_THREAD);
  121. DeletePVar(playerid, "EditPoll");
  122. }
  123. case DIALOG_POLLS_TYPE: {
  124. if(!response) return 1;
  125. arrPolls[pol_iTypeID] = listitem;
  126. format(szMiscArray, sizeof(szMiscArray), "Administrator %s set Poll ID %d's type to: %s", GetPlayerNameEx(playerid), arrPolls[pol_iPollID], inputtext);
  127. ABroadCast(COLOR_YELLOW, szMiscArray, 2);
  128. Log("logs/polls.log", szMiscArray);
  129. format(szMiscArray, sizeof(szMiscArray), "UPDATE `polls` SET `Type` = '%d' WHERE `id` = '%d'", arrPolls[pol_iTypeID], arrPolls[pol_iPollID]);
  130. mysql_tquery(MainPipeline, szMiscArray, false, "OnQueryFinish", "i", SENDDATA_THREAD);
  131. }
  132. case DIALOG_POLLS_HOURS: {
  133. if(!response || !IsNumeric(inputtext)) return 1;
  134. arrPolls[pol_iHours] = strval(inputtext);
  135. format(szMiscArray, sizeof(szMiscArray), "Administrator %s set the minimum playing hours for Poll ID %d to %d hours.", GetPlayerNameEx(playerid), arrPolls[pol_iPollID], arrPolls[pol_iHours]);
  136. ABroadCast(COLOR_YELLOW, szMiscArray, 2);
  137. Log("logs/polls.log", szMiscArray);
  138. format(szMiscArray, sizeof(szMiscArray), "UPDATE `polls` SET `Hours` = '%d' WHERE `id` = '%d'", arrPolls[pol_iHours], arrPolls[pol_iPollID]);
  139. mysql_tquery(MainPipeline, szMiscArray, false, "OnQueryFinish", "i", SENDDATA_THREAD);
  140. }
  141. }
  142. return 0;
  143. }
  144. forward Poll_OnLoadPolls();
  145. public Poll_OnLoadPolls() {
  146. new iRows,
  147. iFields;
  148. cache_get_data(iRows, iFields, MainPipeline);
  149. if(iRows) {
  150. arrPolls[pol_iPollID] = cache_get_field_content_int(0, "id", MainPipeline);
  151. arrPolls[pol_iTypeID] = cache_get_field_content_int(0, "Type", MainPipeline);
  152. arrPolls[pol_iHours] = cache_get_field_content_int(0, "Hours", MainPipeline);
  153. arrPolls[pol_bActive] = true;
  154. cache_get_field_content(0, "Question", arrPolls[pol_szQuestion], MainPipeline, 64);
  155. for(new i; i < MAX_POLL_OPTIONS; ++i) {
  156. format(szMiscArray, sizeof(szMiscArray), "Option%d", i);
  157. cache_get_field_content(0, szMiscArray, arrPollOption[i], MainPipeline, 32);
  158. }
  159. }
  160. else print("[Polls] There aren't any active polls in the database.");
  161. return 1;
  162. }
  163. Poll_UnloadPolls() {
  164. arrPolls[pol_szQuestion][0] = 0;
  165. for(new i; i < MAX_POLL_OPTIONS; ++i) arrPollOption[i][0] = 0;
  166. }
  167. forward Poll_CastVote(playerid, iOptionID);
  168. public Poll_CastVote(playerid, iOptionID) {
  169. if(mysql_errno(MainPipeline)) SendClientMessageEx(playerid, COLOR_YELLOW, "There was an error when casting your vote. Please contact tech support.");
  170. format(szMiscArray, sizeof(szMiscArray), "POLL: You voted %s in Poll %d.", arrPollOption[iOptionID], arrPolls[pol_iPollID]);
  171. SendClientMessageEx(playerid, COLOR_YELLOW, szMiscArray);
  172. format(szMiscArray, sizeof(szMiscArray), "%s (%s) (IP: %s) cast a vote, Poll ID %d, OptionID %d",
  173. GetPlayerNameExt(playerid), PlayerInfo[playerid][pId], GetPlayerSQLId(playerid), GetPlayerIpEx(playerid), arrPolls[pol_iPollID], iOptionID);
  174. Log("logs/polls.log", szMiscArray);
  175. return 1;
  176. }
  177. Poll_TogglePoll(playerid, bool:bState) {
  178. arrPolls[pol_bActive] = bState;
  179. if(!bState) arrPolls[pol_bFinished] = true;
  180. format(szMiscArray, sizeof(szMiscArray), "Administrator %s %s a poll. (Use /poll to cast your vote or view the results).", GetPlayerNameEx(playerid), bState == true ? ("started") : ("ended"));
  181. SendClientMessageToAllEx(COLOR_YELLOW, szMiscArray);
  182. Log("logs/polls.log", szMiscArray);
  183. format(szMiscArray, sizeof(szMiscArray), "UPDATE `polls` SET `Active` = '%d' WHERE `id` = '%d'", bState, arrPolls[pol_iPollID]);
  184. mysql_tquery(MainPipeline, szMiscArray, false, "OnQueryFinish", "i", SENDDATA_THREAD);
  185. }
  186. Poll_CreatePoll() {
  187. mysql_tquery(MainPipeline, "INSERT INTO `polls` (`Active`) VALUES ('1')", true, "Poll_OnCreatePoll", "");
  188. }
  189. forward Poll_OnCreatePoll();
  190. public Poll_OnCreatePoll() {
  191. arrPolls[pol_iPollID] = cache_insert_id();
  192. arrPolls[pol_szQuestion][0] = 0;
  193. arrPolls[pol_bFinished] = false;
  194. arrPolls[pol_bActive] = false;
  195. arrPolls[pol_iTypeID] = 0;
  196. arrPolls[pol_iHours] = 0;
  197. for(new i; i < MAX_POLL_OPTIONS; ++i) arrPollOption[i][0] = 0;
  198. return 1;
  199. }
  200. Poll_GetVotes(playerid) {
  201. format(szMiscArray, sizeof(szMiscArray), "SELECT * FROM `polls` WHERE `id` = '%d'", arrPolls[pol_iPollID]);
  202. mysql_tquery(MainPipeline, szMiscArray, true, "Poll_OnGetVotes", "i", playerid);
  203. }
  204. forward Poll_OnGetVotes(playerid);
  205. public Poll_OnGetVotes(playerid) {
  206. szMiscArray[0] = 0;
  207. new iRows,
  208. iFields,
  209. iCount,
  210. iTotalCount,
  211. szVoteStr[2];
  212. cache_get_data(iRows, iFields, MainPipeline);
  213. format(szMiscArray, sizeof(szMiscArray), "----\tVotes\n\
  214. POLL: %s\t_\n\
  215. __________________________________________\t____\n", arrPolls[pol_szQuestion]);
  216. for(new i; i < MAX_POLL_OPTIONS; ++i) {
  217. // if(!isnull(arrPollOption[i]))
  218. {
  219. format(szVoteStr, sizeof(szVoteStr), "OptionV%d", i);
  220. iCount = cache_get_field_content_int(0, szVoteStr, MainPipeline);
  221. iTotalCount += iCount;
  222. format(szMiscArray, sizeof(szMiscArray), "%s\n%d. %s\t%d",
  223. szMiscArray,
  224. i+1,
  225. arrPollOption[i],
  226. iCount);
  227. }
  228. }
  229. format(szMiscArray, sizeof(szMiscArray), "%s\nTotal Votes:\t%d", szMiscArray, iTotalCount);
  230. ShowPlayerDialogEx(playerid, DIALOG_NOTHING, DIALOG_STYLE_TABLIST_HEADERS, "NG:RP | Poll Results", szMiscArray, "OK", "");
  231. return 1;
  232. }
  233. Poll_GetPollType(iTypeID) {
  234. szMiscArray[0] = 0;
  235. switch(iTypeID) {
  236. case 1: szMiscArray = "Faction";
  237. case 2: szMiscArray = "Gang";
  238. case 3: szMiscArray = "Business";
  239. case 4: szMiscArray = "VIP";
  240. default: szMiscArray = "All";
  241. }
  242. return szMiscArray;
  243. }
  244. Poll_CheckVoteRights(playerid) {
  245. if(PlayerInfo[playerid][pLastPoll] == arrPolls[pol_iPollID]) {
  246. SendClientMessageEx(playerid, COLOR_GRAD1, "You already casted your vote in this poll.");
  247. return 0;
  248. }
  249. if(PlayerInfo[playerid][pConnectHours] < arrPolls[pol_iHours]) {
  250. SendClientMessageEx(playerid, COLOR_GRAD1, "You have insufficient playing hours to participate in this poll.");
  251. return 0;
  252. }
  253. switch(arrPolls[pol_iTypeID]) {
  254. case 0: return 1;
  255. case 1: if(PlayerInfo[playerid][pMember] != INVALID_GROUP_ID && !IsACriminal(playerid)) return 1;
  256. case 2: if(IsACriminal(playerid)) return 1;
  257. case 3: if(PlayerInfo[playerid][pBusiness] != INVALID_BUSINESS_ID) return 1;
  258. case 4: if(PlayerInfo[playerid][pDonateRank] > 0) return 1;
  259. }
  260. return 0;
  261. }
  262. CMD:pollhelp(playerid, params[]) {
  263. SendClientMessageEx(playerid, COLOR_GRAD1, "/poll - To cast your vote or view the poll's results.");
  264. if(PlayerInfo[playerid][pAdmin] == 99999) SendClientMessageEx(playerid, COLOR_YELLOW, "/editpoll | /viewpoll | /nextpoll");
  265. return 1;
  266. }
  267. CMD:poll(playerid, params[]) {
  268. if(arrPolls[pol_bActive]) {
  269. if(!arrPolls[pol_iPollID]) return SendClientMessageEx(playerid, COLOR_GRAD1, "There isn't an active poll.");
  270. if(!Poll_CheckVoteRights(playerid)) return SendClientMessageEx(playerid, COLOR_GRAD1, "You cannot vote in this poll.");
  271. format(szMiscArray, sizeof(szMiscArray), "POLL: %s\n\
  272. _______________________________________________\n", arrPolls[pol_szQuestion]);
  273. for(new i; i < MAX_POLL_OPTIONS; ++i) {
  274. if(!isnull(arrPollOption[i])) {
  275. format(szMiscArray, sizeof(szMiscArray), "%s\n%d. %s", szMiscArray, i, arrPollOption[i]);
  276. }
  277. }
  278. ShowPlayerDialogEx(playerid, DIALOG_POLLS_VOTE, DIALOG_STYLE_LIST, "NG:RP | Poll", szMiscArray, "Vote", "Cancel");
  279. }
  280. else Poll_GetVotes(playerid);
  281. return 1;
  282. }
  283. CMD:viewpoll(playerid, params[]) {
  284. if(PlayerInfo[playerid][pAdmin] != 99999) return SendClientMessage(playerid, COLOR_GRAD1, "You are not authorized to use this command.");
  285. Poll_GetVotes(playerid);
  286. return 1;
  287. }
  288. CMD:nextpoll(playerid, params[]) {
  289. if(PlayerInfo[playerid][pAdmin] != 99999) return SendClientMessage(playerid, COLOR_GRAD1, "You are not authorized to use this command.");
  290. Poll_CreatePoll();
  291. SendClientMessageEx(playerid, COLOR_GRAD1, "You created a new poll. Use /editpoll to edit it.");
  292. return 1;
  293. }
  294. CMD:editpoll(playerid, params[]) {
  295. if(PlayerInfo[playerid][pAdmin] != 99999) return SendClientMessage(playerid, COLOR_GRAD1, "You are not authorized to use this command.");
  296. if(arrPolls[pol_iPollID] == 0 || arrPolls[pol_bFinished]) Poll_CreatePoll();
  297. format(szMiscArray, sizeof(szMiscArray), "Edit Question\n\
  298. Edit Options\n\
  299. Edit Poll Type (%s)\n\
  300. Edit Min. Playing Hours (%d)\n\
  301. Start\n\
  302. End", Poll_GetPollType(arrPolls[pol_iTypeID]), arrPolls[pol_iHours]);
  303. ShowPlayerDialogEx(playerid, DIALOG_POLLS_EDIT, DIALOG_STYLE_LIST, "NG:RP Polls | Edit", szMiscArray, "Select", "Cancel");
  304. return 1;
  305. }