From 085c9a93cf63c5511f28005deb06f8ba25c8b667 Mon Sep 17 00:00:00 2001 From: wens Date: Tue, 8 Mar 2005 16:18:04 +0000 Subject: add "cool down" feature for boards. git-svn-id: http://opensvn.csie.org/pttbbs/trunk/pttbbs@2582 63ad8ddf-47c3-0310-b6dd-a9e9d9715204 --- include/proto.h | 4 ++++ include/pttstruct.h | 41 +++++++++++++++++++--------------- mbbsd/bbs.c | 63 +++++++++++++++++++++++++++++++++++++++++++++++++++++ mbbsd/board.c | 23 +++++++++++++++++++ mbbsd/cache.c | 9 ++++++++ mbbsd/mail.c | 13 +++++++++++ sample/pttbbs.conf | 3 +++ util/shmctl.c | 3 +++ util/uhash_loader.c | 3 +++ 9 files changed, 145 insertions(+), 17 deletions(-) diff --git a/include/proto.h b/include/proto.h index 771151c5..78acebbc 100644 --- a/include/proto.h +++ b/include/proto.h @@ -154,6 +154,10 @@ int is_BM_cache(int); void buildBMcache(int); void reload_bcache(void); void reload_fcache(void); +#ifdef USE_COOLDOWN +#define cooldowntimeof(uid) SHM->cooldowntime[uid - 1] +void add_cooldowntime(int uid, int min); +#endif /* cal */ int give_tax(int money); diff --git a/include/pttstruct.h b/include/pttstruct.h index b08e9bbe..ec740c2c 100644 --- a/include/pttstruct.h +++ b/include/pttstruct.h @@ -212,6 +212,9 @@ typedef struct boardheader_t { #define BRD_LOCALSAVE 000400000 /* 預設 Local Save */ #define BRD_RESTRICTEDPOST 001000000 /* 板友才能發文 */ #define BRD_GUESTPOST 002000000 /* guest能 post */ +#ifdef USE_COOLDOWN +#define BRD_COOLDOWN 004000000 /* 冷靜 */ +#endif #define BRD_LINK_TARGET(x) ((x)->postexpire) #define GROUPOP() (currmode & MODE_GROUPOP) @@ -460,7 +463,7 @@ typedef struct keeploc_t { /* MAX_BMs is dirty hardcode 4 in mbbsd/cache.c:is_BM_cache() */ #define MAX_BMs 4 /* for BMcache, 一個看板最多幾板主 */ -#define SHM_VERSION 2549 +#define SHM_VERSION 2582 typedef struct { int version; /* uhash */ @@ -471,18 +474,22 @@ typedef struct { char gap_2[sizeof(int)]; int money[MAX_USERS]; char gap_3[sizeof(int)]; - int hash_head[1 << HASH_BITS]; +#ifdef USE_COOLDOWN + time4_t cooldowntime[MAX_USERS]; +#endif char gap_4[sizeof(int)]; + int hash_head[1 << HASH_BITS]; + char gap_5[sizeof(int)]; int number; /* # of users total */ int loaded; /* .PASSWD has been loaded? */ /* utmpshm */ userinfo_t uinfo[USHM_SIZE]; - char gap_5[sizeof(userinfo_t)]; + char gap_6[sizeof(userinfo_t)]; int sorted[2][8][USHM_SIZE]; /* 第一維double buffer 由currsorted指向目前使用的 第二維sort type */ - char gap_6[sizeof(int)]; + char gap_7[sizeof(int)]; int currsorted; time4_t UTMPuptime; int UTMPnumber; @@ -490,28 +497,28 @@ typedef struct { char UTMPbusystate; /* brdshm */ - char gap_7[sizeof(int)]; - int BMcache[MAX_BOARD][MAX_BMs]; char gap_8[sizeof(int)]; - boardheader_t bcache[MAX_BOARD]; + int BMcache[MAX_BOARD][MAX_BMs]; char gap_9[sizeof(int)]; - int bsorted[2][MAX_BOARD]; /* 0: by name 1: by class */ /* 裡頭存的是 bid-1 */ + boardheader_t bcache[MAX_BOARD]; char gap_10[sizeof(int)]; + int bsorted[2][MAX_BOARD]; /* 0: by name 1: by class */ /* 裡頭存的是 bid-1 */ + char gap_11[sizeof(int)]; #if HOTBOARDCACHE unsigned char nHOTs; int HBcache[HOTBOARDCACHE]; #endif - char gap_11[sizeof(int)]; - time4_t busystate_b[MAX_BOARD]; char gap_12[sizeof(int)]; - int total[MAX_BOARD]; + time4_t busystate_b[MAX_BOARD]; char gap_13[sizeof(int)]; - unsigned char n_bottom[MAX_BOARD]; /* number of bottom */ + int total[MAX_BOARD]; char gap_14[sizeof(int)]; - int hbfl[MAX_BOARD][MAX_FRIEND + 1]; /* hidden board friend list, 0: load time, 1-MAX_FRIEND: uid */ + unsigned char n_bottom[MAX_BOARD]; /* number of bottom */ char gap_15[sizeof(int)]; - time4_t lastposttime[MAX_BOARD]; + int hbfl[MAX_BOARD][MAX_FRIEND + 1]; /* hidden board friend list, 0: load time, 1-MAX_FRIEND: uid */ char gap_16[sizeof(int)]; + time4_t lastposttime[MAX_BOARD]; + char gap_17[sizeof(int)]; time4_t Buptime; time4_t Btouchtime; int Bnumber; @@ -520,12 +527,12 @@ typedef struct { /* pttcache */ char notes[MAX_MOVIE][200*11]; - char gap_17[sizeof(int)]; + char gap_18[sizeof(int)]; char today_is[20]; int n_notes[MAX_MOVIE_SECTION]; /* 一節中有幾個 看板 */ - char gap_18[sizeof(int)]; - int next_refresh[MAX_MOVIE_SECTION]; /* 下一次要refresh的 看板 */ char gap_19[sizeof(int)]; + int next_refresh[MAX_MOVIE_SECTION]; /* 下一次要refresh的 看板 */ + char gap_20[sizeof(int)]; msgque_t loginmsg; /* 進站水球 */ int max_film; int max_history; diff --git a/mbbsd/bbs.c b/mbbsd/bbs.c index d8da50b0..43d6e2aa 100644 --- a/mbbsd/bbs.c +++ b/mbbsd/bbs.c @@ -551,6 +551,15 @@ do_general(int isbid) vmsg("你不夠資深喔!"); return FULLUPDATE; } + +#ifdef USE_COOLDOWN + if ( !((currmode & MODE_BOARD) || HAS_PERM(PERM_SYSOP)) && + ((currbrdattr & BRD_COOLDOWN) && now < cooldowntimeof(usernum)) ) { + move(5, 10); + vmsg("冷靜一下吧!"); + return FULLUPDATE; + } +#endif #endif #ifdef NO_WATER_POST @@ -767,6 +776,10 @@ do_general(int isbid) } if (currbrdattr & BRD_ANONYMOUS) do_crosspost("UnAnonymous", &postfile, fpath); +#ifdef USE_COOLDOWN + if (currbrdattr & BRD_COOLDOWN) + add_cooldowntime(usernum, 5); +#endif } pressanykey(); return FULLUPDATE; @@ -1042,6 +1055,15 @@ cross_post(int ent, fileheader_t * fhdr, char *direct) return FULLUPDATE; } +#ifdef USE_COOLDOWN + if ( !((currmode & MODE_BOARD) || HAS_PERM(PERM_SYSOP)) && + ((bcache[author - 1].brdattr & BRD_COOLDOWN) && now < cooldowntimeof(usernum)) ) { + move(5, 10); + vmsg("冷靜一下吧!"); + return FULLUPDATE; + } +#endif + ent = 1; author = 0; if (HAS_PERM(PERM_SYSOP) || !strcmp(fhdr->owner, cuser.userid)) { @@ -1103,6 +1125,10 @@ cross_post(int ent, fileheader_t * fhdr, char *direct) bp = getbcache(getbnum(xboard)); if (!xfile.filemode && !(bp->brdattr & BRD_NOTRAN)) outgo_post(&xfile, xboard, cuser.userid, cuser.username); +#ifdef USE_COOLDOWN + if (bp->brdattr & BRD_COOLDOWN) + add_cooldowntime(usernum, 5); +#endif setbtotal(getbnum(xboard)); cuser.numposts++; UPDATE_USEREC; @@ -1951,6 +1977,10 @@ del_post(int ent, fileheader_t * fhdr, char *direct) if (not_owned && tusernum && fhdr->multi.money > 0 && strcmp(currboard, "Test")) { deumoney(tusernum, -fhdr->multi.money); +#ifdef USE_COOLDOWN + if (bp->brdattr & BRD_COOLDOWN) + add_cooldowntime(tusernum, 15); +#endif } if (!not_owned && strcmp(currboard, "Test")) { if (cuser.numposts) @@ -2560,6 +2590,35 @@ change_restrictedpost(int ent, fileheader_t * fhdr, char *direct){ return FULLUPDATE; } +#ifdef USE_COOLDOWN +/** + * 設定看板冷靜功能, 限制使用者發文時間 + */ +static int +change_cooldown(int ent, fileheader_t * fhdr, char *direct) +{ + boardheader_t *bp = getbcache(currbid); + + if (!HAS_PERM(PERM_SYSOP)) + return DONOTHING; + + if (bp->brdattr & BRD_COOLDOWN) { + if (getans("目前降溫中, 要開放嗎(y/N)?") != 'y') + return FULLUPDATE; + bp->brdattr &= ~BRD_COOLDOWN; + outs("大家都可以 post 文章了。\n"); + } else { + if (getans("要限制 post 頻率, 降溫嗎(y/N)?") != 'y') + return FULLUPDATE; + bp->brdattr |= BRD_COOLDOWN; + outs("開始冷靜。\n"); + } + substitute_record(fn_board, bp, sizeof(boardheader_t), currbid); + pressanykey(); + return FULLUPDATE; +} +#endif + /* ----------------------------------------------------- */ /* 看板功能表 */ /* ----------------------------------------------------- */ @@ -2567,7 +2626,11 @@ change_restrictedpost(int ent, fileheader_t * fhdr, char *direct){ const onekey_t read_comms[] = { show_filename, // Ctrl('A') NULL, // Ctrl('B') +#ifdef USE_COOLDOWN + change_cooldown, // Ctrl('C') +#else NULL, // Ctrl('C') +#endif NULL, // Ctrl('D') change_restrictedpost, // Ctrl('E') NULL, // Ctrl('F') diff --git a/mbbsd/board.c b/mbbsd/board.c index 3fb53483..ff3fb610 100644 --- a/mbbsd/board.c +++ b/mbbsd/board.c @@ -192,6 +192,23 @@ addnewbrdstat(int n, int state) static int cmpboardfriends(const void *brd, const void *tmp) { +#ifdef USE_COOLDOWN + if ((B_BH((boardstat_t*)tmp)->brdattr & BRD_COOLDOWN) && + (B_BH((boardstat_t*)brd)->brdattr & BRD_COOLDOWN)) + return 0; + else if ( B_BH((boardstat_t*)tmp)->brdattr & BRD_COOLDOWN ) { + if (B_BH((boardstat_t*)brd)->nuser == 0) + return 0; + else + return 1; + } + else if ( B_BH((boardstat_t*)brd)->brdattr & BRD_COOLDOWN ) { + if (B_BH((boardstat_t*)tmp)->nuser == 0) + return 0; + else + return -1; + } +#endif return ((B_BH((boardstat_t*)tmp)->nuser) - (B_BH((boardstat_t*)brd)->nuser)); } @@ -543,7 +560,13 @@ show_brdlist(int head, int clsflag, int newflag) B_BH(ptr)->title[3] + B_BH(ptr)->title[0]) & 07], B_BH(ptr)->title, B_BH(ptr)->title + 5, B_BH(ptr)->title + 7); +#ifdef USE_COOLDOWN + if (B_BH(ptr)->brdattr & BRD_COOLDOWN) + outs("靜 "); + else if (B_BH(ptr)->brdattr & BRD_BAD) +#else if (B_BH(ptr)->brdattr & BRD_BAD) +#endif outs(" X "); else if (B_BH(ptr)->nuser >= 5000) outs("\033[1;34m爆!\033[m"); diff --git a/mbbsd/cache.c b/mbbsd/cache.c index 4933339f..d32d7f15 100644 --- a/mbbsd/cache.c +++ b/mbbsd/cache.c @@ -1031,3 +1031,12 @@ hbflcheck(int bid, int uid) } return 1; } + +#ifdef USE_COOLDOWN +void add_cooldowntime(int uid, int min) +{ + time4_t new = now + 60 * min; + time4_t old = SHM->cooldowntime[uid - 1]; + SHM->cooldowntime[uid - 1] = new > old ? new : old; +} +#endif diff --git a/mbbsd/mail.c b/mbbsd/mail.c index 5d4ba3b3..7d953388 100644 --- a/mbbsd/mail.c +++ b/mbbsd/mail.c @@ -1053,6 +1053,15 @@ mail_cross_post(int ent, fileheader_t * fhdr, char *direct) return FULLUPDATE; } +#ifdef USE_COOLDOWN + if ( !((currmode & MODE_BOARD) || HAS_PERM(PERM_SYSOP)) && + ((bcache[ent - 1].brdattr & BRD_COOLDOWN) && now < cooldowntimeof(usernum)) ) { + move(5, 10); + vmsg("冷靜一下吧!"); + return FULLUPDATE; + } +#endif + ent = 1; if (HAS_PERM(PERM_SYSOP) || !strcmp(fhdr->owner, cuser.userid)) { getdata(2, 0, "(1)原文轉載 (2)舊轉錄格式?[1] ", @@ -1117,6 +1126,10 @@ mail_cross_post(int ent, fileheader_t * fhdr, char *direct) setbtotal(getbnum(xboard)); if (!xfile.filemode) outgo_post(&xfile, xboard, cuser.userid, cuser.username); +#ifdef USE_COOLDOWN + if (bcache[getbnum(xboard) - 1].brdattr & BRD_COOLDOWN) + add_cooldowntime(usernum, 5); +#endif cuser.numposts++; vmsg("文章轉錄完成"); currmode = currmode0; diff --git a/sample/pttbbs.conf b/sample/pttbbs.conf index e847ab96..8abc066b 100644 --- a/sample/pttbbs.conf +++ b/sample/pttbbs.conf @@ -127,6 +127,9 @@ /* 使用 HUGETLB shared memory . 目前只在 Linux 上有效 */ //#define USE_HUGETLB +/* 讓過於熱門或被鬧的版冷靜, SHM 會變大一些些 */ +#define USE_COOLDOWN + /* 若定義, 則在刪除看板文章的時候, 僅會在 .DIR 中標明, 並不會將該資料 從 .DIR 中拿掉. 可以避免多項問題 (尤其是熱門看板一堆推薦及編輯時) 須配合使用 (尚未完成) */ diff --git a/util/shmctl.c b/util/shmctl.c index 077566ab..0686786a 100644 --- a/util/shmctl.c +++ b/util/shmctl.c @@ -419,6 +419,9 @@ inline void utmpsort(int sortall) if( nusers[i] > 8 && (top < HOTBOARDCACHE || nusers[i] > last) && IS_BOARD(&SHM->bcache[i]) && +#ifdef USE_COOLDOWN + !(SHM->bcache[i].brdattr & BRD_COOLDOWN) && +#endif IS_OPENBRD(&SHM->bcache[i]) ){ for( k = top - 1 ; k >= 0 ; --k ) if(HBcache[k]>=0 && diff --git a/util/uhash_loader.c b/util/uhash_loader.c index 6a0bfaf4..0c7da6db 100644 --- a/util/uhash_loader.c +++ b/util/uhash_loader.c @@ -150,6 +150,9 @@ void userec_add_to_uhash(int n, userec_t *user, int onfly) { strcpy(SHM->userid[n], user->userid); SHM->money[n] = user->money; +#ifdef USE_COOLDOWN + SHM->cooldowntime[n] = 0; +#endif if(onfly) printf("add %s\n", user->userid); } -- cgit v1.2.3