Skip to content
This repository was archived by the owner on Aug 21, 2025. It is now read-only.

Commit 77e29a0

Browse files
committed
command giveaway
1 parent eb7b6df commit 77e29a0

File tree

4 files changed

+201
-2
lines changed

4 files changed

+201
-2
lines changed
Lines changed: 197 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,217 @@
11
package fr.funixgaming.funixbot.twitch.commands;
22

3+
import fr.funixgaming.api.client.funixbot.dtos.FunixBotUserExperienceDTO;
34
import fr.funixgaming.funixbot.core.commands.entities.BotCommand;
5+
import fr.funixgaming.funixbot.core.exceptions.FunixBotException;
46
import fr.funixgaming.funixbot.twitch.FunixBot;
7+
import fr.funixgaming.funixbot.twitch.modules.ChatExperience;
8+
import fr.funixgaming.funixbot.twitch.utils.TwitchEmotes;
59
import fr.funixgaming.twitch.api.chatbot_irc.entities.ChatMember;
10+
import fr.funixgaming.twitch.api.chatbot_irc.entities.ChatMessage;
611
import lombok.NonNull;
12+
import lombok.extern.slf4j.Slf4j;
13+
import org.springframework.lang.Nullable;
714

15+
import java.security.SecureRandom;
16+
import java.util.ArrayList;
17+
import java.util.List;
18+
19+
@Slf4j
820
public class CommandGiveaway extends BotCommand {
21+
private static volatile CommandGiveaway instance = null;
922

1023
private final FunixBot bot;
1124

25+
private boolean active = false;
26+
private boolean subOnly = false;
27+
private int minimumChatLevel = 0;
28+
private String triggerWord = null;
29+
30+
private final List<ChatMember> participants = new ArrayList<>();
31+
private final List<ChatMember> bans = new ArrayList<>();
32+
1233
public CommandGiveaway(final FunixBot funixBot) {
1334
super("giveaway");
1435
this.bot = funixBot;
36+
instance = this;
1537
}
1638

1739
@Override
1840
public void onUserCommand(@NonNull ChatMember user, @NonNull String command, @NonNull String[] args) {
19-
//TODO impl giveaway
41+
if (user.getBadges().isModerator() || user.getBadges().isStreamer()) {
42+
if (args.length > 0) {
43+
final String action = args[0];
44+
45+
if (action.equalsIgnoreCase("start")) {
46+
endGiveaway();
47+
startGiveaway(args);
48+
} else if (action.equalsIgnoreCase("roll")) {
49+
final ChatMember winner = rollWinner();
50+
51+
if (winner == null) {
52+
bot.sendChatMessage(user.getChannelName(), "Pas de participants pour le giveaway.");
53+
} else {
54+
bot.sendChatMessage(winner.getChannelName(), String.format(
55+
"%s %s a gagné le giveaway !",
56+
TwitchEmotes.GIFT,
57+
winner.getDisplayName()
58+
));
59+
log.info("{} a gagné le giveaway.", winner.getDisplayName());
60+
}
61+
} else if (action.equalsIgnoreCase("stop") || action.equalsIgnoreCase("end")) {
62+
endGiveaway();
63+
bot.sendChatMessage(user.getChannelName(), String.format(
64+
"%s Fin du giveaway !",
65+
TwitchEmotes.GIFT
66+
));
67+
} else if (action.equalsIgnoreCase("help")) {
68+
bot.sendChatMessage(user.getChannelName(), "Help -> !giveaway start|stop|roll [triggerWord] [subOnly oui non, non défaut] [minimumChatLevel >= 0, 0 défaut]");
69+
}
70+
}
71+
}
72+
}
73+
74+
public void onUserChat(final ChatMessage chatMessage) throws FunixBotException {
75+
if (active && triggerWord != null) {
76+
final String message = chatMessage.getMessage();
77+
final ChatMember chatMember = chatMessage.getOwner();
78+
79+
if (message.equalsIgnoreCase(triggerWord) && notInList(chatMember) && notBanned(chatMember) && canParticipate(chatMember)) {
80+
participants.add(chatMember);
81+
bot.sendChatMessage(chatMember.getChannelName(), String.format(
82+
"%s %s a été ajouté aux participants du giveaway.",
83+
TwitchEmotes.GIFT,
84+
chatMember.getDisplayName()
85+
));
86+
log.info("{} a été ajouté aux participants du giveaway.", chatMember.getDisplayName());
87+
}
88+
}
89+
}
90+
91+
/**
92+
* !giveaway start [triggerWord] [subOnly oui non, non défaut] [minimumChatLevel >= 0, 0 défaut]
93+
* @param args command args
94+
*/
95+
private void startGiveaway(final String[] args) {
96+
this.active = true;
97+
98+
try {
99+
if (args.length >= 2) {
100+
this.triggerWord = args[1];
101+
}
102+
103+
if (args.length >= 3) {
104+
final String subOnly = args[2];
105+
106+
this.subOnly = subOnly.equalsIgnoreCase("oui") ||
107+
subOnly.equalsIgnoreCase("true") ||
108+
subOnly.equalsIgnoreCase("o") ||
109+
subOnly.equalsIgnoreCase("y");
110+
}
111+
112+
if (args.length >= 4) {
113+
try {
114+
final int minimumLevel = Integer.parseInt(args[3]);
115+
116+
if (minimumLevel < 0) {
117+
throw new NumberFormatException();
118+
} else {
119+
this.minimumChatLevel = minimumLevel;
120+
}
121+
} catch (NumberFormatException numberFormatException) {
122+
throw new FunixBotException("Le niveau entré est invalide. Veuillez entrer un nombre positif.");
123+
}
124+
}
125+
126+
bot.sendChatMessage(bot.getBotConfig().getStreamerUsername(), String.format(
127+
"%s Début du giveaway ! Mot clé -> %s",
128+
TwitchEmotes.GIFT,
129+
this.triggerWord
130+
));
131+
132+
} catch (FunixBotException e) {
133+
endGiveaway();
134+
bot.sendChatMessage(bot.getBotConfig().getStreamerUsername(), String.format(
135+
"%s Giveaway erreur -> %s",
136+
TwitchEmotes.GIFT,
137+
e.getMessage()
138+
));
139+
}
140+
}
141+
142+
@Nullable
143+
private ChatMember rollWinner() {
144+
if (this.participants.isEmpty()) {
145+
return null;
146+
}
147+
148+
final SecureRandom secureRandom = new SecureRandom();
149+
final int participantChosen = secureRandom.nextInt(this.participants.size());
150+
final ChatMember winner = this.participants.get(participantChosen);
151+
152+
this.participants.remove(winner);
153+
this.bans.add(winner);
154+
return winner;
155+
}
156+
157+
private void endGiveaway() {
158+
active = false;
159+
subOnly = false;
160+
minimumChatLevel = 0;
161+
triggerWord = null;
162+
participants.clear();
163+
bans.clear();
164+
}
165+
166+
private boolean canParticipate(final ChatMember chatMember) throws FunixBotException {
167+
if (this.subOnly && !chatMember.getBadges().isSubscriber()) {
168+
bot.sendChatMessage(chatMember.getChannelName(), String.format(
169+
"%s %s Ce giveaway est réservé aux abonnés twitch (!sub).",
170+
chatMember.getDisplayName(),
171+
TwitchEmotes.GIFT
172+
));
173+
return false;
174+
}
175+
176+
if (this.minimumChatLevel > 0) {
177+
final FunixBotUserExperienceDTO userLevel = ChatExperience.getInstance().findExpByUserId(Integer.toString(chatMember.getUserId()));
178+
179+
if (userLevel == null || userLevel.getLevel() < this.minimumChatLevel) {
180+
bot.sendChatMessage(chatMember.getChannelName(), String.format(
181+
"%s %s Ce giveaway est réservé aux membres de niveau %d (!level).",
182+
TwitchEmotes.GIFT,
183+
chatMember.getDisplayName(),
184+
this.minimumChatLevel
185+
));
186+
return false;
187+
}
188+
}
189+
190+
return true;
191+
}
192+
193+
private boolean notInList(final ChatMember chatMember) {
194+
for (final ChatMember participant : participants) {
195+
if (participant.getUserId() == chatMember.getUserId()) {
196+
return false;
197+
}
198+
}
199+
return true;
200+
}
201+
202+
private boolean notBanned(final ChatMember chatMember) {
203+
for (final ChatMember banned : this.bans) {
204+
if (banned.getUserId() == chatMember.getUserId()) {
205+
return false;
206+
}
207+
}
208+
return true;
209+
}
210+
211+
public static CommandGiveaway getInstance() throws FunixBotException {
212+
if (instance == null) {
213+
throw new FunixBotException("CommandGiveaway not loaded.");
214+
}
215+
return instance;
20216
}
21217
}

