Skip to content

Commit 0f412fb

Browse files
authored
feat: add Discord webhook & centre point logic; refactor: remove unused modules & fix KInput makefile (#57)
**NOTE: Pulling these changes will update your DLL files, you will manually have to compile them again if you did so already!** - Created a `DiscordNotification` class to send yourself pings upon certain scripting events. - This sends a post request to the WebHook URL stated in the `secrets.properties` file (gitignored). - Added click closest to centre logic in the `ColourContours` class to prevent selecting an arbitrary first ChromaObj by detection. - The closest object to the centre is now the default logic for the `PointSelector` actions utility. - The `AccountManager`, `.chromascape` directory and `CVTemplates.sh` have been removed due to not being used and support not being planned. - Several changes have been made to the demo scripts including using `Minimap.getXP` in the `DemoAgilityScript`, and better conformity to professional code style, namely for magic numbers and removal of redundant constructors. - KInput's makefile has been changed to remove redundant references to `MinHook`. - Added `sendFunctionKey()` in `VirtualKeyboardUtils` and reduced code duplication in `Kinput.java`. Misc JavaDoc corrections have been made across the board.
1 parent c662806 commit 0f412fb

File tree

30 files changed

+323
-667
lines changed

30 files changed

+323
-667
lines changed

.gitignore

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,8 +62,8 @@ Thumbs.db
6262
output/*
6363
!output/.gitkeep
6464

65-
# chromascape runtime cache
66-
.chromascape/
65+
# chromascape secrets for individual developers
66+
secrets.properties
6767

6868
# custom user scripts
6969
/src/main/java/com/chromascape/scripts/*/

CVTemplates.sh

Lines changed: 0 additions & 72 deletions
This file was deleted.

config/checkstyle/checkstyle-suppressions.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,5 @@
1212
<suppress files=".*WindMouse\.java" checks=".*"/>
1313
<suppress files=".*TemplateMatching\.java" checks="AvoidStarImport"/>
1414
<suppress files=".*ScreenManager\.java" checks="LocalVariableName"/>
15+
<suppress files=".*ColourContours\.java" checks="AvoidStarImport"/>
1516
</suppressions>
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
package com.chromascape.api;
2+
3+
import java.io.FileInputStream;
4+
import java.io.IOException;
5+
import java.io.InputStream;
6+
import java.io.OutputStream;
7+
import java.net.HttpURLConnection;
8+
import java.net.URL;
9+
import java.nio.charset.StandardCharsets;
10+
import java.util.Properties;
11+
import org.slf4j.Logger;
12+
import org.slf4j.LoggerFactory;
13+
14+
/**
15+
* Provides functionality to send logs as notifications to yourself via Discord.
16+
*
17+
* <ul>
18+
* <li>Loads the {@code secrets.properties} file in the root directory.
19+
* <li>Saves the specified WebHook URL.
20+
* <li>Sends a POST req to the endpoint with the user's desired notification.
21+
* </ul>
22+
*
23+
* <p>This is extremely useful if you aren't actively babysitting your bot or in the case of
24+
* reaching a specified XP/GP goal. It's my personal advice to the reader for you to inform yourself
25+
* upon catastrophic failure, promptly.
26+
*/
27+
public class DiscordNotification {
28+
29+
private static final Logger logger = LoggerFactory.getLogger(DiscordNotification.class);
30+
private static String webhookUrl;
31+
32+
static {
33+
try (InputStream input = new FileInputStream("secrets.properties")) {
34+
Properties prop = new Properties();
35+
prop.load(input);
36+
webhookUrl = prop.getProperty("discord.webhook.url");
37+
} catch (IOException ex) {
38+
logger.info("Could not find secrets.properties in the project root.");
39+
}
40+
}
41+
42+
/**
43+
* Sends a user specified message to a Discord WebHook endpoint. Sets up a post request and
44+
* expects a 204 response code for success.
45+
*
46+
* @param message User specified String to send to the endpoint.
47+
*/
48+
public static void send(String message) {
49+
if (webhookUrl == null || webhookUrl.isEmpty()) {
50+
return;
51+
}
52+
53+
String sanitizedMessage = message.replace("\"", "\\\"").replace("\n", "\\n");
54+
String jsonPayload = "{\"content\": \"" + sanitizedMessage + "\"}";
55+
56+
try {
57+
URL url = new URL(webhookUrl);
58+
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
59+
conn.setDoOutput(true);
60+
conn.setRequestMethod("POST");
61+
conn.setRequestProperty("Content-Type", "application/json");
62+
conn.setRequestProperty("User-Agent", "Java-Discord-Webhook");
63+
64+
try (OutputStream os = conn.getOutputStream()) {
65+
os.write(jsonPayload.getBytes(StandardCharsets.UTF_8));
66+
}
67+
68+
// 204 means Success (No Content)
69+
if (conn.getResponseCode() != 204) {
70+
logger.error("Failed to send. Response code: {}", conn.getResponseCode());
71+
}
72+
73+
conn.disconnect();
74+
} catch (Exception e) {
75+
logger.error("Error sending Discord notification: {}", e.getMessage());
76+
}
77+
}
78+
}

src/main/java/com/chromascape/base/BaseScript.java

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package com.chromascape.base;
22

33
import com.chromascape.controller.Controller;
4-
import com.chromascape.utils.core.runtime.HotkeyListener;
54
import com.chromascape.utils.core.runtime.ScriptStoppedException;
65
import com.chromascape.utils.core.state.BotState;
76
import com.chromascape.utils.core.state.StateManager;
@@ -13,38 +12,35 @@
1312
/**
1413
* Abstract base class representing a generic automation script with lifecycle management.
1514
*
16-
* <p>Provides a timed execution framework where the script runs cycles until a specified duration
17-
* elapses or the script is stopped externally.
15+
* <p>Provides a timed execution framework where the script runs cycles until the script is stopped
16+
* externally.
1817
*
19-
* <p>Manages the underlying Controller instance and logging. Subclasses should override {@link
20-
* #cycle()} to define the script's main logic.
18+
* <p>Manages the underlying Controller instance. Subclasses should override {@link #cycle()} to
19+
* define the script's main logic.
2120
*/
2221
public abstract class BaseScript {
2322
private final Controller controller;
2423
private static final Logger logger = LogManager.getLogger(BaseScript.class);
25-
private final HotkeyListener hotkeyListener;
2624
private volatile boolean running = true;
2725
private Thread scriptThread;
2826

2927
/** Constructs a BaseScript. */
3028
public BaseScript() {
3129
controller = new Controller();
32-
hotkeyListener = new HotkeyListener(this);
3330
}
3431

3532
/**
3633
* Runs the script lifecycle.
3734
*
3835
* <p>Initializes the controller, logs start and stop events, then continuously invokes the {@link
39-
* #cycle()} method until the specified duration elapses or the script is stopped. Checks for
40-
* thread interruption and stops gracefully if detected.
36+
* #cycle()} method until the script is stopped. Checks for thread interruption and stops
37+
* gracefully if detected.
4138
*
4239
* <p>This method blocks until completion.
4340
*/
4441
public final void run() {
4542
scriptThread = Thread.currentThread();
4643
controller.init();
47-
hotkeyListener.start();
4844
StatisticsManager.reset();
4945

5046
try {
@@ -61,7 +57,7 @@ public final void run() {
6157
break;
6258
} catch (Exception e) {
6359
StateManager.setState(BotState.ERROR);
64-
logger.error("Exception in cycle: {}", e.getMessage());
60+
logger.error("Exception in cycle: {}, {}", e.getMessage(), e.getStackTrace());
6561
break;
6662
}
6763
}
@@ -84,7 +80,6 @@ public void stop() {
8480
}
8581
logger.info("Stop requested");
8682
running = false;
87-
hotkeyListener.stop();
8883

8984
// Interrupt the script thread instead of throwing exception
9085
if (scriptThread != null) {

0 commit comments

Comments
 (0)