`
);
}
this.modlog(`LOTTERY ${edited ? 'EDIT' : 'CREATE'} ${name}`, null, `${maxWinnersNum} max winners`);
},
delete(target, room, user) {
room = this.requireRoom();
this.checkCan('declare', null, room);
const lottery = lotteries[room.roomid];
if (!lottery) {
return this.errorReply('This room does not have a lottery running.');
}
destroyLottery(room.roomid);
this.addModAction(`${user.name} deleted the "${lottery.name}" lottery.`);
this.modlog('LOTTERY DELETE');
this.sendReply('The lottery was successfully deleted.');
},
end(target, room) {
room = this.requireRoom();
this.checkCan('declare', null, room);
const lottery = lotteries[room.roomid];
if (!lottery) {
return this.errorReply('This room does not have a lottery running.');
}
if (!lottery.running) {
return this.errorReply(`The "${lottery.name}" lottery already ended.`);
}
for (const [ip, participant] of Object.entries(lottery.participants)) {
const userid = toID(participant);
const pUser = Users.get(userid);
if (
Punishments.userids.get(userid) ||
Punishments.getRoomPunishments(pUser || userid, {publicOnly: true, checkIps: true}).length
) {
delete lottery.participants[ip];
}
}
if (lottery.maxWinners >= Object.keys(lottery.participants).length) {
return this.errorReply('There have been not enough participants for you to be able to end this. If you wish to end it anyway use /lottery delete.');
}
const winners = getWinnersInLottery(room.roomid);
if (!winners) return this.errorReply(`An error occured while getting the winners.`);
this.add(
Utils.html`|raw|
${Chat.toListString(winners)} won the "${lottery.name}" lottery!
`
);
this.modlog(`LOTTERY END ${lottery.name}`);
endLottery(room.roomid, winners);
},
join(target, room, user) {
// This hack is used for the HTML room to be able to
// join lotteries in other rooms from the global room
const roomid = target || room?.roomid;
if (!roomid) {
return this.errorReply(`This is not a valid room.`);
}
const lottery = lotteries[roomid];
if (!lottery) {
return this.errorReply(`${roomid} does not have a lottery running.`);
}
if (!lottery.running) {
return this.errorReply(`The "${lottery.name}" lottery already ended.`);
}
if (!user.named) {
return this.popupReply('You must be logged into an account to participate.');
}
if (!user.autoconfirmed) {
return this.popupReply('You must be autoconfirmed to join lotteries.');
}
if (user.locked || Punishments.getRoomPunishments(user, {publicOnly: true, checkIps: true}).length) {
return this.popupReply('Punished users cannot join lotteries.');
}
const success = addUserToLottery(roomid as RoomID, user);
if (success) {
this.popupReply('You have successfully joined the lottery.');
} else {
this.popupReply('You are already in the lottery.');
}
},
leave(target, room, user) {
// This hack is used for the HTML room to be able to
// join lotteries in other rooms from the global room
const roomid = target || room?.roomid;
if (!roomid) {
return this.errorReply('This can only be used in rooms.');
}
const lottery = lotteries[roomid];
if (!lottery) {
return this.errorReply(`${roomid} does not have a lottery running.`);
}
if (!lottery.running) {
return this.errorReply(`The "${lottery.name}" lottery already ended.`);
}
const success = removeUserFromLottery(roomid as RoomID, user);
if (success) {
this.popupReply('You have successfully left the lottery.');
} else {
this.popupReply('You have not joined the lottery.');
}
},
participants(target, room, user) {
room = this.requireRoom();
const lottery = lotteries[room.roomid];
if (!lottery) {
return this.errorReply('This room does not have a lottery running.');
}
const canSeeIps = user.can('ip');
const participants = Object.entries(lottery.participants).map(
([ip, participant]) => `- ${participant}${canSeeIps ? ' (IP: ' + ip + ')' : ''}`
);
let buf = '';
if (user.can('declare', null, room)) {
buf += `List of participants (${participants.length}):${participants.join(' ')}`;
} else {
buf += `${participants.length} participant(s) joined this lottery.`;
}
this.sendReplyBox(buf);
},
help() {
return this.parse('/help lottery');
},
},
lotteryhelp: [
`/lottery - opens the current lottery, if it exists.`,
`/lottery create max winners, name, html - creates a new lottery with [name] as the header and [html] as body. Max winners is the amount of people that will win the lottery. Requires # &`,
`/lottery delete - deletes the current lottery without declaring a winner. Requires # &`,
`/lottery end - ends the current lottery, declaring a random participant as the winner. Requires # &`,
`/lottery edit max winners, name, html - edits the lottery with the provided parameters. Requires # &`,
`/lottery join - joins the current lottery, if it exists, you need to be not currently punished in any public room, not locked and be autoconfirmed.`,
`/lottery leave - leaves the current lottery, if it exists.`,
`/lottery participants - shows the current participants in the lottery.`,
],
};
export const pages: PageTable = {
lottery(query, user) {
this.title = 'Lottery';
const room = this.requireRoom();
let buf = '