merged .c files, fixed dcc/telnet clients lost on reset, rewrote reset some

This commit is contained in:
joonicks
2018-04-15 21:09:37 +02:00
parent 5f0fdada3e
commit 33f72e424b
18 changed files with 1788 additions and 1903 deletions

View File

@@ -29,6 +29,36 @@
#include "text.h"
#include "mcmd.h"
#ifdef TRIVIA
#define TRIV_WAIT_QUESTION 0
#define TRIV_HINT_TWO 1
#define TRIV_HINT_THREE 2
#define TRIV_NO_ANSWER 3
#define TRIV_HINT_DELAY 15
#define TRIV_HINT_DELAY_STR1 "15"
#define TRIV_HINT_DELAY_STR2 "30"
#define TRIV_METACHARS " .,-'%&/?!:;\""
#define DAY_IN_SECONDS (24*60*60)
#define WEEK_IN_SECONDS (7*24*60*60)
LS TrivScore *lastwinner;
LS Chan *triv_chan = NULL;
LS Strp *triv_answers = NULL;
LS time_t triv_ask_time;
LS time_t triv_next_time = 0;
LS time_t triv_weektop10;
LS int triv_mode;
LS int triv_score;
LS int triv_streak;
LS int triv_halt_flag;
#endif /* TRIVIA */
#define BIGSAY_DEFAULTFONT "default"
#define FONT_EXTENSION ".bigchars"
@@ -160,12 +190,522 @@ int read_ascii(char *rest)
to_user_q(global_from,FMT_PLAIN,rest);
}
#ifdef TRIVIA
/*
*
* trivia scorings
*
*/
void trivia_week_toppers(void)
{
char triv_str[MSGLEN];
TrivScore *chosen[10];
TrivScore *su;
char *p;
int week;
int i,x;
chosen[0] = NULL;
week = (now + (3 * DAY_IN_SECONDS)) / WEEK_IN_SECONDS;
for(su=scorelist;su;su=su->next)
{
if (su->week_nr != week)
continue;
for(i=0;i<10;i++)
{
if (!chosen[i] || (chosen[i]->score_wk < su->score_wk))
{
for(x=8;x>=i;x--)
chosen[x+1] = chosen[x];
chosen[i] = su;
break;
}
}
}
if (chosen[0])
{
p = triv_str;
for(i=0;i<10;i++)
{
if (!chosen[i])
break;
if (i)
{
*(p++) = ' ';
*(p++) = ' ';
}
sprintf(p,"#%i: %s (%ipts)",i+1,chosen[i]->nick,chosen[i]->score_wk);
p = STREND(p);
}
to_server("PRIVMSG %s :This Weeks Top 10: %s\n",triv_chan->name,triv_str);
}
}
/*
*
*
*
*/
void hint_one(void)
{
char triv_str[MSGLEN];
char *src,*dst;
sprintf(triv_str,"PRIVMSG %s :1st hint: ",triv_chan->name);
dst = STREND(triv_str);
src = triv_answers->p;
while(*src)
{
if (STRCHR(TRIV_METACHARS,*src))
*(dst++) = *src;
else
*(dst++) = triv_qchar;
src++;
}
*dst = 0;
to_server("%s Question score: %i points\n",triv_str,triv_score);
}
void hint_two(void)
{
char triv_str[MSGLEN];
char *src,*dst;
int n;
sprintf(triv_str,"PRIVMSG %s :2nd hint: ",triv_chan->name);
dst = STREND(triv_str);
src = triv_answers->p;
n = asc2int(src);
if (!errno)
{
if (n > 99 && *src) *(dst++) = *(src++);
if (n > 999 && *src) *(dst++) = *(src++);
if (n > 9999 && *src) *(dst++) = *(src++);
}
else
{
n = strlen(src);
if (n > 2 && *src) *(dst++) = *(src++);
if (n > 4 && *src) *(dst++) = *(src++);
if (n > 6 && *src) *(dst++) = *(src++);
}
while(*src)
{
if (STRCHR(TRIV_METACHARS,*src))
*(dst++) = *src;
else
*(dst++) = triv_qchar;
src++;
}
*dst = 0;
to_server("%s " TRIV_HINT_DELAY_STR2 " seconds remaining.\n",triv_str);
}
void hint_three(void)
{
char triv_str[MSGLEN];
char *src,*dst;
int n;
sprintf(triv_str,"PRIVMSG %s :3rd hint: ",triv_chan->name);
dst = STREND(triv_str);
src = triv_answers->p;
n = asc2int(src);
if (!errno)
{
if (n > 9 && *src) *(dst++) = *(src++);
if (n > 99 && *src) *(dst++) = *(src++);
if (n > 999 && *src) *(dst++) = *(src++);
}
else
{
n = strlen(src);
if (n > 1 && *src) *(dst++) = *(src++);
if (n > 3 && *src) *(dst++) = *(src++);
if (n > 4 && *src) *(dst++) = *(src++);
}
while(*src)
{
if (STRCHR(TRIV_METACHARS "aeiouyAEIOUY",*src))
*(dst++) = *src;
else
*(dst++) = triv_qchar;
src++;
}
*dst = 0;
to_server("%s " TRIV_HINT_DELAY_STR1 " seconds remaining.\n",triv_str);
}
/*
*
*
*
*/
void trivia_cleanup(void)
{
Strp *ans;
triv_mode = TRIV_WAIT_QUESTION;
triv_next_time = now + triv_qdelay;
while((ans = triv_answers))
{
triv_answers = ans->next;
Free((char**)&ans);
}
}
void trivia_check(Chan *chan, char *rest)
{
TrivScore *su;
Strp *ans;
int week;
if (chan != triv_chan)
return;
for(ans=triv_answers;ans;ans=ans->next)
{
if (!stringcasecmp(ans->p,rest))
goto have_answer;
}
return;
have_answer:
week = (now + (3 * DAY_IN_SECONDS)) / WEEK_IN_SECONDS;
for(su=scorelist;su;su=su->next)
{
if (!nickcmp(su->nick,CurrentNick))
{
su->score_mo += triv_score;
if (su->week_nr == week)
su->score_wk += triv_score;
else
{
if (su->week_nr == (week - 1))
su->score_last_wk = su->score_wk;
else
su->score_last_wk = 0;
su->week_nr = week;
su->score_wk = triv_score;
}
break;
}
}
if (!su)
{
set_mallocdoer(trivia_check);
su = (TrivScore*)Calloc(sizeof(TrivScore) + strlen(CurrentNick));
su->next = scorelist;
scorelist = su;
su->score_wk = su->score_mo = triv_score;
su->week_nr = week;
/* su->month_nr = 0; * fix this */
stringcpy(su->nick,CurrentNick);
}
to_server("PRIVMSG %s :Yes, %s! got the answer -> %s <- in %i seconds, and gets %i points!\n",
triv_chan->name,CurrentNick,triv_answers->p,
(int)(now - triv_ask_time),triv_score);
if (su == lastwinner)
{
triv_streak++;
if (su->score_wk == su->score_mo)
{
to_server("PRIVMSG %s :%s has won %i in a row! Total score this Week: %i points\n",
triv_chan->name,CurrentNick,triv_streak,su->score_wk);
}
else
{
to_server("PRIVMSG %s :%s has won %i in a row! Total score this Week: %i points, and this Month: %i points\n",
triv_chan->name,CurrentNick,triv_streak,su->score_wk,su->score_mo);
}
}
else
{
lastwinner = su;
triv_streak = 1;
if (su->score_wk == su->score_mo)
{
to_server("PRIVMSG %s :%s has won the question! Total score this Week: %i points\n",
triv_chan->name,CurrentNick,su->score_wk);
}
else
{
to_server("PRIVMSG %s :%s has won the question! Total score this Week: %i points, and this Month: %i points\n",
triv_chan->name,CurrentNick,su->score_wk,su->score_mo);
}
}
trivia_cleanup();
}
void trivia_no_answer(void)
{
to_server("PRIVMSG %s :Time's up! The answer was -> %s <-\n",
triv_chan->name,triv_answers->p);
trivia_cleanup();
}
char *random_question(char *triv_rand)
{
char *p,tmpname[120];
off_t sz;
int fd,ifd;
int n;
struct
{
int off;
int sz;
} entry;
if (STRCHR(triv_qfile,'/') || strlen(triv_qfile) > 100) // really bad filenames...
return(NULL);
stringcat(stringcpy(tmpname,"trivia/"),triv_qfile);
if ((fd = open(tmpname,O_RDONLY)) < 0)
#ifdef DEBUG
{
debug("(random_question) %s: %s\n",tmpname,strerror(errno));
return(NULL);
}
#else
return(NULL);
#endif /* DEBUG */
stringcpy(triv_rand,tmpname);
if ((p = STRCHR(triv_rand,'.')) == NULL)
p = STREND(triv_rand);
stringcpy(p,".index");
if ((ifd = open(triv_rand,O_RDONLY)) < 0)
return(NULL);
sz = lseek(ifd,0,SEEK_END);
sz = sz / sizeof(entry);
n = RANDOM(1,sz);
n--;
lseek(ifd,(n * sizeof(entry)),SEEK_SET);
if (read(ifd,&entry,sizeof(entry)) == -1)
return(NULL);
lseek(fd,entry.off,SEEK_SET);
if (read(fd,triv_rand,entry.sz) == -1)
return(NULL);
triv_rand[entry.sz] = 0;
close(fd);
close(ifd);
return(triv_rand);
}
void trivia_question(void)
{
char buffer[MSGLEN];
char *question,*answer,*rest;
if (triv_halt_flag)
{
to_server("PRIVMSG %s :Trivia has been stopped!\n",triv_chan->name);
goto stop_trivia;
}
if ((rest = random_question(buffer)) == NULL)
{
bad_question:
to_server("PRIVMSG %s :Bad Question File\n",triv_chan->name);
stop_trivia:
trivia_cleanup();
triv_chan = NULL;
triv_next_time = 0;
triv_halt_flag = FALSE;
short_tv &= ~TV_TRIVIA;
return;
}
question = get_token(&rest,MATCH_ALL);
while((answer = get_token(&rest,MATCH_ALL)))
append_strp(&triv_answers,answer);
if (triv_answers == NULL)
goto bad_question;
triv_score = (RANDOM(2,9) + RANDOM(2,10) + RANDOM(2,10)) / 3;
triv_ask_time = now;
if (now > (triv_weektop10 + 1200))
{
trivia_week_toppers();
triv_weektop10 = now;
}
to_server("PRIVMSG %s :%s\n",triv_chan->name,question);
hint_one();
}
void trivia_tick(void)
{
Chan *chan;
Mech *bot;
if (triv_next_time && (now >= triv_next_time))
{
for(bot=botlist;bot;bot=bot->next)
{
for(chan=bot->chanlist;chan;chan=chan->next)
{
if (triv_chan == chan)
{
current = bot;
triv_next_time = now + TRIV_HINT_DELAY;
switch(triv_mode)
{
case TRIV_WAIT_QUESTION:
trivia_question();
break;
case TRIV_HINT_TWO:
hint_two();
break;
case TRIV_HINT_THREE:
hint_three();
break;
case TRIV_NO_ANSWER:
trivia_no_answer();
return; /* dont increment with triv_mode */
}
triv_mode++;
#ifdef DEBUG
current = NULL;
#endif /* DEBUG */
return;
}
}
}
}
}
/*
*
* File operations
*
*/
void write_triviascore(void)
{
TrivScore *su;
int fd;
if (scorelist)
{
if ((fd = open(TRIVIASCOREFILE,O_WRONLY|O_TRUNC|O_CREAT,NEWFILEMODE)) < 0)
return;
to_file(fd,COMMENT_STRCHR " nick score_wk score_mo score_last_wk score_last_mo\n");
for(su=scorelist;su;su=su->next)
{
to_file(fd,"%s %i %i %i %i %i %i\n",su->nick,su->score_wk,su->score_mo,
su->score_last_wk,su->score_last_mo,su->week_nr,su->month_nr);
}
close(fd);
}
}
int trivia_score_callback(char *rest)
{
TrivScore *su;
char *nick,*wk,*mo,*lwk,*lmo,*wnr,*mnr;
int score_wk,score_mo,score_last_wk,score_last_mo;
int week_nr,month_nr;
int err;
if (*rest != COMMENT_CHAR)
{
nick = chop(&rest);
wk = chop(&rest);
mo = chop(&rest);
lwk = chop(&rest);
lmo = chop(&rest);
wnr = chop(&rest);
mnr = chop(&rest);
if (mnr)
{
score_wk = asc2int(wk);
err = errno;
score_mo = asc2int(mo);
err += errno;
score_last_wk = asc2int(lwk);
err += errno;
score_last_mo = asc2int(lmo);
err += errno;
week_nr = asc2int(wnr);
err += errno;
month_nr = asc2int(mnr);
err += errno;
if (!err)
{
set_mallocdoer(trivia_score_callback);
su = (TrivScore*)Calloc(sizeof(TrivScore) + strlen(nick));
su->next = scorelist;
scorelist = su;
su->score_wk = score_wk;
su->score_mo = score_mo;
su->score_last_wk = score_last_wk;
su->score_last_mo = score_last_mo;
su->week_nr = week_nr;
su->month_nr = month_nr;
stringcpy(su->nick,nick);
}
}
}
return(FALSE);
}
void read_triviascore(void)
{
TrivScore *su;
int fd;
if ((fd = open(TRIVIASCOREFILE,O_RDONLY)) < 0)
return;
while(scorelist)
{
su = scorelist;
scorelist = su->next;
Free((char**)&su);
}
readline(fd,&trivia_score_callback); /* readline closes fd */
}
#endif /* TRIVIA */
/*
-+=====================================================================================================================+-
toybox.c commands
-+=====================================================================================================================+-
*/
void do_bigsay(COMMAND_ARGS)
{
/*
@@ -465,3 +1005,80 @@ pick_randnum:
}
#endif /* TOYBOX */
#ifdef TRIVIA
void do_trivia(COMMAND_ARGS)
{
/*
* on_msg checks CAXS + CARGS
*/
Chan *chan;
int uaccess;
uaccess = get_maxaccess(from);
if ((chan = find_channel_ac(to)) == NULL)
{
if (uaccess) to_user(from,ERR_CHAN,to);
return;
}
if (!stringcasecmp(rest,"start"))
{
if (triv_chan)
{
if (triv_chan == chan)
{
triv_halt_flag = FALSE;
return;
}
if (uaccess) to_user(from,"trivia is already activated on %s!",
(get_useraccess(from,triv_chan->name)) ? triv_chan->name : "another channel");
return;
}
to_server("PRIVMSG %s :Trivia starting! Get ready...\n",chan->name);
triv_chan = chan;
triv_mode = TRIV_WAIT_QUESTION;
triv_next_time = now + triv_qdelay;
triv_weektop10 = now;
lastwinner = NULL;
short_tv |= TV_TRIVIA;
if (!scorelist)
{
read_triviascore();
}
}
else
if (!stringcasecmp(rest,"stop"))
{
if (chan == triv_chan)
{
if (chan == triv_chan)
to_server("PRIVMSG %s :Trivia shutting down...\n",chan->name);
triv_halt_flag = TRUE;
}
}
else
if (!stringcasecmp(rest,"top10"))
{
int n;
if (triv_chan)
{
uaccess = get_authaccess(from,triv_chan->name);
if (now > (triv_weektop10 + 300))
n = 1;
else
n = uaccess;
if (n)
{
trivia_week_toppers();
if (!uaccess) triv_weektop10 = now;
}
}
}
}
#endif /* TRIVIA */