1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
|
/* $Id: openticket.c,v 1.9 2002/11/02 11:02:44 in2 Exp $ */
/* 開獎的 utility */
#define _UTIL_C_
#include "bbs.h"
static char *betname[8] = {"Ptt", "Jaky", "Action", "Heat",
"DUNK", "Jungo", "waiting", "wofe"};
#define MAX_DES 7 /* 最大保留獎數 */
extern userec_t xuser;
int Link(char *src, char *dst)
{
char cmd[200];
if (link(src, dst) == 0)
return 0;
sprintf(cmd, "/bin/cp -R %s %s", src, dst);
return system(cmd);
}
char *
Cdatelite(clock)
time_t *clock;
{
static char foo[18];
struct tm *mytm = localtime(clock);
strftime(foo, 18, "%D %T", mytm);
return (foo);
}
int main()
{
int money, bet, n, total = 0, ticket[8] =
{0, 0, 0, 0, 0, 0, 0, 0};
FILE *fp;
time_t now = time(NULL);
char des[MAX_DES][200] =
{"", "", "", ""};
nice(10);
if(passwd_mmap())
exit(1);
rename(BBSHOME "/etc/" FN_TICKET_RECORD,
BBSHOME "/etc/" FN_TICKET_RECORD ".tmp");
rename(BBSHOME "/etc/" FN_TICKET_USER,
BBSHOME "/etc/" FN_TICKET_USER ".tmp");
if (!(fp = fopen(BBSHOME "/etc/"FN_TICKET_RECORD ".tmp", "r")))
return 0;
fscanf(fp, "%9d %9d %9d %9d %9d %9d %9d %9d\n",
&ticket[0], &ticket[1], &ticket[2], &ticket[3],
&ticket[4], &ticket[5], &ticket[6], &ticket[7]);
for (n = 0; n < 8; n++)
total += ticket[n];
fclose(fp);
if (!total)
return 0;
if((fp = fopen(BBSHOME "/etc/" FN_TICKET , "r")))
{
for (n = 0; n < MAX_DES && fgets(des[n], 200, fp); n++) ;
fclose(fp);
}
srandom(33); // 固定一個 seed 但盡量要避免跟別人的seed同
for( n = (now / (60*60*3)) - 62820; n >0; n--) random();
/*
* 正確的random number generator的用法
* 是用同一個 seed後取 第一個 第二個 地三個.... 數
* srand() 設完seed後
* 每呼叫一次rand()就取下一個數
*
* 但因為我們沒有記錄上次取到第幾個
* 所以用每增四小時()就多取一次 => now / (60*60*4) (每五小時開一次獎)
* (減 61820 是減少 loop 數)
*
* 本來是用srand(time(0)) 不是正確的用法
* 因為開獎時間有規率 所以會被找出規律
*
* ~Ptt
*/
bet=random() % 8;
resolve_utmp();
bet = SHM->UTMPnumber % 8;
/*
* 在C中 srand 跟 srandom 一樣 rand 跟 random 一樣
* 不同的是 rand 是傳回一個 double 給非整數的亂數用
* random 是傳回一個 int 給整數的亂數用
*
* 若要以rand inplement 整數的亂數 要注意以下 (man page中有)
*
* In Numerical Recipes in C: The Art of Scientific Computing
* (William H. Press, Brian P. Flannery, Saul A. Teukolsky,
* William T. Vetterling; New York: Cambridge University
* Press, 1990 (1st ed, p. 207)), the following comments are
* made:
* "If you want to generate a random integer between 1
* and 10, you should always do it by
*
* j=1+(int) (10.0*rand()/(RAND_MAX+1.0));
*
* and never by anything resembling
*
* j=1+((int) (1000000.0*rand()) % 10);
*
* (which uses lower-order bits)."
*
* Random-number generation is a complex topic. The Numeri-
* cal Recipes in C book (see reference above) provides an
* excellent discussion of practical random-number generation
* issues in Chapter 7 (Random Numbers).
* ~ Ptt
*/
money = ticket[bet] ? total * 95 / ticket[bet] : 9999999;
if((fp = fopen(BBSHOME "/etc/" FN_TICKET, "w")))
{
if (des[MAX_DES - 1][0])
n = 1;
else
n = 0;
for (; n < MAX_DES && des[n][0] != 0; n++)
{
fprintf(fp, des[n]);
}
printf("\n\n開獎時間: %s \n\n"
"開獎結果: %s \n\n"
"下注總金額: %d00 元 \n"
"中獎比例: %d張/%d張 (%f)\n"
"每張中獎彩票可得 %d 枚P幣 \n\n",
Cdatelite(&now), betname[bet], total, ticket[bet], total,
(float) ticket[bet] / total, money);
fprintf(fp, "%s 賭盤開出:%s 總金額:%d00 元 獎金/張:%d 元 機率:%1.2f\n",
Cdatelite(&now), betname[bet], total, money,
(float) ticket[bet] / total);
fclose(fp);
}
if (ticket[bet] && (fp = fopen(BBSHOME "/etc/" FN_TICKET_USER ".tmp", "r")))
{
int mybet, num, uid;
char userid[20], genbuf[200];
fileheader_t mymail;
while (fscanf(fp, "%s %d %d\n", userid, &mybet, &num) != EOF)
{
if (mybet == bet)
{
printf("恭喜 %-15s買了%9d 張 %s, 獲得 %d 枚P幣\n"
,userid, num, betname[mybet], money * num);
if((uid=getuser(userid))==0) continue;
deumoney(uid, money * num);
sprintf(genbuf, BBSHOME "/home/%c/%s", userid[0], userid);
stampfile(genbuf, &mymail);
strcpy(mymail.owner, BBSNAME);
sprintf(mymail.title, "[%s] 中獎囉! $ %d", Cdatelite(&now), money * num);
unlink(genbuf);
Link(BBSHOME "/etc/ticket", genbuf);
sprintf(genbuf, BBSHOME "/home/%c/%s/.DIR", userid[0], userid);
append_record(genbuf, &mymail, sizeof(mymail));
}
}
}
unlink(BBSHOME "/etc/" FN_TICKET_RECORD ".tmp");
unlink(BBSHOME "/etc/" FN_TICKET_USER ".tmp");
return 0;
}
|