Skip to content

Commit 7399a61

Browse files
authored
Implement captcha picker
1 parent dce57fd commit 7399a61

File tree

3 files changed

+213
-5
lines changed

3 files changed

+213
-5
lines changed

DefaultPlugin.iml

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
<orderEntry type="inheritedJdk" />
1212
<orderEntry type="sourceFolder" forTests="false" />
1313
<orderEntry type="library" name="Maven: com.github.darkbot-reloaded:DarkBot:master-2d5ec8d194-1" level="project" />
14-
<orderEntry type="library" name="Maven: com.github.darkbot-reloaded:DarkBot:master-be65761a9f-1" level="project" />
14+
<orderEntry type="library" name="Maven: com.github.darkbot-reloaded:DarkBot:master-cfa751249d-1" level="project" />
1515
<orderEntry type="library" name="Maven: com.google.code.gson:gson:2.8.5" level="project" />
1616
<orderEntry type="library" name="Maven: com.formdev:flatlaf:0.36" level="project" />
1717
<orderEntry type="library" name="Maven: com.miglayout:miglayout:3.7.4" level="project" />
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,207 @@
1+
package eu.darkbot.popcorn.def;
2+
3+
import com.github.manolo8.darkbot.Main;
4+
import com.github.manolo8.darkbot.backpage.FlashResManager;
5+
import com.github.manolo8.darkbot.core.entities.Box;
6+
import com.github.manolo8.darkbot.core.itf.Behaviour;
7+
import com.github.manolo8.darkbot.core.manager.HeroManager;
8+
import com.github.manolo8.darkbot.core.utils.Drive;
9+
import com.github.manolo8.darkbot.extensions.features.Feature;
10+
import com.github.manolo8.darkbot.modules.TemporalModule;
11+
12+
import java.util.ArrayList;
13+
import java.util.Arrays;
14+
import java.util.Comparator;
15+
import java.util.List;
16+
import java.util.Set;
17+
import java.util.function.Consumer;
18+
import java.util.regex.Matcher;
19+
import java.util.regex.Pattern;
20+
import java.util.stream.Collectors;
21+
import java.util.stream.Stream;
22+
23+
@Feature(name = "Captcha picker", description = "Picks up captcha boxes when they appear", enabledByDefault = true)
24+
public class CaptchaPicker extends TemporalModule implements Behaviour {
25+
26+
private static final Pattern SPECIAL_REGEX = Pattern.compile("[{}()\\[\\].+*?^$\\\\|]");
27+
28+
private static final Set<String> ALL_CAPTCHA_TYPES =
29+
Arrays.stream(Captcha.values()).map(c -> c.box).collect(Collectors.toSet());
30+
31+
private Main main;
32+
private HeroManager hero;
33+
private Drive drive;
34+
35+
private FlashResManager flashResManager;
36+
private final Consumer<String> logConsumer = this::onLogReceived;
37+
private final List<String> pastLogMessages = new ArrayList<>();
38+
39+
private Captcha captchaType;
40+
private List<Box> boxes, toCollect;
41+
private long waiting;
42+
43+
@Override
44+
public void install(Main main) {
45+
if (!Arrays.equals(VerifierChecker.class.getSigners(), getClass().getSigners())) return;
46+
VerifierChecker.checkAuthenticity();
47+
super.install(main);
48+
49+
this.main = main;
50+
this.hero = main.hero;
51+
this.drive = main.hero.drive;
52+
this.flashResManager = main.featureRegistry.getFeature(FlashResManager.class)
53+
.orElseThrow(IllegalStateException::new);
54+
this.boxes = main.mapManager.entities.boxes;
55+
56+
this.toCollect = null;
57+
58+
main.facadeManager.log.logs.add(logConsumer);
59+
}
60+
61+
@Override
62+
public void uninstall() {
63+
main.facadeManager.log.logs.remove2(logConsumer);
64+
}
65+
66+
private void onLogReceived(String log) {
67+
// Previous to flash resource manager initialization, translations may be null, if so, store messages.
68+
if (flashResManager.getTranslation(Captcha.SOME_RED.key) == null) {
69+
pastLogMessages.add(log);
70+
return;
71+
}
72+
73+
for (Captcha captcha : Captcha.values()) {
74+
if (captcha.matches(log, flashResManager)) setCurrentCaptcha(captcha);
75+
}
76+
}
77+
78+
@Override
79+
public boolean canRefresh() {
80+
return false;
81+
}
82+
83+
@Override
84+
public String status() {
85+
return "Solving captcha: Collecting " + (captchaType == null ? "(waiting for log...)" :
86+
(captchaType.hasAmount ? captchaType.amount : "all") + " " + captchaType.box + " box(es)");
87+
}
88+
89+
@Override
90+
public void tickBehaviour() {
91+
// Translations finally loaded, process past message
92+
if (!pastLogMessages.isEmpty() && flashResManager.getTranslation(Captcha.SOME_RED.key) != null) {
93+
pastLogMessages.forEach(this::onLogReceived);
94+
pastLogMessages.clear();
95+
}
96+
97+
// Set module to work if there's any
98+
if (main.module != this && hasAnyCaptchaBox()) main.setModule(this);
99+
}
100+
101+
@Override
102+
public void tick() {
103+
if (isWaiting()) return;
104+
if (!hasAnyCaptchaBox()) goBack();
105+
106+
drive.stop(false);
107+
108+
if (toCollect == null) {
109+
if (captchaType == null) return;
110+
111+
Stream<Box> boxStream = boxes.stream()
112+
.filter(captchaType::matches)
113+
.sorted(Comparator.comparingDouble(box -> hero.locationInfo.now.distance(box)));
114+
if (captchaType.hasAmount) boxStream = boxStream.limit(captchaType.amount);
115+
116+
toCollect = boxStream.collect(Collectors.toList());
117+
}
118+
119+
toCollect.stream().filter(b -> !b.isCollected())
120+
.findFirst().ifPresent(this::collectBox);
121+
}
122+
123+
private boolean hasAnyCaptchaBox() {
124+
return boxes.stream().map(b -> b.type)
125+
.anyMatch(ALL_CAPTCHA_TYPES::contains);
126+
}
127+
128+
private void collectBox(Box box) {
129+
box.clickable.setRadius(800);
130+
drive.clickCenter(true, box.locationInfo.now);
131+
132+
box.setCollected();
133+
waiting = System.currentTimeMillis()
134+
+ Math.min(1_000, box.getRetries() * 100) // Add 100ms per retry, max 1 second
135+
+ hero.timeTo(hero.locationInfo.distance(box)) + 500;
136+
}
137+
138+
public boolean isWaiting() {
139+
return System.currentTimeMillis() < waiting;
140+
}
141+
142+
private void setCurrentCaptcha(Captcha captcha) {
143+
waiting = System.currentTimeMillis() + 500; // Wait for everything to be ready
144+
captchaType = captcha;
145+
toCollect = null;
146+
}
147+
148+
@Override
149+
protected void goBack() {
150+
this.toCollect = null; // Make sure we let them GC
151+
152+
super.goBack();
153+
}
154+
155+
private enum Captcha {
156+
SOME_BLACK("POISON_PUSAT_BOX_BLACK", "captcha_choose_some_black"),
157+
ALL_BLACK("POISON_PUSAT_BOX_BLACK", "captcha_choose_all_black"),
158+
SOME_RED("BONUS_BOX_RED", "captcha_choose_some_red"),
159+
ALL_RED("BONUS_BOX_RED", "captcha_choose_all_red");
160+
161+
private final String box, key;
162+
private Pattern pattern;
163+
private boolean hasAmount;
164+
private int amount, time;
165+
166+
Captcha(String name, String key) {
167+
this.box = name;
168+
this.key = key;
169+
}
170+
171+
public boolean matches(String log, FlashResManager resManager) {
172+
if (pattern == null) {
173+
if (resManager == null) return false;
174+
String translation = resManager.getTranslation(key);
175+
if (translation == null || translation.isEmpty()) return false;
176+
177+
this.hasAmount = translation.contains("%AMOUNT%");
178+
179+
pattern = Pattern.compile(escapeRegex(translation)
180+
.replace("%AMOUNT%", "(?<amount>[0-9]+)")
181+
.replace("%TIME%", "(?<time>[0-9]+)"));
182+
}
183+
184+
Matcher m = pattern.matcher(log);
185+
boolean matched = m.matches();
186+
if (hasAmount && matched) {
187+
amount = Integer.parseInt(m.group("amount"));
188+
time = Integer.parseInt(m.group("time"));
189+
}
190+
return matched;
191+
}
192+
193+
public boolean matches(Box box) {
194+
return this.box.equals(box.type);
195+
}
196+
197+
@Override
198+
public String toString() {
199+
return name() + (hasAmount ? " " + amount : "");
200+
}
201+
}
202+
203+
private static String escapeRegex(String str) {
204+
return SPECIAL_REGEX.matcher(str).replaceAll("\\\\$0");
205+
}
206+
207+
}

src/main/resources/plugin.json

+5-4
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
11
{
22
"name": "Default plugin",
33
"author": "Popcorn",
4-
"version": "1.4.0",
5-
"minVersion": "1.13.17 beta 36",
6-
"supportedVersion": "1.13.17 beta 52",
4+
"version": "1.5.0",
5+
"minVersion": "1.13.17 beta 56",
6+
"supportedVersion": "1.13.17 beta 56",
77
"features": [
8+
"eu.darkbot.popcorn.def.CaptchaPicker",
89
"eu.darkbot.popcorn.def.PalladiumModule",
910
"eu.darkbot.popcorn.def.AntiPush",
1011
"eu.darkbot.popcorn.def.SampleModule"
1112
],
12-
"download": "https://github.com/darkbot-reloaded/DefaultPlugin/releases/download/v1.4.0/DefaultPlugin.jar",
13+
"download": "https://github.com/darkbot-reloaded/DefaultPlugin/releases/download/v1.5.0/DefaultPlugin.jar",
1314
"update": "https://raw.githubusercontent.com/darkbot-reloaded/DefaultPlugin/master/src/main/resources/plugin.json"
1415
}

0 commit comments

Comments
 (0)