FunixBot-Twitch/src/main/java/fr/funixgaming/funixbot/twitch/events/FunixBotEvents.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import fr.funixgaming.funixbot.core.commands.CommandHandler;
44
import fr.funixgaming.funixbot.core.exceptions.FunixBotException;
55
import fr.funixgaming.funixbot.twitch.FunixBot;
6+
import fr.funixgaming.funixbot.twitch.commands.CommandGiveaway;
67
import fr.funixgaming.funixbot.twitch.modules.AutoMessages;
78
import fr.funixgaming.funixbot.twitch.modules.ChatExperience;
89
import fr.funixgaming.twitch.api.chatbot_irc.TwitchEvents;
@@ -32,6 +33,7 @@ public void onUserChat(UserChatEvent event) {
3233
commandHandler.onNewChat(chatMember, message, FunixBot.getInstance(), chatMember.getChannelName());
3334
autoMessages.userMessage();
3435
chatExperience.userChatExp(chatMember);
36+
CommandGiveaway.getInstance().onUserChat(chatMessage);
3537

3638
log.info("[" + chatMember.getDisplayName() + "] " + message);
3739
} catch (FunixBotException e) {

FunixBot-Twitch/src/main/java/fr/funixgaming/funixbot/twitch/modules/AutoMessages.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
@Component
1212
public class AutoMessages {
13-
private static final int LIMIT_MESSAGES = 15;
13+
private static final int LIMIT_MESSAGES = 20;
1414

1515
private final String[] messages;
1616
private int count = 0;

FunixBot-Twitch/src/main/java/fr/funixgaming/funixbot/twitch/utils/TwitchEmotes.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,5 @@
22

33
public class TwitchEmotes {
44
public final static String TWITCH_LOGO = "imGlitch";
5+
public final static String GIFT = "HolidayPresent";
56
}

0 commit comments

Comments
 (0)