Author Topic: Attempting to make a Vote mod. People can vote more than once. HELP  (Read 1438 times)

This is my script. I have the variable %hasvoted set to 1 once you vote using /yes or /no. Unfortunately, players can still vote.
Code: [Select]
package voting
{
function autoendvote(%c)
{
servercmdendvote(%c);
messageall('',"\c6Time's up!");
}
function servercmdstartvote(%c,%time,%r1,%r2,%r3,%r4,%r5,%r6,%r7,%r8,%r9,%r10,%r11,%r12,%r13,%r14,%r15,%r16,%r17)
{
if(!%c.isadmin)
return;
%time *= 1000;
schedule(%time,0,autoendvote,%c);
$reason = %r1 SPC %r2 SPC %r3 SPC %r4 SPC %r5 SPC %r6 SPC %r7 SPC %r8 SPC %r9 SPC %r10 SPC %r11 SPC %r12 SPC %r13 SPC %r14 SPC %r15 SPC %r16 SPC %r17;
$reason = stripTrailingSpaces($reason);
$totalvotes = "";
$votehost = %c;
$voteactive = 1;
messageall('',"\c3" @ $votehost.name @ "\c6 has called a vote. Reason:\c3" @ $reason);
%time /= 1000;
$votetime = %time;
messageall('',"\c6This vote will last for \c3" @ $votetime @ "\c6 seconds.");
messageall('',"\c6Use /yes to vote yes and /no to vote no.");
messageclient(%c,'',"\c0IMPORTANT:\c6To end the vote, type \"\c3/endvote\c6\".");
}
function servercmdendvote(%c)
{
if(!%c.isadmin)
return;
if(!$voteactive == 1);
return;
$voteactive = 0;
messageall('',"\c6The vote with reason:\c3\"" @ $reason @ "\"\c6 has ended.");
messageall('',"\c6The final tally is...");
if($totalvotes > 0)
messageall('',"\c2The general consensus is yes!\c6 With a final vote of \c3" @ $totalvotes @ "\c6, the vote was a success!");
if($totalvotes < 0)
messageall('',"\c0The general consensus is no!\c6 With a final vote of \c3" @ $totalvotes @ "\c6, the vote was a failure!");
if($totalvotes == 0)
messageall('',"\c3The vote is a tie!\c6 I don't know how you did it, but you broke even!");
for(%x=0;%x<clientGroup.getCount();%x++)
{
clientgroup.getobject(%x).hasvoted = 0;
}
}
function servercmdyes(%c)
{
if(!$voteactive $= 1)
{
%c.chatmessage("\c0Error:\c6There is no vote in progress!");
return;
}
if(%c.hasvoted == 1)
{
%c.chatmessage("\c0Error:\c6You have already voted in this vote.");
return;
}
$voter = %c;
$totalvotes = $totalvotes + 1;
messageclient($votehost,'',"\c3" @ $voter.name @" \c6has voted \c2Yes.");
messageclient($votehost,'',"\c6The current tally of votes is \c3" @ $totalvotes @ "\c6.");
%c.chatmessage("\c6You have voted \c2in favor\c6.");
%c.hasvoted = 1;
}
function servercmdno(%c)
{
if(!$voteactive $= 1)
{
%c.chatmessage("\c0Error:\c6There is no vote in progress!");
return;
}
if(%c.hasvoted == 1)
{
%c.chatmessage("\c0Error:\c6You have already voted in this vote.");
return;
}
$voter = %c;
$totalvotes = $totalvotes - 1;
messageclient($votehost,'',"\c3" @ $voter.name @ " \c6has voted \c0No.");
messageclient($votehost,'',"\c6The current tally of votes is \c3" @ $totalvotes @ "\c6.");
%c.chatmessage("\c6You have voted \c0in opposition\c6.");
%c.hasvoted = 1;
}
};
activatePackage(voting);

Oh, and please don't bug me about the uselessness of packages in this usage. I'm doing that for my own mental cleanliness. (Unless someone tells me that it's BAD to use packages when they aren't neccesary??)

Having made some voting based scripts before, I strongly reccommend you use the following method:

when a player votes, it does nothing to a global variable.
Instead, it sets that player's vote to either 1 (for yes) or 2 (for no)
At the end of the vote, cycle through all players in the server and tally up the votes then
Then when a new vote is started, it resets all votes to 0

