| 2650 | void callvotepacket (int, voteinfo *); |
| 2651 | |
| 2652 | bool scallvote(voteinfo *v, ENetPacket *msg) // true if a regular vote was called |
| 2653 | { |
| 2654 | if (!v) return false; |
| 2655 | int area = isdedicated ? EE_DED_SERV : EE_LOCAL_SERV; |
| 2656 | int error = -1; |
| 2657 | client *c = clients[v->owner], *b = ( v->boot && valid_client(cn2boot) ? clients[cn2boot] : NULL ); |
| 2658 | v->host = v->boot && b ? b->peer->address.host : 0; |
| 2659 | |
| 2660 | int time = servmillis - c->lastvotecall; |
| 2661 | if ( c->nvotes > 0 && time > 4*60*1000 ) c->nvotes -= time/(4*60*1000); |
| 2662 | if ( c->nvotes < 0 || c->role == CR_ADMIN ) c->nvotes = 0; |
| 2663 | c->nvotes++; |
| 2664 | |
| 2665 | |
| 2666 | if( !v || !v->isvalid() || (v->boot && (!b || cn2boot == v->owner) ) ) error = VOTEE_INVALID; |
| 2667 | else if( v->action->role > c->role ) error = VOTEE_PERMISSION; |
| 2668 | else if( !(area & v->action->area) ) error = VOTEE_AREA; |
| 2669 | else if( curvote && curvote->result==VOTE_NEUTRAL ) error = VOTEE_CUR; |
| 2670 | else if( v->type == SA_MAP && v->num1 >= GMODE_NUM && map_queued ) error = VOTEE_NEXT; |
| 2671 | else if( c->role == CR_DEFAULT && v->action->isdisabled() ) error = VOTEE_DISABLED; |
| 2672 | else if( (c->lastvotecall && servmillis - c->lastvotecall < 60*1000 && c->role != CR_ADMIN && numclients()>1) || c->nvotes > 3 ) error = VOTEE_MAX; |
| 2673 | else if( ( ( v->boot == 1 && c->role < roleconf('w') ) || ( v->boot == 2 && c->role < roleconf('X') ) ) |
| 2674 | && !is_lagging(b) && !b->mute && b->spamcount < 2 ) |
| 2675 | { |
| 2676 | /** not same team, with low ratio, not lagging, and not spamming... so, why to kick? */ |
| 2677 | if ( !isteam(c->team, b->team) && b->state.frags < ( b->state.deaths > 0 ? b->state.deaths : 1 ) * 3 ) error = VOTEE_WEAK; |
| 2678 | /** same team, with low tk, not lagging, and not spamming... so, why to kick? */ |
| 2679 | else if ( isteam(c->team, b->team) && b->state.teamkills < c->state.teamkills ) error = VOTEE_WEAK; |
| 2680 | } |
| 2681 | //else if( c->role == CR_DEFAULT && servmillis - c->connectmillis < 60000 && numclients() > 1 ) error = VOTEE_PERMISSION; // after connection 60s delay before possibility of vote start // VOTE_PERMISSION is misleading but reenable modified if misuse occurs |
| 2682 | |
| 2683 | if(error>=0) |
| 2684 | { |
| 2685 | scallvoteerr(v, error); |
| 2686 | return false; |
| 2687 | } |
| 2688 | else |
| 2689 | { |
| 2690 | if ( v->type == SA_MAP && v->num1 >= GMODE_NUM ) map_queued = true; |
| 2691 | if (!v->gonext) sendpacket(-1, 1, msg, v->owner); // FIXME in fact, all votes should go to the server, registered, and then go back to the clients |
| 2692 | else callvotepacket (-1, v); // also, no vote should exclude the caller... these would provide many code advantages/facilities |
| 2693 | scallvotesuc(v); // but we cannot change the vote system now for compatibility issues... so, TODO |
| 2694 | return true; |
| 2695 | } |
| 2696 | } |
| 2697 | |
| 2698 | void callvotepacket (int cn, voteinfo *v = curvote) |
| 2699 | { // FIXME, it would be far smart if the msg buffer from SV_CALLVOTE was simply saved |
no test coverage detected