18 |
#include "utils.h" |
#include "utils.h" |
19 |
} |
} |
20 |
|
|
21 |
|
#include <set> |
22 |
|
#include <iterator> |
23 |
#include <vector> |
#include <vector> |
24 |
#include <map> |
#include <map> |
25 |
#include <string> |
#include <string> |
48 |
{ |
{ |
49 |
FASCISM = 0, |
FASCISM = 0, |
50 |
ANARCHY = 1, |
ANARCHY = 1, |
51 |
KILLARCHY = 2 |
KILLARCHY = 2, |
52 |
|
DEMOCRACY = 3 |
53 |
|
|
54 |
|
}; |
55 |
|
|
56 |
|
enum PollType |
57 |
|
{ |
58 |
|
OPINION = 0, |
59 |
|
BAN = 1 |
60 |
|
}; |
61 |
|
|
62 |
|
struct poll |
63 |
|
{ |
64 |
|
time_t startTime; |
65 |
|
int duration; |
66 |
|
PollType pollType; |
67 |
|
bool closed; |
68 |
|
std::string question; |
69 |
|
//option number and text |
70 |
|
std::map<int, std::string> opts; |
71 |
|
//option number and total votes |
72 |
|
std::map<int, int> results; |
73 |
|
//voter uid and option number |
74 |
|
std::map<int, int> votes; |
75 |
}; |
}; |
76 |
|
|
77 |
struct open_challenge |
struct open_challenge |
105 |
std::pair<int, int> ratingRange; |
std::pair<int, int> ratingRange; |
106 |
}; |
}; |
107 |
|
|
|
struct negotiated_game |
|
|
{ |
|
|
int white; |
|
|
int black; |
|
|
TimeType timeType; |
|
|
int mainTime; |
|
|
int extraTime; |
|
|
int movesTime; |
|
|
std::string message; |
|
|
double komi; |
|
|
}; |
|
|
|
|
108 |
struct occupant |
struct occupant |
109 |
{ |
{ |
110 |
occupant() : admin(false), member(false), silenced(false) { } |
occupant() : admin(false), member(false), silenced(false) { } |
136 |
ListSilenced = 18, |
ListSilenced = 18, |
137 |
ListBanned = 19, |
ListBanned = 19, |
138 |
Ban = 20, |
Ban = 20, |
139 |
UnBan = 21 |
UnBan = 21, |
140 |
|
SubmitPoll = 22, |
141 |
|
Poll = 23, |
142 |
|
PollVote = 24, |
143 |
|
PollResults = 25 |
144 |
}; |
}; |
145 |
|
|
146 |
struct room |
struct room |
151 |
std::vector<int> admins; |
std::vector<int> admins; |
152 |
std::vector<int> silenced; |
std::vector<int> silenced; |
153 |
std::vector<int> banned; |
std::vector<int> banned; |
154 |
|
std::map<int, poll> polls; |
155 |
std::map<int, occupant> occupants; |
std::map<int, occupant> occupants; |
156 |
std::map<int, open_game> open_games; |
std::map<int, open_game> open_games; |
157 |
std::map<int, open_challenge> open_challenges; |
std::map<int, open_challenge> open_challenges; |
160 |
|
|
161 |
static std::map<int, room> rarray; |
static std::map<int, room> rarray; |
162 |
#define ROOM 200 |
#define ROOM 200 |
163 |
|
#define MAX_POLL_OPTS 10 |
164 |
|
|
165 |
/* use this one to send someone a message when they aren't expecting |
/* use this one to send someone a message when they aren't expecting |
166 |
it |
it |
335 |
} |
} |
336 |
} |
} |
337 |
|
|
338 |
|
void check_polls() |
339 |
|
{ |
340 |
|
/* for each room |
341 |
|
for each (open) poll |
342 |
|
check to see if it should be closed |
343 |
|
if not, skip |
344 |
|
if it does need to be closed |
345 |
|
-close it |
346 |
|
-check for quorumness, if command poll |
347 |
|
-tally results |
348 |
|
-send out results |
349 |
|
-if commandpoll, execute command |
350 |
|
|
351 |
|
result format: room num, poll num, number of options, var num of results |
352 |
|
|
353 |
|
*/ |
354 |
|
|
355 |
|
for(std::map<int, room>::iterator rmi = rarray.begin(); |
356 |
|
rmi != rarray.end(); rmi++) { |
357 |
|
for(std::map<int, poll>::iterator pi = rmi->second.polls.begin(); |
358 |
|
pi != rmi->second.polls.end(); pi++) { |
359 |
|
|
360 |
|
poll& pll = pi->second; |
361 |
|
|
362 |
|
//can't do anything with polls that are open or already closed |
363 |
|
if((time(NULL) < pll.startTime + pll.duration) || (pll.closed)) |
364 |
|
continue; |
365 |
|
|
366 |
|
pll.closed = true; |
367 |
|
|
368 |
|
//check for quorum |
369 |
|
// if(pll.pollType != OPINION) |
370 |
|
|
371 |
|
//tally results (no need to zero first, STL rocks) |
372 |
|
for(std::map<int, int>::iterator vi = pll.votes.begin(); |
373 |
|
vi != pll.votes.end(); vi++) |
374 |
|
pll.results[vi->second]++; |
375 |
|
|
376 |
|
for(std::map<int, int>::iterator ri = pll.results.begin(); |
377 |
|
ri != pll.results.end(); ri++) |
378 |
|
std::cout << ri->first << ": " << ri->second << "\n"; |
379 |
|
|
380 |
|
std::cout.flush(); |
381 |
|
|
382 |
|
std::string s; |
383 |
|
std::stringstream ss; |
384 |
|
|
385 |
|
//poll num |
386 |
|
ss << pi->first; |
387 |
|
s = ss.str(); |
388 |
|
ss.str(""); |
389 |
|
s += " "; |
390 |
|
//number of options we're going to send |
391 |
|
ss << pll.opts.size(); |
392 |
|
s += ss.str(); |
393 |
|
ss.str(""); |
394 |
|
s += " "; |
395 |
|
|
396 |
|
for(std::map<int, std::string>::iterator oi = pll.opts.begin(); |
397 |
|
oi != pll.opts.end(); oi++) { |
398 |
|
ss << pll.results[oi->first]; |
399 |
|
s += ss.str(); |
400 |
|
ss.str(""); |
401 |
|
s += " "; |
402 |
|
} |
403 |
|
|
404 |
|
s += "\n"; |
405 |
|
|
406 |
|
NotifyOccupants(rmi->first, ROOM + PollResults, s, -1); |
407 |
|
|
408 |
|
//execute command, if neccessary |
409 |
|
// if(pll.pollType != OPINION) |
410 |
|
} |
411 |
|
} |
412 |
|
} |
413 |
|
|
414 |
|
|
415 |
|
//TODO Only in a Dem for commandpolls |
416 |
|
int com_roompollvote(int p, param_list param) |
417 |
|
{ |
418 |
|
int r = param[0].val.integer; |
419 |
|
int pnum = param[1].val.integer; |
420 |
|
int vote = param[2].val.integer; |
421 |
|
|
422 |
|
// lookup room |
423 |
|
std::map<int, room>::iterator rmi = rarray.find(r); |
424 |
|
if(rmi == rarray.end()) return COM_NOSUCHROOM; |
425 |
|
room& rm = rmi->second; |
426 |
|
|
427 |
|
//membership |
428 |
|
if(std::find(rm.members.begin(), rm.members.end(), parray[p].uid) |
429 |
|
== rm.members.end()) |
430 |
|
return COM_NOTMEMBER; |
431 |
|
|
432 |
|
//occupancy |
433 |
|
std::map<int, occupant>::iterator res = rm.occupants.find(p); |
434 |
|
if(res == rm.occupants.end()) return COM_NOTINROOM; |
435 |
|
|
436 |
|
// lookup poll |
437 |
|
std::map<int, poll>::iterator pi = rm.polls.find(pnum); |
438 |
|
if(pi == rm.polls.end()) return COM_NOSUCHPOLL; |
439 |
|
poll& pll = pi->second; |
440 |
|
|
441 |
|
//lookup option |
442 |
|
std::map<int, std::string>::iterator oi = pll.opts.find(vote); |
443 |
|
if(oi == pll.opts.end()) return COM_HANGINGCHAD; |
444 |
|
|
445 |
|
//lookup uid |
446 |
|
std::map<int, int>::iterator vi = pll.votes.find(parray[p].uid); |
447 |
|
if(vi != pll.votes.end()) return COM_VOTED; |
448 |
|
|
449 |
|
if(pll.closed) |
450 |
|
return COM_VOTELATE; |
451 |
|
|
452 |
|
pll.votes.insert(std::pair<int, int>(parray[p].uid, vote)); |
453 |
|
ReplyOccupant(r, p, ROOM + PollVote, "Thanks for participating in the system!"); |
454 |
|
//or maybe "Rock the Vote!" |
455 |
|
return COM_OK; |
456 |
|
|
457 |
|
} |
458 |
|
|
459 |
|
//Opinion polls are allowed for all gov't types, at least |
460 |
|
//for now |
461 |
|
//They also don't require a quorum |
462 |
|
// |
463 |
|
int com_roomsubmitopinionpoll(int p, param_list param) |
464 |
|
{ |
465 |
|
int r = param[0].val.integer; |
466 |
|
int seconds = param[1].val.integer; |
467 |
|
int i; |
468 |
|
|
469 |
|
// lookup room |
470 |
|
std::map<int, room>::iterator rmi = rarray.find(r); |
471 |
|
if(rmi == rarray.end()) return COM_NOSUCHROOM; |
472 |
|
room& rm = rmi->second; |
473 |
|
|
474 |
|
//membership |
475 |
|
if(std::find(rm.members.begin(), rm.members.end(), parray[p].uid) |
476 |
|
== rm.members.end()) |
477 |
|
return COM_NOTMEMBER; |
478 |
|
|
479 |
|
//occupancy |
480 |
|
std::map<int, occupant>::iterator res = rm.occupants.find(p); |
481 |
|
if(res == rm.occupants.end()) return COM_NOTINROOM; |
482 |
|
|
483 |
|
poll pll; |
484 |
|
|
485 |
|
pll.closed = false; |
486 |
|
|
487 |
|
pll.question = param[2].val.string; |
488 |
|
|
489 |
|
for(i = 3; i < MAX_POLL_OPTS + 3; i++) { |
490 |
|
if (param[i].type == (int) TYPE_NULL) |
491 |
|
break; |
492 |
|
pll.opts.insert(std::pair<int, std::string>(i-3, param[i].val.string)); |
493 |
|
} |
494 |
|
/* |
495 |
|
for(std::map<int, std::string>::iterator si = pll.opts.begin(); |
496 |
|
si != pll.opts.end(); si++) { |
497 |
|
std::cout << si->first << ": " << si->second << "\n"; |
498 |
|
std::cout.flush(); |
499 |
|
} |
500 |
|
*/ |
501 |
|
if(seconds < 10) |
502 |
|
seconds = 10; |
503 |
|
if(seconds > 3600) |
504 |
|
seconds = 3600; |
505 |
|
pll.duration = seconds; |
506 |
|
pll.startTime = time(NULL); |
507 |
|
pll.pollType = OPINION; |
508 |
|
|
509 |
|
for(i = 0; rm.polls.find(i) != rm.polls.end(); i++) |
510 |
|
; |
511 |
|
|
512 |
|
rm.polls.insert(std::pair<int, poll>(i, pll)); |
513 |
|
|
514 |
|
//don't send an ack to the submitter, |
515 |
|
//the Notify will send them a poll |
516 |
|
std::stringstream ss; |
517 |
|
std::string s; |
518 |
|
|
519 |
|
//poll number |
520 |
|
ss << i; |
521 |
|
s += ss.str(); |
522 |
|
s += " "; |
523 |
|
ss.str(""); |
524 |
|
//duration |
525 |
|
ss << pll.duration; |
526 |
|
s += ss.str(); |
527 |
|
s += " "; |
528 |
|
ss.str(""); |
529 |
|
//question |
530 |
|
s += "\""; |
531 |
|
s += pll.question; |
532 |
|
s += "\" "; |
533 |
|
//options |
534 |
|
for(std::map<int, std::string>::iterator si = pll.opts.begin(); |
535 |
|
si != pll.opts.end(); si++) { |
536 |
|
s += "\""; |
537 |
|
s += si->second; |
538 |
|
s += "\" "; |
539 |
|
} |
540 |
|
|
541 |
|
//don't skip p, they need to vote too |
542 |
|
//however, "Notify" won't work, so send |
543 |
|
//p's version as a Reply |
544 |
|
ReplyOccupant(r, p, ROOM + SubmitPoll, "\n"); |
545 |
|
ReplyOccupant(r, p, ROOM + Poll, s); |
546 |
|
s += "\n"; |
547 |
|
NotifyOccupants(r, ROOM + Poll, s, -1); |
548 |
|
|
549 |
|
return COM_OK; |
550 |
|
} |
551 |
|
|
552 |
//should some govt types be by invite only? |
//should some govt types be by invite only? |
553 |
int com_roomjoin(int p, param_list param) |
int com_roomjoin(int p, param_list param) |
554 |
{ |
{ |
889 |
if((uid = find_uid(login_to_ban.c_str())) >= 0) |
if((uid = find_uid(login_to_ban.c_str())) >= 0) |
890 |
rm.banned.push_back(uid); |
rm.banned.push_back(uid); |
891 |
else |
else |
892 |
|
//what to do? This could either mean the |
893 |
|
//database blew up or that the player just |
894 |
|
//isn't registered |
895 |
return COM_NOTIFYADMIN; |
return COM_NOTIFYADMIN; |
896 |
|
|
897 |
ReplyOccupant(r, p, ROOM + Ban, login_to_ban.c_str()); |
ReplyOccupant(r, p, ROOM + Ban, login_to_ban.c_str()); |
1355 |
|
|
1356 |
return COM_OK; |
return COM_OK; |
1357 |
} |
} |
1358 |
|
|
1359 |
|
int com_testquote(int p, param_list param) |
1360 |
|
{ |
1361 |
|
int i = param[0].val.integer; |
1362 |
|
std::string s = param[1].val.string; |
1363 |
|
std::string s2 = param[2].val.string; |
1364 |
|
|
1365 |
|
std::cout << s << "\n" << s2; |
1366 |
|
std::cout.flush(); |
1367 |
|
} |