Skip to content

Commit c9ec181

Browse files
Merge branch 'darkbot-reloaded:master' into master
2 parents cce1c89 + f73a179 commit c9ec181

File tree

10 files changed

+280
-10
lines changed

10 files changed

+280
-10
lines changed

api/src/main/java/eu/darkbot/api/extensions/PluginInfo.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,4 +60,9 @@ public interface PluginInfo extends IssueHandler {
6060
*/
6161
URL getDownloadURL();
6262

63+
/**
64+
* @return An array of all the defined feature ids
65+
*/
66+
String[] getFeatureIds();
67+
6368
}
Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
package eu.darkbot.api.game.entities;
2+
3+
import eu.darkbot.api.config.types.BoxInfo;
4+
import eu.darkbot.api.config.types.NpcInfo;
5+
import eu.darkbot.api.game.other.Location;
6+
7+
/**
8+
* Fake entities help keeping virtual entities on the map even when they go out of visibility range.
9+
* It should be used to assist or predict the positions of these entities for active module.
10+
* Use cases: keeping mine locations to avoid pathing by them
11+
* keeping box locations so the bot remembers going back for them
12+
*/
13+
public interface FakeEntity extends Entity {
14+
static boolean isFakeEntity(Entity entity) {
15+
return entity instanceof FakeEntity;
16+
}
17+
18+
/**
19+
* Set timeout lifetime of a fake object in ms
20+
* @param keepAlive How long to keep the entity alive for in ms
21+
*/
22+
void setTimeout(long keepAlive);
23+
24+
/**
25+
* @param location Set the location of the fake entity
26+
*/
27+
void setLocation(Location location);
28+
29+
/**
30+
* Set the minimum distance to hero for the entity to be automatically removed
31+
* @param removeDistance if hero comes any closer than the distance, entity is removed
32+
*/
33+
void setRemoveDistance(long removeDistance);
34+
35+
/**
36+
* Is remove fake entity after attempt select it
37+
* @param remove true to remove if user attempts selection, false to keep it
38+
*/
39+
void setRemoveOnSelect(boolean remove);
40+
41+
/**
42+
* Fake box can be used to lure collector module
43+
*/
44+
interface FakeBox extends Box, FakeEntity {
45+
}
46+
47+
/**
48+
* Fake mine is an obstacle that avoided by the path builder
49+
*/
50+
interface FakeMine extends Mine, FakeEntity {
51+
}
52+
53+
/**
54+
* Fake ship can be used for players or pets
55+
*/
56+
interface FakeShip extends Ship, FakeEntity {
57+
}
58+
59+
/**
60+
* Fake Npc can be used to lure loot module
61+
*/
62+
interface FakeNpc extends FakeShip, Npc {
63+
}
64+
65+
interface Builder {
66+
Builder keepAlive(Long keepAlive);
67+
Builder location(Location location);
68+
Builder removeDistance(Long removeDistance);
69+
Builder removeOnSelect(boolean remove);
70+
71+
FakeEntity.FakeMine mine(int typeId);
72+
default FakeEntity.FakeMine mine(Mine.Type type) {
73+
return mine(type.ordinal());
74+
}
75+
76+
FakeEntity.FakeNpc npc(NpcInfo npcInfo);
77+
FakeEntity.FakeNpc npc(String npcName);
78+
79+
FakeEntity.FakeBox box(BoxInfo box);
80+
FakeEntity.FakeBox box(String boxName);
81+
82+
abstract class Impl implements Builder {
83+
private Long keepAlive;
84+
private Location location;
85+
private Long removeDistance;
86+
private boolean removeOnSelect = true;
87+
88+
@Override
89+
public Builder keepAlive(Long keepAlive) {
90+
this.keepAlive = keepAlive;
91+
return this;
92+
}
93+
94+
@Override
95+
public Builder location(Location location) {
96+
this.location = location;
97+
return this;
98+
}
99+
100+
@Override
101+
public Builder removeDistance(Long removeDistance) {
102+
this.removeDistance = removeDistance;
103+
return this;
104+
}
105+
106+
@Override
107+
public Builder removeOnSelect(boolean removeOnSelect) {
108+
this.removeOnSelect = removeOnSelect;
109+
return this;
110+
}
111+
112+
protected <T extends FakeEntity> T apply(T entity) {
113+
if (keepAlive != null) entity.setTimeout(keepAlive);
114+
if (location != null) entity.setLocation(location);
115+
if (removeDistance != null) entity.setRemoveDistance(removeDistance);
116+
entity.setRemoveOnSelect(removeOnSelect);
117+
return entity;
118+
}
119+
}
120+
}
121+
}

