00001
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040 #include "services.h"
00041 #include "nickserv.h"
00042 #include "chanserv.h"
00043 #include "log.h"
00044 #include "interp.h"
00045
00049 interp::service_cmd_t gameserv_commands[] = {
00050
00051 { "help", gs_help, 0, LOG_NO, 0, 1},
00052 { "roll", gs_roll, 0, LOG_NO, 0, 1},
00053 { NULL },
00054 };
00055
00056
00057
00058
00068 void
00069 sendToGameServ(UserList * nick, char **args, int numargs)
00070 {
00071 char *from = nick->nick;
00072 interp::parser * cmd;
00073
00074 if (!nick)
00075 return;
00076
00077 cmd =
00078 new interp::parser(GameServ, getOpFlags(nick), gameserv_commands,
00079 args[0]);
00080 if (!cmd)
00081 return;
00082
00083 switch (cmd->run(nick, args, numargs)) {
00084 default:
00085 break;
00086 case RET_FAIL:
00087 sSend(":%s NOTICE %s :Unknown command %s.\r\n"
00088 ":%s NOTICE %s :Please try /msg %s HELP", GameServ, from,
00089 args[0], GameServ, from, GameServ);
00090 break;
00091 }
00092
00093 delete cmd;
00094 }
00095
00096
00097
00098
00110 int
00111 dice(int dice, int sides)
00112 {
00113 int res = 0;
00114
00115
00116 if (dice < 1 || sides < 1)
00117 return 0;
00118
00119
00120 while (dice-- > 0) {
00121 res += 1+(int)(((float)sides * rand()) / (RAND_MAX + 1.0));
00122
00123 }
00124
00125 return res;
00126 }
00127
00128
00129
00130
00131
00135 GCMD(gs_help)
00136 {
00137 char *from = nick->nick;
00138
00139 help(from, GameServ, args, numargs);
00140 return RET_OK;
00141 }
00142
00143
00144
00151 GCMD(gs_roll)
00152 {
00153 char *from = nick->nick;
00154 char *to = nick->nick;
00155 char *string = args[1];
00156 int rolls = 1;
00157 int num_dice = 1;
00158 int num_sides = 1;
00159 int mod = 0;
00160 int multiplier = 1;
00161 int counter = 0;
00162 int i, l = 0, *last_arg = &num_sides;
00163 int result = 0;
00164 char dicebuf[IRCBUF], rollbuf[IRCBUF];
00165 ChanList *chan;
00166
00167 if (numargs < 2) {
00168 sSend(":%s NOTICE %s :Not enough parameters.\r\n"
00169 ":%s NOTICE %s :/msg %s HELP %s for assistance.", GameServ,
00170 nick->nick, GameServ, nick->nick, GameServ, args[0]);
00171 return RET_SYNTAX;
00172 }
00173
00174 if (numargs == 3) {
00175 chan = getChanData(args[1]);
00176 if (!chan || !chan->reg) {
00177 sSend(":%s NOTICE %s :%s: No such registered channel is open.",
00178 GameServ, from, args[1]);
00179 return RET_NOTARGET;
00180 }
00181 if (!getChanUserData(chan, nick)) {
00182 sSend(":%s NOTICE %s :%s: You are not on that channel.",
00183 GameServ, from, args[1]);
00184 return RET_EFAULT;
00185 }
00186 if (getChanOp(chan->reg, nick->nick) < 4 && !isRoot(nick)) {
00187 sSend
00188 (":%s NOTICE %s :%s: You must be a channel operator to do this.",
00189 GameServ, from, args[1]);
00190 return RET_EFAULT;
00191 }
00192 to = args[1];
00193 string = args[2];
00194 }
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208 for (i = 0, l = 0; string[i] && (i < 30); i++)
00209 switch (tolower(string[i])) {
00210 case '#':
00211 if (isdigit(*(string + i - l)))
00212 rolls = atoi(string + i - l);
00213 last_arg = &num_dice;
00214 l = 0;
00215 break;
00216 case 'd':
00217 if (isdigit(*(string + i - l)))
00218 num_dice = atoi(string + i - l);
00219 last_arg = &num_sides;
00220 l = 0;
00221 break;
00222 case '%':
00223 num_sides = 100;
00224 last_arg = NULL;
00225 l = 0;
00226 break;
00227 case '-':
00228 case '+':
00229 if (string[i] == '-')
00230 multiplier = -1;
00231 else
00232 multiplier = 1;
00233 if (isdigit(*(string + i - l)))
00234 num_sides = atoi(string + i - l);
00235 last_arg = &mod;
00236 l = 0;
00237 break;
00238 default:
00239 l++;
00240 break;
00241 }
00242 if (last_arg != NULL && l) {
00243 if (last_arg == &mod) {
00244 char *p = (string + i - l);
00245
00246 if (*p == '-' || *p == '+')
00247 p++;
00248 if (isdigit(*p))
00249 *last_arg = multiplier * atoi(p);
00250 } else
00251 *last_arg = atoi(string + i - l);
00252 }
00253
00254 if (*to == '#' && rolls > 10) {
00255 sSend(":%s NOTICE %s :Limited to 10 rolls for channels.", GameServ,
00256 from);
00257 rolls = 10;
00258 }
00259
00260 if (rolls > 100)
00261 rolls = 100;
00262 if (num_dice > 256)
00263 num_dice = 256;
00264 if (num_sides > 256)
00265 num_sides = 256;
00266 if (mod > 10000)
00267 mod = 10000;
00268 if (mod < -10000)
00269 mod = (-10000);
00270
00271
00272
00273
00274 dicebuf[0] = rollbuf[0] = '\0';
00275
00276 for (i = 0, counter = 0; i < rolls; i++) {
00277 result = (dice(num_dice, num_sides) + mod);
00278 if (*dicebuf)
00279 strcpy(rollbuf, ", ");
00280 else
00281 rollbuf[0] = '\0';
00282 sprintf(rollbuf + strlen(rollbuf), "%2d", result);
00283 strcat(dicebuf, rollbuf);
00284 if (counter++ >= 5 || strlen(dicebuf) >= (sizeof(IRCBUF) - 15)) {
00285 if (nick->floodlevel.GetLev() < (.75 * MAXFLOODLEVEL))
00286 if (addFlood(nick, *to == '#' ? 5 : 1))
00287 return RET_KILLED;
00288 counter = 0;
00289 if (*to == '#')
00290 sSend(":%s PRIVMSG %s :Result (%s) (%d#%dd%d%c%d): %s",
00291 GameServ, to, from, rolls, num_dice, num_sides,
00292 mod >= 0 ? '+' : '-', abs(mod), dicebuf);
00293 else
00294 sSend(":%s NOTICE %s :Result (%d#%dd%d%c%d): %s", GameServ,
00295 to, rolls, num_dice, num_sides, mod >= 0 ? '+' : '-',
00296 abs(mod), dicebuf);
00297 dicebuf[0] = '\0';
00298 }
00299 }
00300 if (counter) {
00301 if (*to == '#')
00302 sSend(":%s PRIVMSG %s :Result (%s) (%d#%dd%d%c%d): %s",
00303 GameServ, to, from, rolls, num_dice, num_sides,
00304 mod >= 0 ? '+' : '-', abs(mod), dicebuf);
00305 else
00306 sSend(":%s NOTICE %s :Result (%d#%dd%d%c%d): %s", GameServ, to,
00307 rolls, num_dice, num_sides, mod >= 0 ? '+' : '-',
00308 abs(mod), dicebuf);
00309 }
00310 return RET_OK;
00311 }