Skip to content

Commit

Permalink
improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
kr45732 committed Jun 27, 2024
1 parent 0c91a63 commit e567c79
Show file tree
Hide file tree
Showing 9 changed files with 80 additions and 63 deletions.
80 changes: 33 additions & 47 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,66 +16,52 @@ This is the source code for the Skyblock Plus Discord bot. A full list of comman

## Self Hosting
### Preface
You may need basic Discord, Gradle, Java, and Postgres knowledge to set up and maintain the bot. There are hardcoded constants that you will need to replace, databases you will need to create, and more. Note that I did not design the bot with the intention of others self-hosting in mind, so the process is not simple nor straightforward.
You may need basic Discord, Gradle, Java, and Postgres knowledge to set up and maintain the bot. There are hardcoded constants that you will need to replace, databases you will need to create, and more. Note that I did not design the bot with the intention of others self-hosting it, so the process isn't very straightforward.

### Prerequisites
Some of these prerequisites aren't necessary required but having all of them will make setting up bot without modification much easier.
- A Discord Bot (created using the [Discord Developers Portal](https://discord.com/developers/applications); you can find tons of tutorials on creating a bot online)
- Postgres database (two would be ideal as using one would require you to modify the code; or maybe you can set both database URLs to the same one and see what happens)
- Self-hosted [rust-query-api](https://github.com/kr45732/rust-query-api) (this is required for price calculations as it is used for lowest bin, average bin, average auction, querying the auction house, etc; also used for auction flipper)
- Self-hosted [haste](https://github.com/kr45732/hste) (I know my haste implementation is wacky, so I would suggest replace it with your own (which will require some code modification) or you can try to self-host mine)
- Hosting my haste steps (good luck!):
- Clone my wacky [hastebin](https://github.com/kr45732/hste)
- Get a [fauna database]([hste](https://github.com/kr45732/hste))
- Set FAUNA_ADMIN_KEY environment variable (might be called secret)
- Set FAUNA_DB_DOMAIN environment variable (might be called endpoint)
- Set KEY environment variable to your choosing and set "HASTE_KEY" in DevSettings.properties for the bot to the same value
- GitHub [personal token](https://github.com/settings/tokens) (give it the repo scope)
- This is used to automatically update the [skyblock-plus-data](https://github.com/kr45732/skyblock-plus-data) repo, which you should clone and have your own. This is most definitely required and will require additional set up later
- This is also used to authenticate the GitHub raw endpoints (though I'm not sure if that's even necessary)
- Some place soft to bang your head against; a wall is fine too, I won't judge
- A Discord Bot (created using the [Discord Developers Portal](https://discord.com/developers/applications))
- 2 Postgres databases (using one might be possible but may require code modifications)
- Self-hosted [rust-query-api](https://github.com/kr45732/rust-query-api) (used in lowest bin, average bin, average auction, querying the auction house, auction flipper, etc)
- Self-hosted [hastebin](https://github.com/kr45732/hste) (my haste implementation is wacky, so I would suggest replace it with your own (which will require some code modification) otherwise self-hosting steps are below)
- Clone [hste](https://github.com/kr45732/hste)
- Obtain a [fauna database]([hste](https://github.com/kr45732/hste))
- Set FAUNA_ADMIN_KEY environment variable (might be called secret)
- Set FAUNA_DB_DOMAIN environment variable (might be called endpoint)
- Set KEY environment variable to your choosing
- GitHub [personal token](https://github.com/settings/tokens) with the repo scope
- This is used to automatically update the [skyblock-plus-data](https://github.com/kr45732/skyblock-plus-data) repo, which you should clone your own of

### Steps
If you made it this far, good job & good luck! If you are stuck or encounter a problem, create an issue and I will try to help you in 3-5 business days!
If you are stuck or encounter a problem in the steps below, create an issue and I will try to help you in 3-5 business days!
1. Clone this repository
2. Rename ExampleDevSettings.properties to DevSettings.properties and move it to the project root (or use environment variables) and follow the comments in there and the guide below to fill it out
2. Rename ExampleDevSettings.properties to DevSettings.properties and move it to the project root (or use environment variables) and follow the instructions there and below to fill it out:
- If you don't plan on using linked roles, you can probably leave CLIENT_SECRET blank (haven't tested)
- Feel free to set the API_USERNAME and API_PASSWORD to some gibberish. Just don't leave it blank because you don't want some random person to access the private endpoints (server settings, linked accounts, etc)
- Same thing as above with JACOB_KEY, you probably won't ever use that endpoint, but you don't want some random person to be able to POST data using it
- Make sure the AUCTION_API_KEY is the same as the ADMIN_API_KEY of your self-hosted rust-query-api
- If you set up my wacky hastebin, then HASTE_KEY should be the same as the KEY set on there
- AUCTION_FLIPPER_WEBHOOK isn't required but who does not want a very ~~not~~ accurate auction flipper
- BOT_STATUS_WEBHOOK might be required but for your sake just make it
3. Databases (yikes!). So the database situation is not ideal. For very not so smart reasons, there are two databases instead of a single one. You might be able to combine it into one without needing to modify code by setting both databases to the same URL and praying (haven't tested). Refer setup-resources for the schemas and database dumps. You will also need the [pg_trgm module](https://www.postgresql.org/docs/current/pgtrgm.html).
- Server settings schema should be automatically generated by Spring (thank god for that because the schema is horrendous). If you have to manually create the schema, use the database dump in setup-resources.
- Linked accounts schema is quite nice actually
- Leaderboard schemas (another yikes!). I designed leaderboards in a very interesting (and inefficient) way. There are 4 leaderboards: "all_lb", "ironman_lb", "stranded_lb", and "selected_lb". The first 3 are self-explanatory. The last one stores players' last played profile and is a cache used for automatic nickname updates, automatic roles claim, etc. All four of these have identical schemas.
- Cache schemas are also not that bad. There is `guild` (used for tracking guilds for "/serverlb"), `json_cache` (used to cache json responses from the Hypixel API), and `json_storage` (persistent cache)
4. Emojis (yikes again!). So right now there are ~90 emoji servers. If you want to use the emojis, you will have to make your own servers and emojis.
- Delete all emojis from "IdToEmojiMappings.json"
- Create around 90 servers with the name "Skyblock Plus - Emoji Server xx" where xx is the server number starting at 1 and invite the bot to it
- Copy the glint_images from [skyblock-plus-data](https://github.com/kr45732/skyblock-plus-data) to "src/main/java/com/skyblockplus/json/glint_images/"
- Optional step & might break in the future: copy the CIT folder from the latest furfsky reborn to "src/main/java/com/skyblockplus/json/cit"
- Feel free to set the API_USERNAME and API_PASSWORD to some gibberish, but don't leave it blank because you don't want anyone to be able to access the private endpoints (server settings, linked accounts, etc)
- Same thing as above with JACOB_KEY, you probably won't ever use that endpoint, but you don't want anyone to be able to POST data to it
- Ensure the AUCTION_API_KEY is the same as the ADMIN_API_KEY of your self-hosted rust-query-api
- If you are self-hosted [hste](https://github.com/kr45732/hste), then HASTE_KEY should be the same as the KEY set on there
3. Databases: At the moment, there are two databases instead of a single one. You might be able to combine it into one without needing to modify code by setting both databases to the same URL, but I haven't tested that. Refer to [setup-resources](https://github.com/kr45732/skyblock-plus/tree/master/setup-resources) for schemas and database dumps. You will also need to install the [pg_trgm module](https://www.postgresql.org/docs/current/pgtrgm.html) on your databases.
- Server settings: should be automatically generated by Spring on first startup
- Linked accounts
- Leaderboards: there are 4 leaderboards (all_lb, ironman_lb, stranded_lb, and selected_lb) with identical schemas. The first 3 are self-explanatory. The last one is a cache that stores players' last played profile for automatic nickname updates, automatic roles claim, etc
- Caching: there is `guild` (used for tracking guilds for "/serverlb"), `json_cache` (used to cache json responses from the Hypixel API), and `json_storage` (persistent cache)
4. Emojis: At the moment, there are around 90 custom emoji servers. To create your own:
- Make "IdToEmojiMappings.json" an empty JSON object
- Create and add the bot to 90 servers with the name "Skyblock Plus - Emoji Server xx" (xx is the server number starting at 1)
- Copy all glint_images from [skyblock-plus-data](https://github.com/kr45732/skyblock-plus-data) to "src/main/java/com/skyblockplus/json/glint_images/"
- Optionally (may not work in the future), copy the CIT folder from the latest FurfSky Reborn to "src/main/java/com/skyblockplus/json/cit"
- Set `DEV = true` and run the bot
- Using the evaluate command run `ev com.skyblockplus.utils.EmojiUpdater.processAll()`
- Using the evaluate command run `ev com.skyblockplus.utils.EmojiUpdater.runEmojis(json)` where json is a haste link to the output JSON you got from processAll() above
- Paste the JSON output of runEmojis into the "IdToEmojiMappings.json"
5. Hardcoded constants you will need to change:
- You will need to update all emoji maps in the Constants.json from [skyblock-plus-data](https://github.com/kr45732/skyblock-plus-data/blob/main/Constants.json) with new emojis
- When I say "update guild" below, the guild ID you are setting it to is **your** primary server
- In `com.skyblockplus.utils.utils.Utils` update:
- botLogChannel guild and channel assignment on L206 and L228 (this is where command uses are logged to)
- networthBugReportChannel guild and channel assignment on L372
- Create 2 messages in a channel to be used for the scuffed event system. Update the assignment of messageId in `com.skyblockplus.features.event.EventHandler` on L46. Update the guild and channel on L56 and L57
- Update guild in L203 of `com.skyblockplus.features.listeners.AutomaticGuild` and channel in L205 (this is the channel where the BOT_STATUS_WEBHOOK is in)
- Update guild in L1180 of `com.skyblockplus.features.listeners.AutomaticGuild`
- Update errorLogChannel in L39, L63, and L94 of `com.skyblockplus.utils.utils.Utils.errorLogChannel` to a channel for error logs
- Update guild in L48 com.skyblockplus.features.listeners.AutomaticGuild
- You will need to update all emoji maps in the Constants.json from [skyblock-plus-data](https://github.com/kr45732/skyblock-plus-data/blob/main/Constants.json) with your own emojis
- Create 2 messages in a channel to be used for the scuffed event system. Update the assignment of messageId in `com.skyblockplus.features.event.EventHandler` on L46. Update the channel on L57
- More will be added as I find/remember them
6. Everything is finally set up (I hope) and you're ready to run the bot (yay!)
- Use gradle or gradelw to build: `gradle build`
- It will create a jar: "build/libs/SkyblockPlus-0.0.1.jar"
- Run the jar using Java 17. I suggest using systemctl to keep it running in the background (see sample in setup-resources/skyblock-plus.service)
6. Running the bot:
- Build using gradle or gradlew: `gradle build` to create a jar at "build/libs/SkyblockPlus-0.0.1.jar"
- Run the jar using Java 17 (example using systemctl to run it in the background [here](https://github.com/kr45732/skyblock-plus/blob/master/setup-resources/skyblock-plus.service))

## Bug reports
Feel free to make an issue or report the bug using the support server linked below.
Expand Down
15 changes: 15 additions & 0 deletions setup-resources/ExampleDevSettings.properties
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,21 @@ CLIENT_SECRET =
# keep to false unless you are working on the bot (good luck!)
DEV = false

# guild used for logging, bug reports, etc
PRIMARY_GUILD_ID =

# text channel in PRIMARY_GUILD where command uses are logged to
LOG_CHANNEL_ID =

# text channel in PRIMARY_GUILD where errors in commands and features are logged to
ERROR_LOG_CHANNEL_ID =

# text channel in PRIMARY_GUILD where bot status notifications are sent (same channel as the BOT_STATUS_WEBHOOK)
BOT_STATUS_CHANNEL_ID =

# text channel in PRIMARY_GUILD where networth bug reports are logged to
NETWORTH_BUG_REPORT_CHANNEL_ID =

# used for prefix commands (mainly dev commands)
# requires message content intent to be enabled to use prefix
# if you don't have the message content intent & want to use prefix commands, then just mention the bot instead of a prefix
Expand Down
8 changes: 4 additions & 4 deletions setup-resources/schemas.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
If you're really lazy or completely stuck you might be able to just copy and paste SQL from the dumps, but I haven't tested it so no guarantee it will work. The "server-settings-linked-accounts-dump.sql" has the SQL for server settings schema and linked accounts.
If you're really lazy or completely stuck you might be able to just copy and paste SQL from the database dumps. I haven't tested this so no guarantee it will work. [server-settings-linked-accounts-dump.sql](https://github.com/kr45732/skyblock-plus/blob/master/setup-resources/server-settings-linked-accounts-dump.sql) has the SQL for server settings and linked accounts. [leaderboard-cache-dump.sql](https://github.com/kr45732/skyblock-plus/blob/master/setup-resources/leaderboard-cache-dump.sql) has the SQL for leaderboards and caching.


# Server settings schemas
If you need this, then you might be cooked. Try using the database dump and pray
Should be automatically created on first startup by Spring. If you need to manually create it, try using [server-settings-linked-accounts-dump.sql](https://github.com/kr45732/skyblock-plus/blob/master/setup-resources/server-settings-linked-accounts-dump.sql).

# Linked accounts schema
```postgresql
Expand All @@ -21,8 +21,8 @@ Indexes:
"linked_account_uuid_key" UNIQUE CONSTRAINT, btree (uuid)
```

# Leaderboard schemas
Remember all four have the same schema, just different table names
# Leaderboards schema
All four leaderboards (all_lb, ironman_lb, stranded_lb, and selected_lb) have the same schema, just different table names.
```postgresql
Table "public.all_lb"
Column | Type | Collation | Nullable | Default
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/com/skyblockplus/Main.java
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ public void onCommandException(CommandEvent event, Command command, Throwable th
!IS_DEV
? database.getAllServerSettings().stream().collect(Collectors.toMap(ServerSettingsModel::getServerId, Function.identity()))
: Stream
.of("796790757947867156", "782154976243089429", "869217817680044042")
.of(PRIMARY_GUILD_ID, "782154976243089429", "869217817680044042")
.collect(Collectors.toMap(Function.identity(), e -> database.getServerSettingsModel(e), (e1, e2) -> e1));
log.info("Loaded all server settings");

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ public static void updateEvents() {
}

jda
.getGuildById("796790757947867156")
.getGuildById(PRIMARY_GUILD_ID)
.getTextChannelById("959829695686381658")
.retrieveMessageById(messageId)
.queue(m -> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -200,9 +200,9 @@ public class AutomaticGuild {
public AutomaticGuild(GenericGuildEvent event) {
guildId = event.getGuild().getId();

if (!IS_DEV && guildId.equals("796790757947867156")) {
if (!IS_DEV && guildId.equals(PRIMARY_GUILD_ID)) {
try {
((GuildMessageChannel) jda.getGuildChannelById("957658797155975208")).getHistory()
((GuildMessageChannel) jda.getGuildChannelById(BOT_STATUS_CHANNEL_ID)).getHistory()
.retrievePast(1)
.queue(m -> {
long seconds = Duration.between(m.get(0).getTimeCreated().toInstant(), Instant.now()).toSeconds();
Expand Down Expand Up @@ -1177,7 +1177,7 @@ public void onButtonInteraction(ButtonInteractionEvent event) {
} else if (event.getComponentId().equals("mayor_special_button")) {
event.replyEmbeds(MayorSlashCommand.getSpecialMayors().build()).setEphemeral(true).queue();
} else if (event.getComponentId().equals("mayor_current_election_button")) {
Message msg = guildMap.get("796790757947867156").lastMayorElectionOpenMessage;
Message msg = guildMap.get(PRIMARY_GUILD_ID).lastMayorElectionOpenMessage;
event
.reply(
(msg != null
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import static com.skyblockplus.features.listeners.MainListener.guildMap;
import static com.skyblockplus.utils.Constants.mayorNameToEmoji;
import static com.skyblockplus.utils.utils.StringUtils.getRelativeTimestamp;
import static com.skyblockplus.utils.utils.Utils.PRIMARY_GUILD_ID;
import static com.skyblockplus.utils.utils.Utils.defaultEmbed;

import com.skyblockplus.features.listeners.AutomaticGuild;
Expand All @@ -45,7 +46,7 @@ public MayorSlashCommand() {
}

public static MessageEditBuilder getMayor() {
AutomaticGuild automaticGuild = guildMap.get("796790757947867156");
AutomaticGuild automaticGuild = guildMap.get(PRIMARY_GUILD_ID);

List<Button> buttons = new ArrayList<>(automaticGuild.lastMayorElectedMessage.getButtons());
if (automaticGuild.lastMayorElectionOpenMessage != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ public class GlobalExceptionHandler implements Thread.UncaughtExceptionHandler {
public void uncaughtException(Thread t, Throwable e) {
try {
if (errorLogChannel == null) {
errorLogChannel = jda.getGuildById("796790757947867156").getTextChannelById("864156114060705814");
errorLogChannel = jda.getGuildById(PRIMARY_GUILD_ID).getTextChannelById(ERROR_LOG_CHANNEL_ID);
}

String stackTrace = getStackTrace(e);
Expand All @@ -60,7 +60,7 @@ public void uncaughtException(Thread t, Throwable e) {

public String uncaughtException(SlashCommandEvent event, Throwable e) {
if (errorLogChannel == null) {
errorLogChannel = jda.getGuildById("796790757947867156").getTextChannelById("864156114060705814");
errorLogChannel = jda.getGuildById(PRIMARY_GUILD_ID).getTextChannelById(ERROR_LOG_CHANNEL_ID);
}

String description = "**Guild:** " + event.getGuild().getName() + " (" + event.getGuild().getId() + ")";
Expand Down Expand Up @@ -91,7 +91,7 @@ public String uncaughtException(SlashCommandEvent event, Throwable e) {

public void uncaughtException(CommandEvent event, Command command, Throwable e) {
if (errorLogChannel == null) {
errorLogChannel = jda.getGuildById("796790757947867156").getTextChannelById("864156114060705814");
errorLogChannel = jda.getGuildById(PRIMARY_GUILD_ID).getTextChannelById(ERROR_LOG_CHANNEL_ID);
}

String stackTrace = getStackTrace(e);
Expand Down
Loading

0 comments on commit e567c79

Please sign in to comment.