This helps:
   people leaving before the vote ends
   people joining multiple times to vote multiple times
   anything buggy that might happen when switching votes

The way you do if statements reminds me alot of me when I first started scripting.

Instead of saying if(%var ==1) or if(%var $= 1)

just do if(%var)

it is effectively the same, jsut testing if the variable is true

also, if you need to increment or decrement a variable, you can do

$var++;

or

$var--;
« Last Edit: January 12, 2012, 12:04:14 AM by Nexus »

when a player votes, it does nothing to a global variable.
Instead, it sets that player's vote to either 1 (for yes) or 2 (for no)
At the end of the vote, cycle through all players in the server and tally up the votes then
Then when a new vote is started, it resets all votes to 0
Sounds good, actually. What is the weight of null votes in OP's system? Abstaining?

Sounds good, actually. What is the weight of null votes in OP's system? Abstaining?

In my system, it would just say the percent of people that participated.  I usually would discount the entire vote if the interest was too low.

In my system, it would just say the percent of people that participated.  I usually would discount the entire vote if the interest was too low.
Sounds good.


Also, to answer OP's question, no. It's not bad to package all functions. It may actually be good, because at the end of the server it disables all packages. Newly created functions will also vanish if they're in a package (I think).



Er, it occurred to me that players could use an exploit where they join multiple times at once by opening multiple instances of blockland.  When tallying up the votes, probably make a check to ensure that a bl_id is not getting to vote twice.

Er, it occurred to me that players could use an exploit where they join multiple times at once by opening multiple instances of blockland.  When tallying up the votes, probably make a check to ensure that a bl_id is not getting to vote twice.
My first reply actually noted this, and then I redacted it.

If you only set a property on the client that is only tallied after the vote, this bug doesn't happen. The only exploit would be having multiple clients join of the same BL_ID, but that's somewhat impractical.

sooo...

for(%x=0;%x<clientGroup.getCount();%x++)
   {
      if(clientgroup.getobject(%x).vote = 1)
              $totalvotes + 1;
      if(clientgroup.getobject(%x).vote = 2)
              $totalvotes - 1;
      if(clientgroup.getobject(%x).vote = 0)
   }

Code: [Select]
function servercmdendvote(%c)
{
if(!%c.isadmin)
return;
if(!$voteactive == 1);
return;
$voteactive = 0;
for(%x=0;%x<clientGroup.getCount();%x++)
{
if(clientgroup.getobject(%x).vote == 1)
$totalvotes++;
if(clientgroup.getobject(%x).vote == 2)
$totalvotes--;
}
messageall('',"\c6The vote with reason:\c3\"" @ $reason @ "\"\c6 has ended.");
messageall('',"\c6The final tally is...");
if($totalvotes > 0)
messageall('',"\c2The general consensus is yes!\c6 With a final vote of \c3" @ $totalvotes @ "\c6, the vote was a success!");
if($totalvotes < 0)
messageall('',"\c0The general consensus is no!\c6 With a final vote of \c3" @ $totalvotes @ "\c6, the vote was a failure!");
if($totalvotes == 0)
messageall('',"\c3The vote is a tie!\c6 I don't know how you did it, but you broke even!");
for(%x=0;%x<clientGroup.getCount();%x++)
{
clientgroup.getobject(%x).vote = 0;
}
}
function servercmdyes(%c)
{
if(!$voteactive == 1)
{
%c.chatmessage("\c0Error:\c6There is no vote in progress!");
return;
}
$voter = %c;
$totalvotes = $totalvotes + 1;
messageclient($votehost,'',"\c3" @ $voter.name @" \c6has voted \c2Yes.");
messageclient($votehost,'',"\c6The current tally of votes is \c3" @ $totalvotes @ "\c6.");
%c.chatmessage("\c6You have voted \c2in favor\c6.");
%c.vote = 1;
}
Something like this?
If this doesn't work, you'll probably find out that I have no idea how to use for() loops, and I just got lucky in the usage in my main code...
« Last Edit: January 12, 2012, 01:42:35 AM by Lugnut1206 »

Instead of adding or subtracting to the same variable, do it $votesYes and $votesNo and then compare them to see which is larger.

As you have it, if no wins, it would display a negative number of votes.

Also don't forget that you are removing $totalvotes = $totalvotes + 1;
« Last Edit: January 12, 2012, 01:47:30 AM by Nexus »