api/src/main/java/eu/darkbot/api/managers/ConfigAPI.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,11 @@ default Set<String> getChildren(ConfigSetting<?> root, String path) {
176176
*/
177177
List<String> getConfigProfiles();
178178

179+
/**
180+
* @return the currently running profile in the bot
181+
*/
182+
String getCurrentProfile();
183+
179184
/**
180185
* Sets the current running profile.
181186
* Note there are no guarantees about it changing immediately, and may change on the next bot tick.

api/src/main/java/eu/darkbot/api/managers/EntitiesAPI.java

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import eu.darkbot.api.game.entities.BattleStation;
77
import eu.darkbot.api.game.entities.Box;
88
import eu.darkbot.api.game.entities.Entity;
9+
import eu.darkbot.api.game.entities.FakeEntity;
910
import eu.darkbot.api.game.entities.Mine;
1011
import eu.darkbot.api.game.entities.Mist;
1112
import eu.darkbot.api.game.entities.Npc;
@@ -19,6 +20,7 @@
1920
import eu.darkbot.api.game.entities.StaticEntity;
2021
import eu.darkbot.api.game.entities.Station;
2122
import eu.darkbot.api.game.other.Obstacle;
23+
import org.jetbrains.annotations.ApiStatus;
2224
import org.jetbrains.annotations.UnmodifiableView;
2325

2426
import java.util.Collection;
@@ -159,11 +161,17 @@ public interface EntitiesAPI extends API.Singleton {
159161
* <p>
160162
* For performance reasons it is not advised to use this method unless necessary.
161163
*
162-
* @return A new collection with ALL of the entities provided by all the methods in this API, including unknown.
164+
* @return A new collection with ALL the entities provided by all the methods in this API, including unknown.
163165
*/
164166
@UnmodifiableView
165167
Collection<? extends Entity> getAll();
166168

169+
/**
170+
* @return a builder to create fake entities
171+
*/
172+
@ApiStatus.AvailableSince("0.9.6")
173+
FakeEntity.Builder fakeEntityBuilder();
174+
167175
/**
168176
* Base entity event triggered whenever any entity is added or removed.
169177
* To listen only for creation or removal, use the more specific events:

api/src/main/java/eu/darkbot/api/managers/GameResourcesAPI.java

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,17 @@
11
package eu.darkbot.api.managers;
22

33
import eu.darkbot.api.API;
4+
import org.jetbrains.annotations.ApiStatus;
45
import org.jetbrains.annotations.NotNull;
56
import org.jetbrains.annotations.Nullable;
67

78
import java.util.Locale;
89
import java.util.Optional;
10+
import java.util.regex.Matcher;
911

1012
/**
1113
* Provides access to in-game resources, like translation keys.
14+
* TODO: provide a way to search text-to-key
1215
*/
1316
public interface GameResourcesAPI extends API.Singleton {
1417

@@ -23,5 +26,45 @@ public interface GameResourcesAPI extends API.Singleton {
2326
*/
2427
Optional<String> findTranslation(@NotNull String key);
2528

26-
// TODO: provide a way to search text-to-key
29+
/**
30+
* Retrieves a TranslationMatcher for the specified translation key with replacements.
31+
*
32+
* @param key the translation key to search for
33+
* @param replacements optional strings to replace within the translation
34+
* @return an Optional containing the TranslationMatcher if the key is found, or Optional.empty() otherwise
35+
*/
36+
@ApiStatus.AvailableSince("0.9.6")
37+
Optional<TranslationMatcher> getTranslationMatcher(@NotNull String key, String... replacements);
38+
39+
interface TranslationMatcher {
40+
/**
41+
* Returns the locale used for the translation.
42+
*
43+
* @return the locale
44+
*/
45+
Locale getLanguage();
46+
47+
/**
48+
* Attempts to match the log with the translation.
49+
*
50+
* @param log the log string to search in
51+
* @return true if the translation key was found, false otherwise
52+
*/
53+
boolean find(String log);
54+
55+
/**
56+
* Returns the extracted group of text at the specified index.
57+
*
58+
* @param group the index of the group to retrieve starting from 1 - (0 is a whole text)
59+
* @return the extracted group of text, or null if not found
60+
*/
61+
@Nullable String get(int group);
62+
63+
/**
64+
* Returns the underlying matcher used to search for the translation key.
65+
*
66+
* @return the underlying matcher
67+
*/
68+
Matcher getMatcher();
69+
}
2770
}

api/src/main/java/eu/darkbot/api/managers/SeassonPassAPI.java

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -107,9 +107,12 @@ default QuestStatus getSeassonPassQuestStatus() {
107107
@AllArgsConstructor
108108
enum QuestStatus {
109109
UNKNOWN(-1),
110-
COMPLETED(0),
111-
GOLD_LOCKED(2),
112-
NOT_COMPLETED(3);
110+
INCOMPLETE(0),
111+
INCOMPLETE_UNLOCKED(1),
112+
INCOMPLETE_LOCKED(2),
113+
COMPLETED(3),
114+
COMPLETED_UNLOCKED(4),
115+
COMPLETED_LOCKED(5);
113116

114117
private final int value;
115118

build.gradle.kts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ dependencies {
2121
api(project(":darkbot-shared"))
2222
}
2323

24-
val apiVersion = "0.9.5"
24+
val apiVersion = "0.9.8"
2525

2626
allprojects {
2727
group = "eu.darkbot"
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
package eu.darkbot.impl.utils;
2+
3+
import eu.darkbot.api.managers.GameResourcesAPI;
4+
import lombok.Getter;
5+
import org.jetbrains.annotations.Nullable;
6+
7+
import java.util.Locale;
8+
import java.util.Objects;
9+
import java.util.regex.Matcher;
10+
import java.util.regex.Pattern;
11+
12+
public class TranslationMatcherImpl implements GameResourcesAPI.TranslationMatcher {
13+
private static final Pattern ESCAPE_SPECIAL_CHARS = Pattern.compile("[{}()\\[\\].+*?^$\\\\|]");
14+
private static final Pattern REPLACE_UNUSED = Pattern.compile("%.*?%");
15+
16+
@Getter
17+
private final Matcher matcher;
18+
private final int amount;
19+
20+
@Getter
21+
private final Locale language;
22+
23+
public TranslationMatcherImpl(Locale language, String translation, String... replacements) {
24+
this.language = Objects.requireNonNull(language);
25+
26+
String s = ESCAPE_SPECIAL_CHARS.matcher(translation).replaceAll("\\\\$0");
27+
int amount = 0;
28+
for (String replacement : replacements) {
29+
s = s.replace(replacement, "(?<n" + ++amount + ">.*)");
30+
}
31+
32+
this.matcher = Pattern.compile(REPLACE_UNUSED.matcher(s).replaceAll("(.*)")).matcher("");
33+
this.amount = amount;
34+
}
35+
36+
@Override
37+
public boolean find(String log) {
38+
matcher.reset(log);
39+
return matcher.find();
40+
}
41+
42+
@Override
43+
public @Nullable String get(int group) {
44+
if (group < 0 || group > amount) throw new IndexOutOfBoundsException("Index out of bounds");
45+
if (group == 0) return matcher.group();
46+
return matcher.group("n" + group);
47+
}
48+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
package eu.darkbot.impl;
2+
3+
import eu.darkbot.api.managers.GameResourcesAPI;
4+
import eu.darkbot.impl.utils.TranslationMatcherImpl;
5+
import org.jetbrains.annotations.VisibleForTesting;
6+
import org.junit.jupiter.api.Assertions;
7+
import org.junit.jupiter.api.Test;
8+
9+
import java.util.Locale;
10+
11+
@VisibleForTesting
12+
class TranslationMatcherTest {
13+
14+
@Test
15+
void patternTest() {
16+
String log = "%CLAN% is now in control of the %STATION% Battle Station on the %MAP% map!" +
17+
" This Battle Station's Defelctor is being activated.";
18+
19+
String clan = "#497 18623 WHATEVER CLAN &.73!@#$!$^)#@$*@% ";
20+
String station = "REALLY WEIRD s.,][][1\3@$^@i0gfua/sXSD!@#% Station ";
21+
String map = "I s th ..XX+T@_$TT%_C@#_P{}#$P}{{}{{][] 2-3 a map?";
22+
23+
GameResourcesAPI.TranslationMatcher translationMatcher = // 1, 2, 3
24+
new TranslationMatcherImpl(Locale.ENGLISH, log, "%MAP%", "%CLAN%", "%STATION%");
25+
26+
String logToProcess = log.replace("%CLAN%", clan)
27+
.replace("%STATION%", station)
28+
.replace("%MAP%", map);
29+
30+
Assertions.assertTrue(translationMatcher.find(logToProcess));
31+
32+
Assertions.assertEquals(map, translationMatcher.get(1));
33+
Assertions.assertEquals(clan, translationMatcher.get(2));
34+
Assertions.assertEquals(station, translationMatcher.get(3));
35+
}
36+
}

shared/src/main/java/eu/darkbot/shared/utils/SafetyFinder.java

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -85,13 +85,14 @@ public enum Escaping {
8585
ENEMY, SIGHT, REPAIR, REFRESH, WAITING, NONE;
8686
boolean canUse(SafetyInfo safety) {
8787
if (safety.getType() == SafetyInfo.Type.CBS) {
88-
BattleStation.Hull cbs = ((BattleStation.Hull) safety.getEntity().orElse(null));
89-
if (cbs == null) return false;
90-
// Ignore enemy CBS, and if set to ALLY only, ignore empty meteorites (hull = 0)
91-
if (cbs.getEntityInfo().isEnemy() || (cbs.getHullId() == 0 && safety.getCbsMode() == SafetyInfo.CbsMode.ALLY)) return false;
88+
return safety.getEntity()
89+
.map(c -> c instanceof BattleStation.Hull ? (BattleStation.Hull) c : null)
90+
.map(cbs -> !(cbs.getEntityInfo().isEnemy() || (cbs.getHullId() == 0 && safety.getCbsMode() == SafetyInfo.CbsMode.ALLY)))
91+
.orElse(false);
9292
}
9393
return safety.getRunMode().ordinal() <= this.ordinal();
9494
}
95+
9596
boolean shouldJump(SafetyInfo safety) {
9697
SafetyInfo.JumpMode jm = safety.getJumpMode();
9798
if (safety.getType() != SafetyInfo.Type.PORTAL || jm == null) return false;

0 commit comments

Comments
 (0)