Compare commits
79 Commits
f9c13e5ada
...
main
Author | SHA1 | Date | |
---|---|---|---|
330c132e3b | |||
492034865b | |||
f2be21ef89 | |||
e08dc0ef17 | |||
2762f6e29f | |||
1612334e00 | |||
f3075be1cf | |||
83adf33910 | |||
853bf3141f | |||
e99ca2f302 | |||
9a8c0599ed | |||
9467119249 | |||
b84ae5e2c1 | |||
7cb5b563d7 | |||
9e60fa8c37 | |||
5914242316 | |||
18446f1dea | |||
d81879cec2 | |||
5dc8e46080 | |||
1aac53deb8 | |||
0a5d94fd8c | |||
5f0de3f326 | |||
ff29cc1c53 | |||
ce3507db62 | |||
0739ac9376 | |||
765ab7f8d1 | |||
624af4f5fd | |||
25a1d92e52 | |||
e523385e5c | |||
9e4a91dd46 | |||
d9ae8e729a | |||
664eafa4cc | |||
1f810ca533 | |||
64776ad8cf | |||
e8c2d1495d | |||
8c41ad39c3 | |||
f3c0f7d728 | |||
217781b4f0 | |||
b67befd3eb | |||
d1111732f3 | |||
3df664614f | |||
faf823ec37 | |||
ef355ecd48 | |||
3968a0e0c8 | |||
550542ae50 | |||
4c1e01b3c4 | |||
3459e1f733 | |||
7ad3b82fb4 | |||
492248f01b | |||
4ec70b3601 | |||
e40d9eb14a | |||
60a50c3bfb | |||
2dcbced91e | |||
981de3d2e5 | |||
eddf87df4d | |||
6f24616c81 | |||
0f54fbf07e | |||
1e72ecdf53 | |||
e5644462b9 | |||
1b89c4440b | |||
cf968f198a | |||
b68cb0b219 | |||
0c1cc63b9b | |||
fbc9238e97 | |||
d52431ffb5 | |||
f5d9aefc0f | |||
7678a44945 | |||
bbd329a4cf | |||
5685dd5fb7 | |||
fbcd0d1bb9 | |||
0588dd1c45 | |||
c433e25fba | |||
c8a4507253 | |||
7bf7c8c8dc | |||
df3ff5f1c3 | |||
fabc504e06 | |||
ea405ba6d5 | |||
d1f08e3dfa | |||
70b0b86a23 |
@@ -1,59 +0,0 @@
|
||||
name: Build and Deploy
|
||||
on: [push]
|
||||
|
||||
jobs:
|
||||
Deploy Web:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
container:
|
||||
image: catthehacker/ubuntu:act-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Use Nodejs
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 18
|
||||
- run: npm install
|
||||
working-directory: ./web
|
||||
- run: npm run build
|
||||
working-directory: ./web
|
||||
|
||||
- uses: docker/setup-qemu-action@v2
|
||||
- uses: docker/setup-buildx-action@v2
|
||||
|
||||
- uses: docker/login-action@v2
|
||||
with:
|
||||
registry: gitea.xeovalyte.dev
|
||||
username: ${{ secrets.DOCKER_USERNAME }}
|
||||
password: ${{ secrets.DOCKER_PASSWORD }}
|
||||
|
||||
- run: docker buildx build -t gitea.xeovalyte.dev/xeovalyte/polarcraft-web:latest --load --platform=linux/amd64 ./web
|
||||
- run: docker push gitea.xeovalyte.dev/xeovalyte/polarcraft-web:latest
|
||||
|
||||
Deploy Discord Bot:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
container:
|
||||
image: catthehacker/ubuntu:act-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Use Nodejs
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 18
|
||||
- run: npm install
|
||||
working-directory: ./discord-bot
|
||||
|
||||
- uses: docker/setup-qemu-action@v2
|
||||
- uses: docker/setup-buildx-action@v2
|
||||
|
||||
- uses: docker/login-action@v2
|
||||
with:
|
||||
registry: gitea.xeovalyte.dev
|
||||
username: ${{ secrets.DOCKER_USERNAME }}
|
||||
password: ${{ secrets.DOCKER_PASSWORD }}
|
||||
|
||||
- run: docker buildx build -t gitea.xeovalyte.dev/xeovalyte/polarcraft-discord:latest --load --platform=linux/amd64 ./discord-bot
|
||||
- run: docker push gitea.xeovalyte.dev/xeovalyte/polarcraft-discord:latest
|
55
.gitea/workflows/release-nighty.yaml
Normal file
55
.gitea/workflows/release-nighty.yaml
Normal file
@@ -0,0 +1,55 @@
|
||||
name: Build and Publish
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- 'dev'
|
||||
|
||||
jobs:
|
||||
Build and Publish Discord Bot:
|
||||
runs-on: ubuntu-latest
|
||||
container:
|
||||
image: catthehacker/ubuntu:act-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- uses: docker/login-action@v2
|
||||
with:
|
||||
registry: gitea.xeovalyte.dev
|
||||
username: ${{ gitea.actor }}
|
||||
password: ${{ secrets.DOCKER_PASSWORD }}
|
||||
|
||||
- uses: docker/build-push-action@master
|
||||
with:
|
||||
context: ./discordbot
|
||||
push: true
|
||||
tags: gitea.xeovalyte.dev/xeovalyte/polarcraft:nightly
|
||||
|
||||
|
||||
Build and Publish Minecraft Mod:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Set up JDK
|
||||
uses: actions/setup-java@v1
|
||||
with:
|
||||
java-version: 17
|
||||
|
||||
- name: Grant execute permission for gradlew
|
||||
working-directory: ./mod
|
||||
run: chmod +x gradlew
|
||||
|
||||
- name: Build with Gradle
|
||||
working-directory: ./mod
|
||||
run: ./gradlew build
|
||||
|
||||
- name: Upload Artifacts
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: polarcraft-mod.jar
|
||||
path: |
|
||||
mod/build/libs/*.jar
|
||||
!mod/build/libs/*-sources.jar
|
||||
!mod/build/libs/*-dev.jar
|
||||
|
||||
|
53
.gitea/workflows/release.yaml
Normal file
53
.gitea/workflows/release.yaml
Normal file
@@ -0,0 +1,53 @@
|
||||
name: Build and Publish
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- 'main'
|
||||
|
||||
jobs:
|
||||
Build and Publish Discord Bot:
|
||||
runs-on: ubuntu-latest
|
||||
container:
|
||||
image: catthehacker/ubuntu:act-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- uses: docker/login-action@v2
|
||||
with:
|
||||
registry: gitea.xeovalyte.dev
|
||||
username: ${{ gitea.actor }}
|
||||
password: ${{ secrets.DOCKER_PASSWORD }}
|
||||
|
||||
- uses: docker/build-push-action@master
|
||||
with:
|
||||
context: ./discordbot
|
||||
push: true
|
||||
tags: gitea.xeovalyte.dev/xeovalyte/polarcraft:latest
|
||||
|
||||
|
||||
Build and Publish Minecraft Mod:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Set up JDK
|
||||
uses: actions/setup-java@v1
|
||||
with:
|
||||
java-version: 17
|
||||
|
||||
- name: Grant execute permission for gradlew
|
||||
working-directory: ./mod
|
||||
run: chmod +x gradlew
|
||||
|
||||
- name: Build with Gradle
|
||||
working-directory: ./mod
|
||||
run: ./gradlew build
|
||||
|
||||
- name: Upload Artifacts
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: polarcraft-mod.jar
|
||||
path: |
|
||||
mod/build/libs/*.jar
|
||||
!mod/build/libs/*-sources.jar
|
||||
!mod/build/libs/*-dev.jar
|
BIN
assets/logo-zoomed-dev.png
Normal file
BIN
assets/logo-zoomed-dev.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 601 KiB |
@@ -1,11 +0,0 @@
|
||||
FROM node:18-alpine
|
||||
|
||||
WORKDIR /usr/src/app
|
||||
|
||||
COPY . .
|
||||
|
||||
RUN npm install
|
||||
|
||||
EXPOSE 3000
|
||||
|
||||
CMD [ "node", "index.js" ]
|
@@ -1,173 +0,0 @@
|
||||
const { SlashCommandBuilder } = require('discord.js');
|
||||
const { QueryType } = require('discord-player');
|
||||
|
||||
module.exports = {
|
||||
data: new SlashCommandBuilder()
|
||||
.setName('music')
|
||||
.setDescription('Play and configure music')
|
||||
.addSubcommand(subcommand => subcommand
|
||||
.setName('play')
|
||||
.setDescription('Play music')
|
||||
.addStringOption(option => option
|
||||
.setName('link-or-query')
|
||||
.setDescription('The song or link you want to play')
|
||||
.setRequired(true)))
|
||||
.addSubcommand(subcommand => subcommand
|
||||
.setName('skip')
|
||||
.setDescription('Skip current song'))
|
||||
.addSubcommand(subcommand => subcommand
|
||||
.setName('stop')
|
||||
.setDescription('Stop current queue'))
|
||||
.addSubcommand(subcommand => subcommand
|
||||
.setName('pause')
|
||||
.setDescription('Pause the current song'))
|
||||
.addSubcommand(subcommand => subcommand
|
||||
.setName('shuffle')
|
||||
.setDescription('Shuffle the queue'))
|
||||
.addSubcommand(subcommand => subcommand
|
||||
.setName('resume')
|
||||
.setDescription('Resume the current song'))
|
||||
.addSubcommand(subcommand => subcommand
|
||||
.setName('filter')
|
||||
.setDescription('Apply a filter')
|
||||
.addStringOption(option => option
|
||||
.setName('type')
|
||||
.setDescription('Type of filter')
|
||||
.setRequired(true)
|
||||
.addChoices(
|
||||
{ name: 'Bassboost', value: 'bassboost_low' },
|
||||
{ name: 'Nightcore', value: 'nightcore' },
|
||||
)))
|
||||
.addSubcommand(subcommand => subcommand
|
||||
.setName('volume')
|
||||
.setDescription('Set volume')
|
||||
.addNumberOption(option => option
|
||||
.setName('percentage')
|
||||
.setDescription('The percentage of the volume between 1 and 100')
|
||||
.setRequired(true))),
|
||||
|
||||
async execute({ interaction, createEmbed, client }) {
|
||||
if (!interaction.member.voice.channelId) return await interaction.reply({ embeds: [createEmbed.basic('You are not in a voice channel!')], ephemeral: true });
|
||||
if (interaction.guild.members.me.voice.channelId && interaction.member.voice.channelId !== interaction.guild.members.me.voice.channelId) {
|
||||
return await interaction.reply({ embeds: [createEmbed.basic('You are not in my voice channel!')], ephemeral: true });
|
||||
}
|
||||
|
||||
|
||||
if (interaction.options.getSubcommand() === 'play') {
|
||||
const query = interaction.options.getString('link-or-query');
|
||||
|
||||
const queue = client.player.createQueue(interaction.guild, {
|
||||
ytdlOptions: {
|
||||
filter: 'audioonly',
|
||||
highWaterMark: 1 << 30,
|
||||
dlChunkSize: 0,
|
||||
},
|
||||
metadata: {
|
||||
channel: interaction.channel,
|
||||
},
|
||||
});
|
||||
|
||||
// verify vc connection
|
||||
try {
|
||||
if (!queue.connection) await queue.connect(interaction.member.voice.channel);
|
||||
} catch {
|
||||
queue.destroy();
|
||||
return await interaction.reply({ embeds: [createEmbed.basic('Could not join your voice channel!')], ephemeral: true });
|
||||
}
|
||||
|
||||
await interaction.reply({ embeds: [createEmbed.basic('Searching...')], ephemeral: true });
|
||||
|
||||
const searchResult = await client.player.search(query, {
|
||||
requestedBy: interaction.user,
|
||||
searchEngine: QueryType.AUTO,
|
||||
});
|
||||
if (!searchResult || !searchResult.tracks[0]) return await interaction.editReply({ embeds: [createEmbed.basic(`Track or playlist **${query}** not found!`)], ephemeral: true });
|
||||
|
||||
searchResult.playlist ? queue.addTracks(searchResult.tracks) : queue.addTrack(searchResult.tracks[0]);
|
||||
if (!queue.playing) await queue.play();
|
||||
|
||||
if (!searchResult.playlist) await interaction.editReply({ embeds: [createEmbed.basic(`Adding track **${searchResult.tracks[0].title}**`)], ephemeral: false });
|
||||
else await interaction.editReply({ embeds: [createEmbed.basic(`Adding **${searchResult.playlist.tracks.length}** tracks from playlist **${searchResult.playlist.title}**`)], ephemeral: false });
|
||||
|
||||
} else if (interaction.options.getSubcommand() === 'skip') {
|
||||
|
||||
const queue = client.player.getQueue(interaction.guild);
|
||||
|
||||
if (!queue || !queue.playing) return await interaction.reply({ embeds: [createEmbed.basic('No music is being played')] });
|
||||
|
||||
const currentTrack = queue.nowPlaying();
|
||||
const success = queue.skip();
|
||||
|
||||
await interaction.reply({ embeds: [createEmbed.basic(success ? `Skipped **${currentTrack.title}**` : 'Something went wrong')] });
|
||||
} else if (interaction.options.getSubcommand() === 'volume') {
|
||||
const vol = interaction.options.getNumber('percentage');
|
||||
|
||||
const queue = client.player.getQueue(interaction.guild);
|
||||
|
||||
if (!queue || !queue.playing) return await interaction.reply({ embeds: [createEmbed.basic('No music is being played')] });
|
||||
|
||||
if (vol < 1 || vol > 100) return interaction.reply({ embeds: [createEmbed.basic('Volume must be between 1 and 100')] });
|
||||
|
||||
const success = queue.setVolume(vol);
|
||||
|
||||
await interaction.reply({ embeds: [createEmbed.basic(success ? `Volume set to **${vol}%**` : 'Something went wrong')] });
|
||||
} else if (interaction.options.getSubcommand() === 'stop') {
|
||||
|
||||
const queue = client.player.getQueue(interaction.guild);
|
||||
|
||||
if (!queue || !queue.playing) return await interaction.reply({ embeds: [createEmbed.basic('No music is being played')] });
|
||||
|
||||
queue.destroy();
|
||||
|
||||
await interaction.reply({ embeds: [createEmbed.basic('Stopped the player')] });
|
||||
} else if (interaction.options.getSubcommand() === 'pause') {
|
||||
|
||||
const queue = client.player.getQueue(interaction.guild);
|
||||
|
||||
if (!queue || !queue.playing) return await interaction.reply({ embeds: [createEmbed.basic('No music is being played')] });
|
||||
|
||||
queue.setPaused(true);
|
||||
|
||||
await interaction.reply({ embeds: [createEmbed.basic('Paused the player')] });
|
||||
} else if (interaction.options.getSubcommand() === 'resume') {
|
||||
|
||||
const queue = client.player.getQueue(interaction.guild);
|
||||
|
||||
if (!queue || !queue.playing) return await interaction.reply({ embeds: [createEmbed.basic('No music is being played')] });
|
||||
|
||||
queue.setPaused(false);
|
||||
|
||||
await interaction.reply({ embeds: [createEmbed.basic('Resumed the player')] });
|
||||
} else if (interaction.options.getSubcommand() === 'filter') {
|
||||
const filter = interaction.options.getString('type');
|
||||
|
||||
const queue = client.player.getQueue(interaction.guild);
|
||||
|
||||
if (!queue || !queue.playing) return await interaction.reply({ embeds: [createEmbed.basic('No music is being played')] });
|
||||
|
||||
if (filter === 'bassboost_low') {
|
||||
await queue.setFilters({
|
||||
bassboost_low: !queue.getFiltersEnabled().includes('bassboost_low'),
|
||||
normalizer2: !queue.getFiltersEnabled().includes('bassboost_low'),
|
||||
});
|
||||
}
|
||||
|
||||
if (filter === 'nightcore') {
|
||||
await queue.setFilters({
|
||||
nightcore: !queue.getFiltersEnabled().includes('nightcore'),
|
||||
});
|
||||
}
|
||||
|
||||
await interaction.reply({ embeds: [createEmbed.basic(queue.getFiltersEnabled().includes(filter) ? `Applied **${filter}** filter` : `Removed **${filter}** filter`)] });
|
||||
} else if (interaction.options.getSubcommand() === 'shuffle') {
|
||||
|
||||
const queue = client.player.getQueue(interaction.guild);
|
||||
|
||||
if (!queue || !queue.playing) return await interaction.reply({ embeds: [createEmbed.basic('No music is being played')] });
|
||||
|
||||
const success = queue.shuffle();
|
||||
|
||||
await interaction.reply({ embeds: [createEmbed.basic(success ? 'The queue has been shuffled' : 'Something went wrong')] });
|
||||
}
|
||||
},
|
||||
};
|
@@ -1,12 +0,0 @@
|
||||
const { SlashCommandBuilder } = require('discord.js');
|
||||
|
||||
module.exports = {
|
||||
data: new SlashCommandBuilder()
|
||||
.setName('ping')
|
||||
.setDescription('Replies with Pong!'),
|
||||
|
||||
async execute({ interaction, createEmbed, client }) {
|
||||
const reply = await interaction.reply({ embeds: [createEmbed.basic(`Websocket heartbeat: **${client.ws.ping}ms**\n Roundtrip latency: **Pinging...**`)], fetchReply: true, ephemeral: true });
|
||||
interaction.editReply({ embeds: [createEmbed.basic(`Websocket heartbeat: **${client.ws.ping}ms**\n Roundtrip latency: **${reply.createdTimestamp - interaction.createdTimestamp}ms**`)], emphemeral: true });
|
||||
},
|
||||
};
|
@@ -1,70 +0,0 @@
|
||||
const { SlashCommandBuilder, PermissionsBitField, ChannelType, ButtonStyle, ButtonBuilder, ActionRowBuilder } = require('discord.js');
|
||||
|
||||
module.exports = {
|
||||
data: new SlashCommandBuilder()
|
||||
.setName('ticket')
|
||||
.setDescription('Commands for managing a ticket')
|
||||
.addSubcommand(subcommand => subcommand
|
||||
.setName('create')
|
||||
.setDescription('Create a ticket with you and moderators'))
|
||||
.addSubcommand(subcommand => subcommand
|
||||
.setName('close')
|
||||
.setDescription('Close current ticket')),
|
||||
|
||||
async execute({ interaction, createEmbed }) {
|
||||
if (interaction.options.getSubcommand() === 'create') {
|
||||
await interaction.reply({ embeds: [createEmbed.basic('Creating ticket channel...')], fetchReply: true, ephemeral: true });
|
||||
|
||||
const ticketChannel = await interaction.member.guild.channels.create({
|
||||
name: `ticket-${interaction.user.username}`,
|
||||
type: ChannelType.GuildText,
|
||||
parent: process.env.TICKET_CATEGORY_ID,
|
||||
permissionOverwrites: [
|
||||
{
|
||||
id: interaction.guild.id,
|
||||
deny: [PermissionsBitField.Flags.ViewChannel],
|
||||
},
|
||||
{
|
||||
id: process.env.MODERATOR_ROLE_ID,
|
||||
allow: [PermissionsBitField.Flags.ViewChannel],
|
||||
},
|
||||
{
|
||||
id: interaction.user.id,
|
||||
allow: [PermissionsBitField.Flags.ViewChannel],
|
||||
},
|
||||
],
|
||||
|
||||
});
|
||||
|
||||
await ticketChannel.send({ embeds: [createEmbed.basic(`${interaction.user} created a ticket`)] });
|
||||
|
||||
interaction.editReply({ embeds: [createEmbed.basic(`${ticketChannel} has been created`)], emphemeral: true });
|
||||
|
||||
} else if (interaction.options.getSubcommand() === 'close') {
|
||||
|
||||
if (!interaction.channel.name.startsWith('ticket')) return interaction.reply({ embeds: [createEmbed.basic('You must execute this command inside a ticket channel')], emphemeral: true });
|
||||
|
||||
const cancelRow = new ActionRowBuilder()
|
||||
.addComponents(
|
||||
new ButtonBuilder()
|
||||
.setCustomId('cancel')
|
||||
.setLabel('Cancel')
|
||||
.setStyle(ButtonStyle.Danger),
|
||||
);
|
||||
|
||||
const closeMessage = await interaction.reply({ embeds: [createEmbed.basic('Closing ticket in 10 seconds...')], components: [cancelRow] });
|
||||
const collector = closeMessage.createMessageComponentCollector();
|
||||
|
||||
const timeout = setTimeout(() => {
|
||||
try {
|
||||
interaction.channel.delete();
|
||||
} catch {}
|
||||
}, 10000);
|
||||
|
||||
collector.on('collect', async () => {
|
||||
clearTimeout(timeout);
|
||||
await closeMessage.edit({ embeds: [createEmbed.basic('Ticket closing has been stopped')], components: [] });
|
||||
});
|
||||
}
|
||||
},
|
||||
};
|
@@ -1,17 +0,0 @@
|
||||
const { Events } = require('discord.js');
|
||||
|
||||
module.exports = {
|
||||
name: Events.MessageCreate,
|
||||
async execute({ log }, message) {
|
||||
|
||||
if (message.channelId === process.env.MINECRAFT_CHANNEL_ID && !message.author.bot) {
|
||||
await fetch(process.env.WEB_HOST + '/api/minecraft/message/chattominecraft', {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({
|
||||
content: message.content,
|
||||
discordId: message.author.id,
|
||||
}),
|
||||
});
|
||||
}
|
||||
},
|
||||
};
|
@@ -1,17 +0,0 @@
|
||||
const { Events, EmbedBuilder } = require('discord.js');
|
||||
|
||||
module.exports = {
|
||||
name: Events.GuildMemberAdd,
|
||||
async execute({ client, log }, member) {
|
||||
log.Info(`${member.user.username} has joined`);
|
||||
|
||||
const newMemberEmbed = new EmbedBuilder()
|
||||
.setTitle(`${member.user.username} has joined!`)
|
||||
.setDescription(`Welcome ${member} to the **Polarcraft** Discord server!`)
|
||||
.setColor(process.env.EMBED_COLOR)
|
||||
.setThumbnail(member.user.avatarURL());
|
||||
|
||||
const channel = await client.channels.cache.get(process.env.LOG_CHANNEL_ID);
|
||||
channel.send({ embeds: [newMemberEmbed] });
|
||||
},
|
||||
};
|
@@ -1,15 +0,0 @@
|
||||
const { Events, EmbedBuilder } = require('discord.js');
|
||||
|
||||
module.exports = {
|
||||
name: Events.GuildMemberRemove,
|
||||
async execute({ client, log }, member) {
|
||||
log.Info(`${member.user.username} has left`);
|
||||
|
||||
const newMemberEmbed = new EmbedBuilder()
|
||||
.setTitle(`${member.user.username} has left!`)
|
||||
.setColor(process.env.EMBED_COLOR);
|
||||
|
||||
const channel = await client.channels.cache.get(process.env.LOG_CHANNEL_ID);
|
||||
channel.send({ embeds: [newMemberEmbed] });
|
||||
},
|
||||
};
|
@@ -1,26 +0,0 @@
|
||||
const { Events } = require('discord.js');
|
||||
|
||||
module.exports = {
|
||||
name: Events.InteractionCreate,
|
||||
async execute({ log, createEmbed, client }, interaction) {
|
||||
|
||||
if (interaction.isChatInputCommand()) {
|
||||
const command = interaction.client.commands.get(interaction.commandName);
|
||||
|
||||
if (!command) {
|
||||
return log.Error(`No command matching ${interaction.commandName} was found`);
|
||||
} else {
|
||||
log.Info(`${interaction.user.username} executed command ${interaction.commandName}`);
|
||||
}
|
||||
|
||||
try {
|
||||
await command.execute({ interaction, log, createEmbed, client });
|
||||
} catch (error) {
|
||||
log.Error(error);
|
||||
|
||||
await interaction.reply({ content: 'There was an error while executing this command!', ephemeral: true });
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
};
|
@@ -1,11 +0,0 @@
|
||||
const { Events } = require('discord.js');
|
||||
|
||||
module.exports = {
|
||||
name: Events.ClientReady,
|
||||
once: true,
|
||||
execute({ client, log }) {
|
||||
log.Info(`Ready! Logged in as ${client.user.tag}`);
|
||||
|
||||
require('../functions/registerCommands.js').registerCommands(log);
|
||||
},
|
||||
};
|
@@ -1,12 +0,0 @@
|
||||
const { EmbedBuilder } = require('discord.js');
|
||||
const dotenv = require('dotenv');
|
||||
|
||||
dotenv.config();
|
||||
|
||||
const basic = (description) => {
|
||||
return new EmbedBuilder()
|
||||
.setColor(process.env.EMBED_COLOR)
|
||||
.setDescription(description);
|
||||
};
|
||||
|
||||
module.exports = { basic };
|
@@ -1,31 +0,0 @@
|
||||
const { EmbedBuilder } = require('discord.js');
|
||||
|
||||
const registerEvents = ({ client }) => {
|
||||
|
||||
client.player.on('trackStart', (queue, track) => {
|
||||
|
||||
const nowPlayingEmbed = new EmbedBuilder()
|
||||
.setTitle('Now Playing')
|
||||
.setColor(process.env.EMBED_COLOR)
|
||||
.setDescription(`[${track.title}](${track.url})`)
|
||||
.addFields(
|
||||
{ name: 'Requested By', value: `${track.requestedBy}`, inline: true },
|
||||
{ name: 'Duration', value: track.duration, inline: true },
|
||||
{ name: 'Queue', value: `${queue.tracks.length} song(s)`, inline: true },
|
||||
{ name: 'Author', value: track.author, inline: true },
|
||||
{ name: 'Source', value: track.source, inline: true },
|
||||
{ name: 'Volume', value: `${queue.options.initialVolume}%`, inline: true },
|
||||
{ name: 'Filters', value: queue.getFiltersEnabled().join('\n') || 'No filters active', inline: false },
|
||||
)
|
||||
.setThumbnail(track.thumbnail)
|
||||
.setTimestamp();
|
||||
|
||||
queue.metadata.channel.send({ embeds: [nowPlayingEmbed] });
|
||||
});
|
||||
|
||||
client.player.on('error', (queue, error) => {
|
||||
console.log(error);
|
||||
});
|
||||
};
|
||||
|
||||
module.exports = { registerEvents };
|
@@ -1,48 +0,0 @@
|
||||
const { REST, Routes } = require('discord.js');
|
||||
const fs = require('node:fs');
|
||||
const dotenv = require('dotenv');
|
||||
|
||||
dotenv.config();
|
||||
|
||||
const registerCommands = (log) => {
|
||||
const commands = [];
|
||||
// Grab all the command files from the commands directory you created earlier
|
||||
const commandFiles = fs.readdirSync('./commands').filter(file => file.endsWith('.js'));
|
||||
|
||||
// Grab the SlashCommandBuilder#toJSON() output of each command's data for deployment
|
||||
for (const file of commandFiles) {
|
||||
const command = require(`../commands/${file}`);
|
||||
commands.push(command.data.toJSON());
|
||||
}
|
||||
|
||||
// Construct and prepare an instance of the REST module
|
||||
const rest = new REST({ version: '10' }).setToken(process.env.DISCORD_TOKEN);
|
||||
|
||||
// and deploy your commands!
|
||||
(async () => {
|
||||
try {
|
||||
log.Info(`Started refreshing ${commands.length} application (/) commands.`);
|
||||
|
||||
// The put method is used to fully refresh all commands in the guild with the current set
|
||||
let data = null;
|
||||
if (process.env.GUILD_ID !== 'production') {
|
||||
data = await rest.put(
|
||||
Routes.applicationGuildCommands(process.env.CLIENT_ID, process.env.GUILD_ID),
|
||||
{ body: commands },
|
||||
);
|
||||
} else {
|
||||
data = await rest.put(
|
||||
Routes.applicationGuildCommands(process.env.CLIENT_ID),
|
||||
{ body: commands },
|
||||
);
|
||||
}
|
||||
|
||||
log.Info(`Successfully reloaded ${data.length} application (/) commands.`);
|
||||
} catch (error) {
|
||||
// And of course, make sure you catch and log any errors!
|
||||
log.Error(error);
|
||||
}
|
||||
})();
|
||||
};
|
||||
|
||||
module.exports = { registerCommands };
|
@@ -1,25 +0,0 @@
|
||||
{
|
||||
"type": "commonjs",
|
||||
"name": "discord-bot",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"lint": "eslint .",
|
||||
"lint-fix": "eslint . --fix"
|
||||
},
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"@discord-player/extractor": "^3.0.2",
|
||||
"@discordjs/opus": "^0.8.0",
|
||||
"chalk": "^4.1.2",
|
||||
"discord-player": "^5.3.2",
|
||||
"discord.js": "^14.7.1",
|
||||
"distube": "^4.0.4",
|
||||
"dotenv": "^16.0.3",
|
||||
"eslint": "^8.29.0",
|
||||
"express": "^4.18.2",
|
||||
"ytdl-core": "^4.11.4"
|
||||
}
|
||||
}
|
@@ -1,38 +0,0 @@
|
||||
const { WebhookClient, EmbedBuilder } = require('discord.js');
|
||||
const express = require('express');
|
||||
|
||||
const router = express.Router();
|
||||
const webhookClient = new WebhookClient({ url: process.env.MINECRAFT_WEBHOOK_URL });
|
||||
|
||||
router.post('/sendchatmessage', (req, res) => {
|
||||
const { content, username, avatarURL } = req.body;
|
||||
|
||||
if (!username || !content || !avatarURL) return res.status(400).send({ error: 'Content, username and avatar_url are required' });
|
||||
|
||||
webhookClient.send({
|
||||
content: content,
|
||||
username: username,
|
||||
avatarURL: avatarURL,
|
||||
});
|
||||
|
||||
res.send({ data: 'Test data' });
|
||||
});
|
||||
|
||||
router.post('/sendgamemessage', (req, res) => {
|
||||
const { content, avatarURL } = req.body;
|
||||
|
||||
if (!content || !avatarURL) return res.status(400).send({ error: 'Content, username and avatar_url are required' });
|
||||
|
||||
const messageEmbed = new EmbedBuilder()
|
||||
.setColor(process.env.EMBED_COLOR)
|
||||
.setAuthor({ name: content, iconURL: avatarURL });
|
||||
|
||||
webhookClient.send({
|
||||
embeds: [messageEmbed],
|
||||
username: 'Server',
|
||||
});
|
||||
|
||||
res.send({ data: 'Test data' });
|
||||
});
|
||||
|
||||
module.exports = router;
|
@@ -1,145 +0,0 @@
|
||||
const express = require('express');
|
||||
const index = require('../index');
|
||||
const { PermissionsBitField, ChannelType } = require('discord.js');
|
||||
|
||||
const router = express.Router();
|
||||
|
||||
router.post('/createchannels', async (req, res) => {
|
||||
const { name, discordId } = req.body;
|
||||
|
||||
if (!name || !discordId) return res.status(400).send({ error: 'Name en discordId zijn vereist' });
|
||||
|
||||
try {
|
||||
const guild = await index.client.guilds.fetch(process.env.GUILD_ID);
|
||||
|
||||
const category = await guild.channels.fetch(process.env.TEAM_CATEGORY_ID);
|
||||
|
||||
const member = await guild.members.fetch(discordId);
|
||||
|
||||
const textChannel = await guild.channels.create({
|
||||
name: name,
|
||||
type: ChannelType.GuildText,
|
||||
parent: category,
|
||||
permissionOverwrites: [
|
||||
{
|
||||
id: guild.id,
|
||||
deny: [PermissionsBitField.Flags.ViewChannel],
|
||||
},
|
||||
{
|
||||
id: member.id,
|
||||
allow: [PermissionsBitField.Flags.ViewChannel],
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
const voiceChannel = await guild.channels.create({
|
||||
name: name,
|
||||
type: ChannelType.GuildVoice,
|
||||
parent: category,
|
||||
permissionOverwrites: [
|
||||
{
|
||||
id: guild.id,
|
||||
deny: [PermissionsBitField.Flags.ViewChannel],
|
||||
},
|
||||
{
|
||||
id: member.id,
|
||||
allow: [PermissionsBitField.Flags.ViewChannel],
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
res.send({ textChannel, voiceChannel });
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
return res.status(500).send({ error: 'Error tijdens het maken van discord channels' });
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
router.post('/deletechannels', async (req, res) => {
|
||||
const { textChannelId, voiceChannelId } = req.body;
|
||||
|
||||
if (!textChannelId, !voiceChannelId) return res.status(400).send({ error: 'textChannelId en voiceChannelId zijn vereist' });
|
||||
|
||||
try {
|
||||
const guild = await index.client.guilds.fetch(process.env.GUILD_ID);
|
||||
|
||||
const textChannel = await guild.channels.fetch(textChannelId);
|
||||
const voiceChannel = await guild.channels.fetch(voiceChannelId);
|
||||
|
||||
await textChannel.delete();
|
||||
await voiceChannel.delete();
|
||||
|
||||
res.send({ status: 'success' });
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
return res.status(500).send({ error: 'Error tijdens het verwijderen van discord channels' });
|
||||
}
|
||||
});
|
||||
|
||||
router.post('/removeteammember', async (req, res) => {
|
||||
const { textChannelId, voiceChannelId, discordId } = req.body;
|
||||
|
||||
if (!textChannelId, !voiceChannelId, !discordId) return res.status(400).send({ error: 'textChannelId, voiceChannelId en discordId zijn vereist' });
|
||||
|
||||
try {
|
||||
const guild = await index.client.guilds.fetch(process.env.GUILD_ID);
|
||||
const member = await guild.members.fetch(discordId);
|
||||
|
||||
const textChannel = await guild.channels.fetch(textChannelId);
|
||||
const voiceChannel = await guild.channels.fetch(voiceChannelId);
|
||||
|
||||
await textChannel.permissionOverwrites.delete(member);
|
||||
await voiceChannel.permissionOverwrites.delete(member);
|
||||
|
||||
res.send({ status: 'success' });
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
return res.status(500).send({ error: 'Error tijdens het verwijderen van een team member' });
|
||||
}
|
||||
});
|
||||
|
||||
router.post('/addteammember', async (req, res) => {
|
||||
const { textChannelId, voiceChannelId, discordId } = req.body;
|
||||
|
||||
if (!textChannelId, !voiceChannelId, !discordId) return res.status(400).send({ error: 'textChannelId, voiceChannelId en discordId zijn vereist' });
|
||||
|
||||
try {
|
||||
const guild = await index.client.guilds.fetch(process.env.GUILD_ID);
|
||||
const member = await guild.members.fetch(discordId);
|
||||
|
||||
const textChannel = await guild.channels.fetch(textChannelId);
|
||||
const voiceChannel = await guild.channels.fetch(voiceChannelId);
|
||||
|
||||
await textChannel.permissionOverwrites.edit(member, { ViewChannel: true });
|
||||
await voiceChannel.permissionOverwrites.edit(member, { ViewChannel: true });
|
||||
|
||||
res.send({ status: 'success' });
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
return res.status(500).send({ error: 'Error tijdens het toevoegen van team member' });
|
||||
}
|
||||
});
|
||||
|
||||
router.post('/edit', async (req, res) => {
|
||||
const { textChannelId, voiceChannelId, name } = req.body;
|
||||
|
||||
if (!textChannelId, !voiceChannelId, !name) return res.status(400).send({ error: 'textChannelId, voiceChannelId en name zijn vereist' });
|
||||
|
||||
try {
|
||||
const guild = await index.client.guilds.fetch(process.env.GUILD_ID);
|
||||
|
||||
const textChannel = await guild.channels.fetch(textChannelId);
|
||||
const voiceChannel = await guild.channels.fetch(voiceChannelId);
|
||||
|
||||
await textChannel.edit({ name: name });
|
||||
await voiceChannel.edit({ name: name });
|
||||
|
||||
res.send({ status: 'success' });
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
return res.status(500).send({ error: 'Error tijds het veranderen van Discord channel naam' });
|
||||
}
|
||||
});
|
||||
|
||||
module.exports = router;
|
@@ -1,47 +0,0 @@
|
||||
const express = require('express');
|
||||
const index = require('../index');
|
||||
|
||||
const router = express.Router();
|
||||
|
||||
router.post('/changenickname', async (req, res) => {
|
||||
const { nickname, discordId } = req.body;
|
||||
|
||||
if (!nickname || !discordId) return res.status(400).send({ error: 'Nickname en discordId zijn vereist' });
|
||||
|
||||
const nick = nickname.length > 32 ? nickname.slice(0, 32) : nickname;
|
||||
|
||||
try {
|
||||
const guild = await index.client.guilds.fetch(process.env.GUILD_ID);
|
||||
|
||||
const member = await guild.members.fetch(discordId);
|
||||
|
||||
await member.edit({ nick: nick });
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
return res.status(500).send({ error: 'Error tijds het veranderen van de nickname' });
|
||||
}
|
||||
|
||||
res.send({ status: 'success' });
|
||||
});
|
||||
|
||||
router.post('/ban', async (req, res) => {
|
||||
const { discordId, reason } = req.body;
|
||||
|
||||
if (!reason || !discordId) return res.status(400).send({ error: 'Reason en discordId zijn vereist' });
|
||||
|
||||
try {
|
||||
const guild = await index.client.guilds.fetch(process.env.GUILD_ID);
|
||||
|
||||
const member = await guild.members.fetch(discordId);
|
||||
|
||||
await member.ban({ deleteMessageSeconds: 24 * 3600, reason: reason });
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
return res.status(500).send({ error: 'Error tijds het bannen van gebruiker' });
|
||||
}
|
||||
|
||||
res.send({ status: 'success' });
|
||||
});
|
||||
|
||||
|
||||
module.exports = router;
|
@@ -5,7 +5,8 @@
|
||||
"es6": true
|
||||
},
|
||||
"parserOptions": {
|
||||
"ecmaVersion": 2021
|
||||
"ecmaVersion": 2021,
|
||||
"sourceType": "module"
|
||||
},
|
||||
"rules": {
|
||||
"arrow-spacing": ["warn", { "before": true, "after": true }],
|
@@ -1,2 +1,3 @@
|
||||
.env
|
||||
node_modules
|
||||
database.sqlite
|
13
discordbot/Dockerfile
Normal file
13
discordbot/Dockerfile
Normal file
@@ -0,0 +1,13 @@
|
||||
FROM node:18-alpine
|
||||
|
||||
WORKDIR /usr/src/app
|
||||
|
||||
COPY . .
|
||||
|
||||
RUN apk update && apk upgrade
|
||||
RUN apk add --no-cache sqlite
|
||||
|
||||
RUN npm install
|
||||
RUN npm install --save sqlite3
|
||||
|
||||
CMD ["node", "index.js"]
|
29
discordbot/commands/adduser.js
Normal file
29
discordbot/commands/adduser.js
Normal file
@@ -0,0 +1,29 @@
|
||||
const { SlashCommandBuilder } = require('discord.js');
|
||||
const { simpleEmbed } = require('../functions/embeds.js');
|
||||
const { Users } = require('../functions/models.js');
|
||||
|
||||
module.exports = {
|
||||
data: new SlashCommandBuilder()
|
||||
.setName('adduser')
|
||||
.setDescription('Add a user to the system')
|
||||
.addUserOption(option => option
|
||||
.setName('user')
|
||||
.setDescription('The user to add')),
|
||||
|
||||
async execute(interaction) {
|
||||
const user = interaction.options.getUser('user') ? interaction.options.getUser('user') : interaction.user;
|
||||
|
||||
try {
|
||||
await Users.create({
|
||||
id: user.id,
|
||||
rawUsername: user.globalName,
|
||||
});
|
||||
|
||||
await interaction.reply({ embeds: [simpleEmbed('Added user to the system')], ephemeral: true });
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
|
||||
await interaction.reply({ embeds: [simpleEmbed('There was an error while adding the user')], ephemeral: true });
|
||||
}
|
||||
},
|
||||
};
|
49
discordbot/commands/ban.js
Normal file
49
discordbot/commands/ban.js
Normal file
@@ -0,0 +1,49 @@
|
||||
const { SlashCommandBuilder } = require('discord.js');
|
||||
const { simpleEmbed } = require('../functions/embeds.js');
|
||||
const { Users } = require('../functions/models.js');
|
||||
const { client } = require('../index.js');
|
||||
|
||||
module.exports = {
|
||||
data: new SlashCommandBuilder()
|
||||
.setName('ban')
|
||||
.setDescription('Ban a user')
|
||||
.setDefaultMemberPermissions(0)
|
||||
.addUserOption(option => option
|
||||
.setName('user')
|
||||
.setDescription('The user to ban')
|
||||
.setRequired(true))
|
||||
.addStringOption(option => option
|
||||
.setName('reason')
|
||||
.setDescription('Why ban the user')
|
||||
.setRequired(true)),
|
||||
|
||||
async execute(interaction) {
|
||||
const member = interaction.options.getMember('user');
|
||||
const reason = interaction.options.getString('reason');
|
||||
|
||||
try {
|
||||
await member.ban({ reason });
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
return await interaction.reply({ embeds: [simpleEmbed(`Error while banning ${member}`)], ephemeral: true });
|
||||
}
|
||||
|
||||
const userInstance = await Users.findOne({ where: { id: member.id } });
|
||||
if (!userInstance) return await interaction.reply({ embeds: [simpleEmbed('Error while getting user information')], ephemeral: true });
|
||||
|
||||
if (userInstance.minecraftUuid) {
|
||||
await fetch(process.env.MINECRAFT_HOST + '/console', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'content-type': 'text/plain',
|
||||
},
|
||||
body: `ban ${userInstance.minecraftUuid} ${reason}`,
|
||||
});
|
||||
}
|
||||
|
||||
const channel = client.channels.cache.get(process.env.MOD_LOG_CHANNEL_ID);
|
||||
await channel.send({ embeds: [simpleEmbed(`${interaction.user} banned ${member}, reason: **${reason}**`)] });
|
||||
|
||||
await interaction.reply({ embeds: [simpleEmbed(`Banned ${member}`)], ephemeral: true });
|
||||
},
|
||||
};
|
@@ -1,4 +1,5 @@
|
||||
const { SlashCommandBuilder, PermissionFlagsBits } = require('discord.js');
|
||||
const { simpleEmbed } = require('../functions/embeds.js');
|
||||
|
||||
module.exports = {
|
||||
data: new SlashCommandBuilder()
|
||||
@@ -10,15 +11,13 @@ module.exports = {
|
||||
.setDescription('The amount of messages to clear')
|
||||
.setRequired(true)),
|
||||
|
||||
async execute({ interaction, createEmbed, client }) {
|
||||
async execute(interaction) {
|
||||
const amount = interaction.options.getNumber('amount');
|
||||
|
||||
if (amount < 1 || amount > 100) return await interaction.reply({ embeds: [createEmbed.basic('The amount must be between 1-100')] });
|
||||
if (amount < 1 || amount > 100) return await interaction.reply({ embeds: [simpleEmbed('The amount must be between 1-100')] });
|
||||
|
||||
const channel = client.channels.cache.get(interaction.channelId);
|
||||
interaction.channel.bulkDelete(amount, true);
|
||||
|
||||
channel.bulkDelete(amount);
|
||||
|
||||
await interaction.reply({ embeds: [createEmbed.basic(`Cleared **${amount}** messages`)], ephemeral: true });
|
||||
await interaction.reply({ embeds: [simpleEmbed(`Cleared **${amount}** messages`)], ephemeral: true });
|
||||
},
|
||||
};
|
11
discordbot/commands/dennis.js
Normal file
11
discordbot/commands/dennis.js
Normal file
@@ -0,0 +1,11 @@
|
||||
const { SlashCommandBuilder } = require('discord.js');
|
||||
const { simpleEmbed } = require('../functions/embeds.js');
|
||||
|
||||
module.exports = {
|
||||
data: new SlashCommandBuilder()
|
||||
.setName('dennis')
|
||||
.setDescription('Dennis.'),
|
||||
async execute(interaction) {
|
||||
await interaction.reply({ embeds: [simpleEmbed('Dennis is koel')], ephemeral: true });
|
||||
},
|
||||
};
|
62
discordbot/commands/message.js
Normal file
62
discordbot/commands/message.js
Normal file
@@ -0,0 +1,62 @@
|
||||
const { SlashCommandBuilder, EmbedBuilder } = require('discord.js');
|
||||
|
||||
module.exports = {
|
||||
data: new SlashCommandBuilder()
|
||||
.setName('message')
|
||||
.setDescription('Send a default game message')
|
||||
.setDefaultMemberPermissions(0)
|
||||
.addStringOption(option => option
|
||||
.setName('option')
|
||||
.setDescription('Which message to send')
|
||||
.setRequired(true)
|
||||
.addChoices(
|
||||
{ name: 'welcome', value: 'welcome' },
|
||||
{ name: 'moderators', value: 'moderators' },
|
||||
)),
|
||||
|
||||
async execute(interaction) {
|
||||
const option = interaction.options.getString('option');
|
||||
|
||||
if (option === 'welcome') {
|
||||
const embed0 = new EmbedBuilder()
|
||||
.setTitle('Rules')
|
||||
.setColor(process.env.EMBED_COLOR)
|
||||
.setDescription('De regels zijn dit seizoen niet concreet. Zorg ervoor dat de ervaring voor iedereen leuk is en blijft. Een grapje maken mag, maar verpest niet iemand anders zijn ervaring.');
|
||||
|
||||
const embed1 = new EmbedBuilder()
|
||||
.setTitle('Commands')
|
||||
.setColor(process.env.EMBED_COLOR)
|
||||
.addFields(
|
||||
{ name: 'Whitelist', value: 'Join de Minecraft server en vul de gekregen code in door de `/whitelist` commando uit te voeren in discord. Door het commando `/removewhitelist` uit te voeren verwijder je jezelf van de whitelist.\n\u200B' },
|
||||
{ name: 'Team', value: '**Team maken:** Voer het commando `/team create` uit in discord. Kleur kan je uitzoeken op deze website: [HTML Color Codes](https://htmlcolorcodes.com/color-picker/)\n\n**Inviten:** Voer het commando `/team invite <user>` uit in discord. Deze persoon zal een invite krijgen en deze accepteren of weigeren.\n\n**Leave:** Voer het commando `/team leave` uit om het team te verlaten.\n\u200B' },
|
||||
{ name: 'Username', value: 'Door het commando `/setusername <type>` uit te voeren kan gekozen worden tussen de Minecraft of Discord username. Deze username zal op Discord en Minecraft weergegeven worden.\n\u200B' },
|
||||
{ name: 'Minecraft', value: 'Door het commando `/map <hide/show>` uit te voeren in Minecraft kan gekozen om zichtbaar te zijn op [deze map](https://polarcraft.xeovalyte.com/) of niet' },
|
||||
);
|
||||
|
||||
const embed2 = new EmbedBuilder()
|
||||
.setTitle('Polarcraft Modpack')
|
||||
.setColor(process.env.EMBED_COLOR)
|
||||
.addFields({ name: 'Installeer Instructies', value: `
|
||||
**1.** Installeer de [Modrinth launcher](https://modrinth.com/app) en log in\n
|
||||
**2.** Klik op het zoek icoon op de linker balk en zoek voor "Polarcraft Modpack"\n
|
||||
**3.** Klik vervolgens op "install"\n
|
||||
**4.** Klaar! Klik op "Play" om Minecraft op te starten\n
|
||||
` })
|
||||
.setDescription('De Polarcraft Modpack is niet nodig, maar wel handig. In deze modpack zitten mods voor betere performance en Proximity chat mod. Als je er voor kiest om deze modpack niet te gebruiken is het leuk om zelf de [Plasmo Voice](https://modrinth.com/plugin/plasmo-voice) mod te installeren.');
|
||||
|
||||
const embed3 = new EmbedBuilder()
|
||||
.setTitle('Links')
|
||||
.setColor(process.env.EMBED_COLOR)
|
||||
.setDescription('-> IP: polarcraft.xeovalyte.com\n-> [Minecraft Map](https://polarcraft.xeovalyte.com)\n-> [Polarcraft Modpack](https://modrinth.com/modpack/polarcraft-modpack)');
|
||||
|
||||
await interaction.reply({ embeds: [embed0, embed1, embed2, embed3] });
|
||||
} else if (option === 'moderators') {
|
||||
const embed = new EmbedBuilder()
|
||||
.setTitle('Commands')
|
||||
.setColor(process.env.EMBED_COLOR)
|
||||
.setDescription('`/suspend <user> <time> <reason>` Dit commando zorgt ervoor dat een persoon tijdelijk niks kan doen. Gebruik dit als er bijvoorbeeld gegriefd wordt\n\n`/nuke` Dit commando zet de server in maintenance mode waardoor niemand meer kan joinen');
|
||||
|
||||
await interaction.reply({ embeds: [embed] });
|
||||
}
|
||||
},
|
||||
};
|
21
discordbot/commands/nuke.js
Normal file
21
discordbot/commands/nuke.js
Normal file
@@ -0,0 +1,21 @@
|
||||
const { SlashCommandBuilder } = require('discord.js');
|
||||
const { simpleEmbed } = require('../functions/embeds.js');
|
||||
|
||||
module.exports = {
|
||||
data: new SlashCommandBuilder()
|
||||
.setName('nuke')
|
||||
.setDescription('Put the server in maintenance mode')
|
||||
.setDefaultMemberPermissions(0),
|
||||
|
||||
async execute(interaction) {
|
||||
await fetch(process.env.MINECRAFT_HOST + '/console', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'content-type': 'text/plain',
|
||||
},
|
||||
body: 'maintenance on',
|
||||
});
|
||||
|
||||
await interaction.reply({ embeds: [simpleEmbed('Nuked server!')], ephemeral: true });
|
||||
},
|
||||
};
|
14
discordbot/commands/ping.js
Normal file
14
discordbot/commands/ping.js
Normal file
@@ -0,0 +1,14 @@
|
||||
const { SlashCommandBuilder } = require('discord.js');
|
||||
const { simpleEmbed } = require('../functions/embeds.js');
|
||||
const { client } = require('../index.js');
|
||||
|
||||
module.exports = {
|
||||
data: new SlashCommandBuilder()
|
||||
.setName('ping')
|
||||
.setDescription('Replies with Pong!'),
|
||||
async execute(interaction) {
|
||||
const reply = await interaction.reply({ embeds: [simpleEmbed(`Websocket heartbeat: **${client.ws.ping}ms**\n Roundtrip latency: **Pinging...**`)], fetchReply: true, ephemeral: true });
|
||||
|
||||
interaction.editReply({ embeds: [simpleEmbed(`Websocket heartbeat: **${client.ws.ping}ms**\n Roundtrip latency: **${reply.createdTimestamp - interaction.createdTimestamp}ms**`)], ephemeral: true });
|
||||
},
|
||||
};
|
31
discordbot/commands/removewhitelist.js
Normal file
31
discordbot/commands/removewhitelist.js
Normal file
@@ -0,0 +1,31 @@
|
||||
const { SlashCommandBuilder } = require('discord.js');
|
||||
const { simpleEmbed } = require('../functions/embeds.js');
|
||||
const { Minecraft, Users } = require('../functions/models.js');
|
||||
const { applyUsername } = require('../functions/utils.js');
|
||||
|
||||
module.exports = {
|
||||
data: new SlashCommandBuilder()
|
||||
.setName('removewhitelist')
|
||||
.setDescription('Remove yourself from the whitelist'),
|
||||
|
||||
async execute(interaction) {
|
||||
try {
|
||||
const user = await Users.findOne({ where: { id: interaction.user.id } });
|
||||
|
||||
if (!user.minecraftUuid) return await interaction.reply({ embeds: [simpleEmbed('You are not whitelisted')], ephemeral: true });
|
||||
|
||||
await Minecraft.destroy({ where: { uuid: user.minecraftUuid } });
|
||||
|
||||
await applyUsername(user, interaction.member);
|
||||
|
||||
const role = await interaction.guild.roles.fetch(process.env.MINECRAFT_ROLE_ID);
|
||||
await interaction.member.roles.remove(role);
|
||||
|
||||
await interaction.reply({ embeds: [simpleEmbed('Successfully removed you from the whitelist')], ephemeral: true });
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
|
||||
await interaction.reply({ embeds: [simpleEmbed('There was an error while removing you from the whitelist')], ephemeral: true });
|
||||
}
|
||||
},
|
||||
};
|
38
discordbot/commands/setusername.js
Normal file
38
discordbot/commands/setusername.js
Normal file
@@ -0,0 +1,38 @@
|
||||
const { SlashCommandBuilder } = require('discord.js');
|
||||
const { simpleEmbed } = require('../functions/embeds.js');
|
||||
const { Users } = require('../functions/models.js');
|
||||
const { applyUsername } = require('../functions/utils.js');
|
||||
|
||||
module.exports = {
|
||||
data: new SlashCommandBuilder()
|
||||
.setName('setusername')
|
||||
.setDescription('Choose between Discord or Minecraft username')
|
||||
.addStringOption(option => option
|
||||
.setName('type')
|
||||
.setDescription('Discord or Minecraft')
|
||||
.setRequired(true)
|
||||
.addChoices(
|
||||
{ name: 'Discord', value: 'discord' },
|
||||
{ name: 'Minecraft', value: 'minecraft' },
|
||||
)),
|
||||
|
||||
async execute(interaction) {
|
||||
const usernameType = interaction.options.getString('type');
|
||||
|
||||
try {
|
||||
const user = await Users.findOne({ where: { id: interaction.user.id } });
|
||||
|
||||
user.useMinecraftUsername = usernameType === 'minecraft' ? true : false;
|
||||
|
||||
await user.save();
|
||||
|
||||
await applyUsername(user, interaction.member);
|
||||
|
||||
await interaction.reply({ embeds: [simpleEmbed('Successfully changed your username type')], ephemeral: true });
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
|
||||
await interaction.reply({ embeds: [simpleEmbed('There was an error while changing your username type')], ephemeral: true });
|
||||
}
|
||||
},
|
||||
};
|
49
discordbot/commands/suspend.js
Normal file
49
discordbot/commands/suspend.js
Normal file
@@ -0,0 +1,49 @@
|
||||
const { SlashCommandBuilder } = require('discord.js');
|
||||
const { simpleEmbed } = require('../functions/embeds.js');
|
||||
const { Users } = require('../functions/models.js');
|
||||
const { client } = require('../index.js');
|
||||
|
||||
module.exports = {
|
||||
data: new SlashCommandBuilder()
|
||||
.setName('suspend')
|
||||
.setDescription('Suspend a user')
|
||||
.setDefaultMemberPermissions(0)
|
||||
.addUserOption(option => option
|
||||
.setName('user')
|
||||
.setDescription('The user to suspend')
|
||||
.setRequired(true))
|
||||
.addNumberOption(option => option
|
||||
.setName('time')
|
||||
.setDescription('The amount of time to suspend the user in minutes')
|
||||
.setRequired(true))
|
||||
.addStringOption(option => option
|
||||
.setName('reason')
|
||||
.setDescription('Why suspend the user')
|
||||
.setRequired(true)),
|
||||
|
||||
async execute(interaction) {
|
||||
const time = interaction.options.getNumber('time');
|
||||
const member = interaction.options.getMember('user');
|
||||
const reason = interaction.options.getString('reason');
|
||||
|
||||
await member.timeout(time * 60 * 1000, reason);
|
||||
|
||||
const user = await Users.findOne({ where: { id: member.id } });
|
||||
if (!user) return await interaction.reply({ embeds: [simpleEmbed('Error while getting user information')], ephemeral: true });
|
||||
|
||||
if (user.minecraftUuid) {
|
||||
await fetch(process.env.MINECRAFT_HOST + '/console', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'content-type': 'text/plain',
|
||||
},
|
||||
body: `tempban ${user.minecraftUuid} ${time}m ${reason}`,
|
||||
});
|
||||
}
|
||||
|
||||
const channel = client.channels.cache.get(process.env.MOD_LOG_CHANNEL_ID);
|
||||
await channel.send({ embeds: [simpleEmbed(`${interaction.user} suspended ${member} for **${time}** minutes, reason: **${reason}**`)] });
|
||||
|
||||
await interaction.reply({ embeds: [simpleEmbed(`Suspended ${member} for **${time}** minutes`)], ephemeral: true });
|
||||
},
|
||||
};
|
208
discordbot/commands/team.js
Normal file
208
discordbot/commands/team.js
Normal file
@@ -0,0 +1,208 @@
|
||||
const { SlashCommandBuilder, ModalBuilder, TextInputStyle, TextInputBuilder, ActionRowBuilder, ChannelType, PermissionsBitField, ButtonBuilder, ButtonStyle, ComponentType } = require('discord.js');
|
||||
const { simpleEmbed } = require('../functions/embeds.js');
|
||||
const { Users, Team } = require('../functions/models.js');
|
||||
const { applyUsername } = require('../functions/utils.js');
|
||||
const { client } = require('../index.js');
|
||||
|
||||
module.exports = {
|
||||
data: new SlashCommandBuilder()
|
||||
.setName('team')
|
||||
.setDescription('Team command')
|
||||
.addSubcommand(subcommand => subcommand
|
||||
.setName('create')
|
||||
.setDescription('Create a team'))
|
||||
.addSubcommand(subcommand => subcommand
|
||||
.setName('invite')
|
||||
.setDescription('Invite an user')
|
||||
.addUserOption(option => option
|
||||
.setName('user')
|
||||
.setDescription('The user to invite')
|
||||
.setRequired(true)))
|
||||
.addSubcommand(subcommand => subcommand
|
||||
.setName('leave')
|
||||
.setDescription('Leave your team')),
|
||||
|
||||
async execute(interaction) {
|
||||
const user = await Users.findOne({ where: { id: interaction.user.id } });
|
||||
if (!user) return await interaction.reply({ embeds: [simpleEmbed('Error while getting user information')], ephemeral: true });
|
||||
|
||||
if (interaction.options.getSubcommand() === 'create') {
|
||||
if (user.teamId) return await interaction.reply({ embeds: [simpleEmbed('You are already in a team')], ephemeral: true });
|
||||
|
||||
const modal = new ModalBuilder()
|
||||
.setCustomId('teamCreate')
|
||||
.setTitle('Create team');
|
||||
|
||||
const nameInput = new TextInputBuilder()
|
||||
.setCustomId('nameInput')
|
||||
.setLabel('Team name')
|
||||
.setMinLength(3)
|
||||
.setMaxLength(16)
|
||||
.setStyle(TextInputStyle.Short);
|
||||
|
||||
const colorInput = new TextInputBuilder()
|
||||
.setCustomId('colorInput')
|
||||
.setLabel('Team color (hex)')
|
||||
.setStyle(TextInputStyle.Short)
|
||||
.setPlaceholder('#00ff00');
|
||||
|
||||
const firstActionRow = new ActionRowBuilder().addComponents(nameInput);
|
||||
const secondActionRow = new ActionRowBuilder().addComponents(colorInput);
|
||||
|
||||
modal.addComponents(firstActionRow, secondActionRow);
|
||||
|
||||
await interaction.showModal(modal);
|
||||
|
||||
try {
|
||||
const filter = (filterInteraction) => filterInteraction.customId === 'teamCreate';
|
||||
const modalInteraction = await interaction.awaitModalSubmit({ filter, time: 10 * 60 * 1000 });
|
||||
|
||||
const teamName = modalInteraction.fields.getTextInputValue('nameInput');
|
||||
const teamColor = modalInteraction.fields.getTextInputValue('colorInput');
|
||||
|
||||
if (!/^[a-zA-Z0-9]+$/.test(teamName)) return await modalInteraction.reply({ embeds: [simpleEmbed('Team name can only include alphanumeric characters')], ephemeral: true });
|
||||
if (!/^#([0-9A-Fa-f]{3}|[0-9A-Fa-f]{6})$/.test(teamColor)) return await modalInteraction.reply({ embeds: [simpleEmbed('Team color must be a valid hex code. [Color Picker](https://htmlcolorcodes.com/color-picker/)')], ephemeral: true });
|
||||
|
||||
|
||||
const guild = await client.guilds.fetch(process.env.GUILD_ID);
|
||||
const category = await guild.channels.fetch(process.env.TEAM_CATEGORY_ID);
|
||||
|
||||
const textChannel = await guild.channels.create({
|
||||
name: teamName,
|
||||
type: ChannelType.GuildText,
|
||||
parent: category,
|
||||
permissionOverwrites: [
|
||||
{
|
||||
id: guild.id,
|
||||
deny: [PermissionsBitField.Flags.ViewChannel],
|
||||
},
|
||||
{
|
||||
id: interaction.member.id,
|
||||
allow: [PermissionsBitField.Flags.ViewChannel],
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
const voiceChannel = await guild.channels.create({
|
||||
name: teamName,
|
||||
type: ChannelType.GuildVoice,
|
||||
parent: category,
|
||||
permissionOverwrites: [
|
||||
{
|
||||
id: guild.id,
|
||||
deny: [PermissionsBitField.Flags.ViewChannel],
|
||||
},
|
||||
{
|
||||
id: interaction.member.id,
|
||||
allow: [PermissionsBitField.Flags.ViewChannel],
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
const team = await Team.create({
|
||||
name: teamName,
|
||||
color: teamColor,
|
||||
textChannelId: textChannel.id,
|
||||
voiceChannelId: voiceChannel.id,
|
||||
});
|
||||
|
||||
await team.addMembers([ user ]);
|
||||
|
||||
await applyUsername(user, interaction.member);
|
||||
|
||||
await modalInteraction.reply({ embeds: [simpleEmbed(`Successfully created team **${teamName}**`)], ephemeral: true });
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
}
|
||||
} else if (interaction.options.getSubcommand() === 'leave') {
|
||||
if (!user.teamId) return await interaction.reply({ embeds: [simpleEmbed('You are not in a team')], ephemeral: true });
|
||||
|
||||
const team = await user.getTeam();
|
||||
await team.removeMember(user);
|
||||
|
||||
const guild = await client.guilds.fetch(process.env.GUILD_ID);
|
||||
|
||||
const textChannel = await guild.channels.fetch(team.textChannelId);
|
||||
const voiceChannel = await guild.channels.fetch(team.voiceChannelId);
|
||||
|
||||
|
||||
if (await team.countMembers() <= 0) {
|
||||
await textChannel.delete();
|
||||
await voiceChannel.delete();
|
||||
|
||||
await team.destroy();
|
||||
} else {
|
||||
await textChannel.permissionOverwrites.delete(interaction.member);
|
||||
await voiceChannel.permissionOverwrites.delete(interaction.member);
|
||||
}
|
||||
|
||||
await applyUsername(user, interaction.member);
|
||||
|
||||
await interaction.reply({ embeds: [simpleEmbed('Successfully left team')], ephemeral: true });
|
||||
} else if (interaction.options.getSubcommand() === 'invite') {
|
||||
if (!user.teamId) return await interaction.reply({ embeds: [simpleEmbed('You are not in a team')], ephemeral: true });
|
||||
|
||||
const invitedUser = interaction.options.getUser('user');
|
||||
if (interaction.user.id === invitedUser.id) return await interaction.reply({ embeds: [simpleEmbed('You cannot invite yourself')], ephemeral: true });
|
||||
|
||||
const invitedUserInstance = await Users.findOne({ where: { id: invitedUser.id } });
|
||||
if (invitedUserInstance.teamId) return await interaction.reply({ embeds: [simpleEmbed('The user you are trying already is in a team')], ephemeral: true });
|
||||
|
||||
const team = await user.getTeam();
|
||||
|
||||
const acceptButton = new ButtonBuilder()
|
||||
.setCustomId('accept')
|
||||
.setLabel('Accept')
|
||||
.setStyle(ButtonStyle.Success);
|
||||
|
||||
const denyButton = new ButtonBuilder()
|
||||
.setCustomId('deny')
|
||||
.setLabel('Deny')
|
||||
.setStyle(ButtonStyle.Danger);
|
||||
|
||||
const row = new ActionRowBuilder()
|
||||
.addComponents(acceptButton, denyButton);
|
||||
|
||||
const inviteMessage = await invitedUser.send({
|
||||
embeds: [simpleEmbed(`**${user.rawUsername}** invited you to join team **${team.name}**`)],
|
||||
components: [row],
|
||||
});
|
||||
|
||||
await interaction.reply({ embeds: [simpleEmbed(`Successfully invited ${invitedUser} to your team`)], ephemeral: true });
|
||||
|
||||
const collector = inviteMessage.createMessageComponentCollector({ componentType: ComponentType.Button, time: 60 * 60 * 1000 });
|
||||
|
||||
collector.on('collect', async i => {
|
||||
try {
|
||||
if (i.customId === 'accept') {
|
||||
await invitedUserInstance.reload();
|
||||
if (invitedUserInstance.teamId) return await i.message.edit({ embeds: [simpleEmbed('You are already in a team')], components: [] });
|
||||
|
||||
await team.addMember(i.user.id);
|
||||
|
||||
const guild = await client.guilds.fetch(process.env.GUILD_ID);
|
||||
const member = await guild.members.fetch(i.user.id);
|
||||
|
||||
const textChannel = await guild.channels.fetch(team.textChannelId);
|
||||
const voiceChannel = await guild.channels.fetch(team.voiceChannelId);
|
||||
|
||||
await textChannel.permissionOverwrites.edit(member, { ViewChannel: true });
|
||||
await voiceChannel.permissionOverwrites.edit(member, { ViewChannel: true });
|
||||
|
||||
await applyUsername(invitedUserInstance, member);
|
||||
|
||||
await i.message.edit({ embeds: [simpleEmbed(`Successfully joined team **${team.name}**`)], components: [] });
|
||||
} else if (i.customId === 'deny') {
|
||||
await i.message.edit({ embeds: [simpleEmbed(`Successfully denied the request to join team **${team.name}**`)], components: [] });
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
}
|
||||
});
|
||||
|
||||
collector.on('end', async () => {
|
||||
inviteMessage.edit({ embeds: [simpleEmbed('Confirmation not received within 1 hour, cancelling')], components: [] });
|
||||
});
|
||||
}
|
||||
},
|
||||
};
|
51
discordbot/commands/whitelist.js
Normal file
51
discordbot/commands/whitelist.js
Normal file
@@ -0,0 +1,51 @@
|
||||
const { SlashCommandBuilder } = require('discord.js');
|
||||
const { simpleEmbed } = require('../functions/embeds.js');
|
||||
const { Minecraft, Users } = require('../functions/models.js');
|
||||
const { applyUsername } = require('../functions/utils.js');
|
||||
|
||||
module.exports = {
|
||||
data: new SlashCommandBuilder()
|
||||
.setName('whitelist')
|
||||
.setDescription('Whitelist yourself on the Minecraft server')
|
||||
.addStringOption(option => option
|
||||
.setName('code')
|
||||
.setDescription('6 digit code from Minecraft')
|
||||
.setRequired(true)),
|
||||
|
||||
async execute(interaction) {
|
||||
const code = interaction.options.getString('code');
|
||||
|
||||
if (code.length !== 6) return await interaction.reply({ embeds: [simpleEmbed('The code must be 6 digits long')], ephemeral: true });
|
||||
const user = await Users.findOne({ where: { id: interaction.user.id } });
|
||||
|
||||
if (!user) return await interaction.reply({ embeds: [simpleEmbed('There was an error while finding the user')], ephemeral: true });
|
||||
if (user.minecraftUuid) return await interaction.reply({ embeds: [simpleEmbed('You are already whitelisted')], ephemeral: true });
|
||||
|
||||
try {
|
||||
const minecraftCol = await Minecraft.findOne({ where: { code: code } });
|
||||
|
||||
if (!minecraftCol) return await interaction.reply({ embeds: [simpleEmbed('The code was not linked with a Minecraft account')], ephemeral: true });
|
||||
|
||||
if (minecraftCol.whitelisted) return await interaction.reply({ embeds: [simpleEmbed('Minecraft account already whitelisted')], ephemeral: true });
|
||||
|
||||
|
||||
minecraftCol.whitelisted = true;
|
||||
delete minecraftCol.code;
|
||||
|
||||
user.minecraftUuid = minecraftCol.uuid;
|
||||
|
||||
await minecraftCol.save();
|
||||
await user.save();
|
||||
|
||||
await applyUsername(user, interaction.member);
|
||||
|
||||
const role = await interaction.guild.roles.fetch(process.env.MINECRAFT_ROLE_ID);
|
||||
await interaction.member.roles.add(role);
|
||||
|
||||
await interaction.reply({ embeds: [simpleEmbed('You are successfully whitelisted')], ephemeral: true });
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
}
|
||||
|
||||
},
|
||||
};
|
26
discordbot/events/guildMemberAdd.js
Normal file
26
discordbot/events/guildMemberAdd.js
Normal file
@@ -0,0 +1,26 @@
|
||||
const { Events, EmbedBuilder } = require('discord.js');
|
||||
const { client } = require('../index.js');
|
||||
const { Users } = require('../functions/models');
|
||||
|
||||
module.exports = {
|
||||
name: Events.GuildMemberAdd,
|
||||
async execute(member) {
|
||||
const addMemberEmbed = new EmbedBuilder()
|
||||
.setTitle(`${member.user.globalName} has joined!`)
|
||||
.setDescription(`Welcome ${member} to the **Polarcraft** Discord server!`)
|
||||
.setColor(process.env.EMBED_COLOR)
|
||||
.setThumbnail(member.user.avatarURL());
|
||||
|
||||
const channel = client.channels.cache.get(process.env.LOG_CHANNEL_ID);
|
||||
await channel.send({ embeds: [addMemberEmbed] });
|
||||
|
||||
try {
|
||||
await Users.create({
|
||||
id: member.user.id,
|
||||
});
|
||||
} catch (error) {
|
||||
if (error.name === 'SequelizeUniqueConstraintError') return;
|
||||
console.error(error);
|
||||
}
|
||||
},
|
||||
};
|
14
discordbot/events/guildMemberRemove.js
Normal file
14
discordbot/events/guildMemberRemove.js
Normal file
@@ -0,0 +1,14 @@
|
||||
const { Events, EmbedBuilder } = require('discord.js');
|
||||
const { client } = require('../index.js');
|
||||
|
||||
module.exports = {
|
||||
name: Events.GuildMemberRemove,
|
||||
async execute(member) {
|
||||
const removeMemberEmbed = new EmbedBuilder()
|
||||
.setTitle(`${member.user.globalName} has left!`)
|
||||
.setColor(process.env.EMBED_COLOR);
|
||||
|
||||
const channel = client.channels.cache.get(process.env.LOG_CHANNEL_ID);
|
||||
channel.send({ embeds: [removeMemberEmbed] });
|
||||
},
|
||||
};
|
25
discordbot/events/interactionCreate.js
Normal file
25
discordbot/events/interactionCreate.js
Normal file
@@ -0,0 +1,25 @@
|
||||
const { Events } = require('discord.js');
|
||||
const { simpleEmbed } = require('../functions/embeds.js');
|
||||
|
||||
module.exports = {
|
||||
name: Events.InteractionCreate,
|
||||
async execute(interaction) {
|
||||
if (interaction.isChatInputCommand() || interaction.isUserContextMenuCommand()) {
|
||||
const command = interaction.client.commands.get(interaction.commandName);
|
||||
|
||||
if (!command) {
|
||||
console.error(`No command matching ${interaction.commandName} was found.`);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
await command.execute(interaction);
|
||||
} catch (error) {
|
||||
await interaction.reply({ embeds: [simpleEmbed('There was an error while executing the command')], ephemeral: true });
|
||||
console.error(`Error executing ${interaction.commandName}`);
|
||||
console.error(error);
|
||||
}
|
||||
}
|
||||
|
||||
},
|
||||
};
|
35
discordbot/events/messageCreate.js
Normal file
35
discordbot/events/messageCreate.js
Normal file
@@ -0,0 +1,35 @@
|
||||
const { Events } = require('discord.js');
|
||||
const { Users } = require('../functions/models.js');
|
||||
|
||||
module.exports = {
|
||||
name: Events.MessageCreate,
|
||||
async execute(message) {
|
||||
if (message.channelId === process.env.MINECRAFT_CHANNEL_ID && !message.author.bot) {
|
||||
try {
|
||||
const user = await Users.findOne({ where: { id: message.author.id } });
|
||||
|
||||
if (!user) return;
|
||||
|
||||
const team = await user.getTeam();
|
||||
|
||||
let tellraw;
|
||||
|
||||
if (!team) {
|
||||
tellraw = `tellraw @a ["",{"text":"DC","color":"gray"},{"text":" ${user.rawUsername} > ${message.content}"}]`;
|
||||
} else {
|
||||
tellraw = `tellraw @a ["",{"text":"DC ","color":"dark_gray"},{"text":"[","color":"gray"},{"text":"${team.name}","color":"${team.color}"},{"text":"]","color":"gray"},{"text":" ${user.rawUsername} "},{"text":"> ${message.content}"}]`;
|
||||
}
|
||||
|
||||
await fetch(process.env.MINECRAFT_HOST + '/console', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'content-type': 'text/plain',
|
||||
},
|
||||
body: tellraw,
|
||||
});
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
17
discordbot/events/ready.js
Normal file
17
discordbot/events/ready.js
Normal file
@@ -0,0 +1,17 @@
|
||||
const { Events } = require('discord.js');
|
||||
const deployCommands = require('../functions/deployCommands');
|
||||
const { Users, Team, Minecraft } = require('../functions/models');
|
||||
|
||||
module.exports = {
|
||||
name: Events.ClientReady,
|
||||
once: true,
|
||||
execute(client) {
|
||||
Users.sync();
|
||||
Team.sync();
|
||||
Minecraft.sync();
|
||||
|
||||
console.log(`Ready! Logged in as ${client.user.tag}`);
|
||||
|
||||
deployCommands();
|
||||
},
|
||||
};
|
45
discordbot/functions/deployCommands.js
Normal file
45
discordbot/functions/deployCommands.js
Normal file
@@ -0,0 +1,45 @@
|
||||
const { REST, Routes } = require('discord.js');
|
||||
const fs = require('node:fs');
|
||||
const path = require('node:path');
|
||||
|
||||
module.exports = function deployCommands() {
|
||||
const commands = [];
|
||||
|
||||
const commandsPath = path.join(__dirname, '../commands');
|
||||
const commandFiles = fs.readdirSync(commandsPath).filter(file => file.endsWith('.js'));
|
||||
|
||||
for (const file of commandFiles) {
|
||||
const filePath = path.join(commandsPath, file);
|
||||
const command = require(filePath);
|
||||
if ('data' in command && 'execute' in command) {
|
||||
commands.push(command.data.toJSON());
|
||||
} else {
|
||||
console.log(`[WARNING] The command at ${filePath} is missing a required "data" or "execute" property.`);
|
||||
}
|
||||
}
|
||||
|
||||
const rest = new REST().setToken(process.env.DISCORD_TOKEN);
|
||||
|
||||
(async () => {
|
||||
try {
|
||||
console.log(`Started refreshing ${commands.length} application (/) commands.`);
|
||||
|
||||
let data;
|
||||
if (process.env.GUILD_ID === 'production') {
|
||||
data = await rest.put(
|
||||
Routes.applicationCommands(process.env.DISCORD_APPLICATION_ID),
|
||||
{ body: commands },
|
||||
);
|
||||
} else {
|
||||
data = await rest.put(
|
||||
Routes.applicationGuildCommands(process.env.DISCORD_APPLICATION_ID, process.env.GUILD_ID),
|
||||
{ body: commands },
|
||||
);
|
||||
}
|
||||
|
||||
console.log(`Successfully reloaded ${data.length} application (/) commands.`);
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
}
|
||||
})();
|
||||
};
|
9
discordbot/functions/embeds.js
Normal file
9
discordbot/functions/embeds.js
Normal file
@@ -0,0 +1,9 @@
|
||||
const { EmbedBuilder } = require('discord.js');
|
||||
|
||||
const simpleEmbed = (content) => {
|
||||
return new EmbedBuilder()
|
||||
.setColor(process.env.EMBED_COLOR)
|
||||
.setDescription(content);
|
||||
};
|
||||
|
||||
module.exports = { simpleEmbed };
|
73
discordbot/functions/models.js
Normal file
73
discordbot/functions/models.js
Normal file
@@ -0,0 +1,73 @@
|
||||
const { PartialWebhookMixin } = require('discord.js');
|
||||
const { sequelize } = require('../index');
|
||||
const Sequelize = require('sequelize');
|
||||
|
||||
const Users = sequelize.define('users', {
|
||||
id: {
|
||||
type: Sequelize.STRING,
|
||||
primaryKey: true,
|
||||
unique: true,
|
||||
},
|
||||
useMinecraftUsername: {
|
||||
type: Sequelize.BOOLEAN,
|
||||
defaultValue: false,
|
||||
},
|
||||
rawUsername: {
|
||||
type: Sequelize.STRING,
|
||||
},
|
||||
moderator: {
|
||||
type: Sequelize.BOOLEAN,
|
||||
defaultValue: false,
|
||||
},
|
||||
admin: {
|
||||
type: Sequelize.BOOLEAN,
|
||||
defaultValue: false,
|
||||
},
|
||||
});
|
||||
|
||||
const Team = sequelize.define('teams', {
|
||||
name: {
|
||||
type: Sequelize.STRING,
|
||||
unique: true,
|
||||
validate: {
|
||||
len: [3, 16],
|
||||
isAlphanumeric: true,
|
||||
},
|
||||
},
|
||||
color: {
|
||||
type: Sequelize.STRING,
|
||||
validate: {
|
||||
is: /^#?([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/,
|
||||
},
|
||||
},
|
||||
textChannelId: {
|
||||
type: Sequelize.STRING,
|
||||
},
|
||||
voiceChannelId: {
|
||||
type: Sequelize.STRING,
|
||||
},
|
||||
});
|
||||
|
||||
const Minecraft = sequelize.define('minecraft', {
|
||||
uuid: {
|
||||
type: Sequelize.UUID,
|
||||
unique: true,
|
||||
primaryKey: true,
|
||||
},
|
||||
whitelisted: {
|
||||
type: Sequelize.BOOLEAN,
|
||||
defaultValue: false,
|
||||
},
|
||||
code: {
|
||||
type: Sequelize.STRING,
|
||||
unique: true,
|
||||
},
|
||||
});
|
||||
|
||||
Minecraft.hasOne(Users);
|
||||
Users.belongsTo(Minecraft);
|
||||
|
||||
Team.hasMany(Users, { as: 'members' });
|
||||
Users.belongsTo(Team);
|
||||
|
||||
module.exports = { Users, Team, Minecraft };
|
29
discordbot/functions/utils.js
Normal file
29
discordbot/functions/utils.js
Normal file
@@ -0,0 +1,29 @@
|
||||
const applyUsername = async (user, member) => {
|
||||
await user.reload();
|
||||
|
||||
let rawUsername = member.user.globalName;
|
||||
|
||||
if (user.useMinecraftUsername && user.minecraftUuid) {
|
||||
const response = await fetch(`https://sessionserver.mojang.com/session/minecraft/profile/${user.minecraftUuid}`);
|
||||
const minecraftProfile = await response.json();
|
||||
|
||||
rawUsername = minecraftProfile.name;
|
||||
}
|
||||
|
||||
user.rawUsername = rawUsername;
|
||||
|
||||
const username = await getUsername(user);
|
||||
|
||||
await user.save();
|
||||
await member.setNickname(username.slice(0, 32));
|
||||
|
||||
return username;
|
||||
};
|
||||
|
||||
const getUsername = async (user) => {
|
||||
const team = await user.getTeam();
|
||||
|
||||
return team ? user.rawUsername + ' [' + team.name + ']' : user.rawUsername;
|
||||
};
|
||||
|
||||
module.exports = { applyUsername, getUsername };
|
@@ -1,45 +1,29 @@
|
||||
const chalk = require('chalk');
|
||||
const { Client, GatewayIntentBits, Collection } = require('discord.js');
|
||||
const { Player } = require('discord-player');
|
||||
const express = require('express');
|
||||
const Sequelize = require('sequelize');
|
||||
const dotenv = require('dotenv');
|
||||
const fs = require('node:fs');
|
||||
const path = require('node:path');
|
||||
const dotenv = require('dotenv');
|
||||
const express = require('express');
|
||||
|
||||
const createEmbed = require('./functions/createEmbed.js');
|
||||
dotenv.config();
|
||||
|
||||
const log = {
|
||||
Info: (message) => console.log(chalk.blue('INFO'), message),
|
||||
Error: (message) => console.log(chalk.red('ERROR'), message),
|
||||
Warn: (message) => console.log(chalk.hex('#FFA500'), message),
|
||||
};
|
||||
|
||||
// Register client and music events
|
||||
const client = new Client({ intents: [GatewayIntentBits.Guilds, GatewayIntentBits.GuildVoiceStates, GatewayIntentBits.GuildMembers, GatewayIntentBits.GuildMessages, GatewayIntentBits.MessageContent] });
|
||||
client.player = new Player(client);
|
||||
|
||||
require('./functions/player.js').registerEvents({ client, createEmbed });
|
||||
|
||||
|
||||
// Express
|
||||
const app = express();
|
||||
app.use(express.json());
|
||||
|
||||
const minecraftRoute = require('./routes/Minecraft');
|
||||
const userRoute = require('./routes/User');
|
||||
const teamRoute = require('./routes/Team');
|
||||
|
||||
app.use('/minecraft', minecraftRoute);
|
||||
app.use('/user', userRoute);
|
||||
app.use('/team', teamRoute);
|
||||
|
||||
app.listen('4000', () => {
|
||||
log.Info('Express app running');
|
||||
// Configure database
|
||||
const sequelize = new Sequelize('polarcraft', 'user', process.env.DATABSE_PASSWORD, {
|
||||
host: 'localhost',
|
||||
dialect: 'sqlite',
|
||||
logging: false,
|
||||
// SQLite only
|
||||
storage: 'database.sqlite',
|
||||
});
|
||||
|
||||
exports.sequelize = sequelize;
|
||||
|
||||
|
||||
// Configure Discord
|
||||
const client = new Client({ intents: [GatewayIntentBits.Guilds, GatewayIntentBits.GuildVoiceStates, GatewayIntentBits.GuildMembers, GatewayIntentBits.GuildMessages, GatewayIntentBits.MessageContent] });
|
||||
exports.client = client;
|
||||
|
||||
// Command handling
|
||||
client.commands = new Collection();
|
||||
|
||||
const commandsPath = path.join(__dirname, 'commands');
|
||||
@@ -52,12 +36,10 @@ for (const file of commandFiles) {
|
||||
if ('data' in command && 'execute' in command) {
|
||||
client.commands.set(command.data.name, command);
|
||||
} else {
|
||||
log.Warn(`The command at ${filePath} is missing a required "data" or "execute" property.`);
|
||||
console.log(`[WARNING] The command at ${filePath} is missing a required "data" or "execute" property.`);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Event handling
|
||||
const eventsPath = path.join(__dirname, 'events');
|
||||
const eventFiles = fs.readdirSync(eventsPath).filter(file => file.endsWith('.js'));
|
||||
|
||||
@@ -65,12 +47,26 @@ for (const file of eventFiles) {
|
||||
const filePath = path.join(eventsPath, file);
|
||||
const event = require(filePath);
|
||||
if (event.once) {
|
||||
client.once(event.name, (...args) => event.execute({ client, log, createEmbed }, ...args));
|
||||
client.once(event.name, (...args) => event.execute(...args));
|
||||
} else {
|
||||
client.on(event.name, (...args) => event.execute({ client, log, createEmbed }, ...args));
|
||||
client.on(event.name, (...args) => event.execute(...args));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Configure express
|
||||
const app = express();
|
||||
app.use(express.json());
|
||||
|
||||
const verifyMinecraftRoute = require('./routes/verifyminecraft');
|
||||
const messageRoute = require('./routes/message');
|
||||
|
||||
app.use('/verifyminecraft', verifyMinecraftRoute);
|
||||
app.use('/message', messageRoute);
|
||||
|
||||
app.listen('3000', () => {
|
||||
console.log('Express app is running');
|
||||
});
|
||||
|
||||
client.login(process.env.DISCORD_TOKEN);
|
||||
|
||||
module.exports.client = client;
|
2191
discord-bot/package-lock.json → discordbot/package-lock.json
generated
2191
discord-bot/package-lock.json → discordbot/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
21
discordbot/package.json
Normal file
21
discordbot/package.json
Normal file
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"name": "discordbot",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"author": "Xeovalyte",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"discord.js": "^14.12.1",
|
||||
"dotenv": "^16.3.1",
|
||||
"express": "^4.18.2",
|
||||
"sequelize": "^6.32.1",
|
||||
"sqlite3": "^5.1.6"
|
||||
},
|
||||
"devDependencies": {
|
||||
"eslint": "^8.46.0"
|
||||
}
|
||||
}
|
56
discordbot/routes/message.js
Normal file
56
discordbot/routes/message.js
Normal file
@@ -0,0 +1,56 @@
|
||||
const express = require('express');
|
||||
const { WebhookClient, EmbedBuilder } = require('discord.js');
|
||||
const { getUsername } = require('../functions/utils.js');
|
||||
const { Users } = require('../functions/models.js');
|
||||
|
||||
const router = express.Router();
|
||||
const webhookClient = new WebhookClient({ url: process.env.MINECRAFT_WEBHOOK_URL });
|
||||
|
||||
router.post('/player', async (req, res) => {
|
||||
const { content, uuid } = req.body;
|
||||
|
||||
if (!uuid || !content) return res.status(400).send({ errorMessage: 'uuid and content are required' });
|
||||
|
||||
try {
|
||||
const user = await Users.findOne({ where: { minecraftUUID: uuid } });
|
||||
|
||||
const username = await getUsername(user);
|
||||
|
||||
webhookClient.send({
|
||||
content,
|
||||
username,
|
||||
avatarURL: 'https://api.mineatar.io/face/' + uuid + '?scale=8',
|
||||
});
|
||||
|
||||
res.send({ status: 'ok' });
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
|
||||
res.status(500).send({ errorMessage: 'Error while sending player message' });
|
||||
}
|
||||
});
|
||||
|
||||
router.post('/game', async (req, res) => {
|
||||
const { content, uuid } = req.body;
|
||||
|
||||
if (!uuid || !content) return res.status(400).send({ errorMessage: 'uuid and content are required' });
|
||||
|
||||
try {
|
||||
const messageEmbed = new EmbedBuilder()
|
||||
.setColor(process.env.EMBED_COLOR)
|
||||
.setAuthor({ name: content, iconURL: 'https://api.mineatar.io/face/' + uuid + '?scale=8' });
|
||||
|
||||
webhookClient.send({
|
||||
embeds: [messageEmbed],
|
||||
username: 'Server',
|
||||
});
|
||||
|
||||
res.send({ status: 'ok' });
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
|
||||
res.status(500).send({ errorMessage: 'Error while sending player message' });
|
||||
}
|
||||
});
|
||||
|
||||
module.exports = router;
|
47
discordbot/routes/verifyminecraft.js
Normal file
47
discordbot/routes/verifyminecraft.js
Normal file
@@ -0,0 +1,47 @@
|
||||
const express = require('express');
|
||||
const { Minecraft, Users } = require('../functions/models.js');
|
||||
|
||||
const router = express.Router();
|
||||
|
||||
router.post('/', async (req, res) => {
|
||||
const { uuid } = req.body;
|
||||
|
||||
if (!uuid) return res.status(400).send({ errorMessage: 'UUID is required' });
|
||||
|
||||
try {
|
||||
const user = await Users.findOne({ where: { minecraftUUID: uuid } });
|
||||
|
||||
if (!user) {
|
||||
const minecraftCol = await Minecraft.findOrCreate({
|
||||
where: { uuid },
|
||||
defaults: {
|
||||
code: generateCode().toString(),
|
||||
},
|
||||
});
|
||||
|
||||
return res.send({ code: minecraftCol[0].code, whitelisted: minecraftCol[0].whitelisted });
|
||||
}
|
||||
|
||||
const team = await user.getTeam();
|
||||
|
||||
let username;
|
||||
if (!team) {
|
||||
username = user.rawUsername;
|
||||
} else {
|
||||
username = '<gray>[</gray>' + `<color:${team.color}>${team.name}</color>` + '<gray>] </gray>' + user.rawUsername;
|
||||
}
|
||||
|
||||
|
||||
res.send({ whitelisted: true, username, rawUsername: user.rawUsername });
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
|
||||
res.status(500).send({ errorMessage: 'Error while verifing minecraft uuid' });
|
||||
}
|
||||
});
|
||||
|
||||
const generateCode = () => {
|
||||
return Math.floor(100000 + Math.random() * 900000);
|
||||
};
|
||||
|
||||
module.exports = router;
|
@@ -1,6 +1,7 @@
|
||||
plugins {
|
||||
id 'fabric-loom' version '1.1-SNAPSHOT'
|
||||
id 'fabric-loom' version '1.3-SNAPSHOT'
|
||||
id 'maven-publish'
|
||||
id 'com.github.johnrengelman.shadow' version '7.0.0'
|
||||
}
|
||||
|
||||
version = project.mod_version
|
||||
@@ -42,6 +43,7 @@ dependencies {
|
||||
// These are included in the Fabric API production distribution and allow you to update your mod to the latest modules at a later more convenient time.
|
||||
|
||||
// modImplementation "net.fabricmc.fabric-api:fabric-api-deprecated:${project.fabric_version}"
|
||||
shadow(implementation("com.sparkjava:spark-core:2.9.4"))
|
||||
}
|
||||
|
||||
processResources {
|
||||
@@ -72,6 +74,17 @@ jar {
|
||||
}
|
||||
}
|
||||
|
||||
shadowJar {
|
||||
configurations = [project.configurations.shadow]
|
||||
archiveClassifier.set("dev")
|
||||
relocate "net.objecthunter", "de.siphalor.spiceoffabric.shadow.net.objecthunter"
|
||||
}
|
||||
|
||||
remapJar {
|
||||
dependsOn(shadowJar)
|
||||
inputFile = tasks.shadowJar.archiveFile
|
||||
}
|
||||
|
||||
// configure the maven publication
|
||||
publishing {
|
||||
publications {
|
||||
@@ -87,4 +100,4 @@ publishing {
|
||||
// The repositories here will be used for publishing your artifact, not for
|
||||
// retrieving dependencies.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -4,9 +4,9 @@ org.gradle.parallel=true
|
||||
|
||||
# Fabric Properties
|
||||
# check these on https://fabricmc.net/develop
|
||||
minecraft_version=1.19.4
|
||||
yarn_mappings=1.19.4+build.2
|
||||
loader_version=0.14.19
|
||||
minecraft_version=1.20.2
|
||||
yarn_mappings=1.20.2+build.2
|
||||
loader_version=0.14.22
|
||||
|
||||
# Mod Properties
|
||||
mod_version=1.0.0
|
||||
@@ -14,4 +14,4 @@ maven_group=com.xeovalyte.polarcraft
|
||||
archives_base_name=polarcraft-mod
|
||||
|
||||
# Dependencies
|
||||
fabric_version=0.79.0+1.19.4
|
||||
fabric_version=0.89.3+1.20.2
|
||||
|
121
mod/remappedSrc/com/xeovalyte/polarcraft/PolarcraftMod.java
Normal file
121
mod/remappedSrc/com/xeovalyte/polarcraft/PolarcraftMod.java
Normal file
@@ -0,0 +1,121 @@
|
||||
package com.xeovalyte.polarcraft;
|
||||
|
||||
import com.xeovalyte.polarcraft.util.messageFunctions;
|
||||
import com.xeovalyte.polarcraft.util.verifyFunction;
|
||||
|
||||
import net.fabricmc.api.ModInitializer;
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import net.fabricmc.fabric.api.networking.v1.ServerPlayConnectionEvents;
|
||||
import net.fabricmc.loader.api.FabricLoader;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.network.ServerPlayerEntity;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.io.File;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
|
||||
import static spark.Spark.*;
|
||||
|
||||
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents;
|
||||
import net.fabricmc.fabric.api.message.v1.ServerMessageEvents;
|
||||
|
||||
public class PolarcraftMod implements ModInitializer {
|
||||
// This logger is used to write text to the console and the log file.
|
||||
// It is considered best practice to use your mod id as the logger's name.
|
||||
// That way, it's clear which mod wrote info, warnings, and errors.
|
||||
public static final Logger LOGGER = LoggerFactory.getLogger("polarcraft-mod");
|
||||
|
||||
private static final Gson GSON = new GsonBuilder().setPrettyPrinting().create();
|
||||
private static final File CONFIG_FILE = new File(FabricLoader.getInstance().getConfigDir().toFile(), "polarcraft.json");
|
||||
|
||||
public static String configChatMessageUrl = "https://example.com/message/player";
|
||||
public static String configGameMessageUrl = "https://example.com/message/game";
|
||||
public static String configVerifyUrl = "https://example.com/verifyminecraft";
|
||||
|
||||
|
||||
@Override
|
||||
public void onInitialize() {
|
||||
// This code runs as soon as Minecraft is in a mod-load-ready state.
|
||||
// However, some things (like resources) may still be uninitialized.
|
||||
// Proceed with mild caution.
|
||||
loadConfig();
|
||||
|
||||
ServerPlayConnectionEvents.JOIN.register((handler, sender, server) -> {
|
||||
ServerPlayerEntity player = (ServerPlayerEntity) handler.player;
|
||||
|
||||
verifyFunction.onPlayerJoin(player, server);
|
||||
});
|
||||
|
||||
ServerPlayConnectionEvents.DISCONNECT.register((handler, server) -> {
|
||||
ServerPlayerEntity player = (ServerPlayerEntity) handler.player;
|
||||
messageFunctions.sendGameMessage(player.getUuid(), player.getDisplayName().getString() + " left the game");
|
||||
});
|
||||
|
||||
ServerMessageEvents.CHAT_MESSAGE.register((message, sender, params) -> {
|
||||
messageFunctions.sendChatMessage(message, sender);
|
||||
});
|
||||
|
||||
ServerLifecycleEvents.SERVER_STARTED.register((MinecraftServer server) -> {
|
||||
port(8080); // Choose a suitable port for your web server
|
||||
|
||||
// Define the /console POST endpoint
|
||||
post("/console", (req, res) -> {
|
||||
String command = req.body(); // Get the command from the request body
|
||||
// Validate and sanitize the command if needed
|
||||
|
||||
// Execute the console command in the Minecraft environment
|
||||
executeConsoleCommand(command, server);
|
||||
|
||||
res.status(200);
|
||||
return "Command executed successfully.";
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
private static void executeConsoleCommand(String command, MinecraftServer server) {
|
||||
// Code to execute the console command within the Minecraft environment.
|
||||
|
||||
server.getCommandManager().executeWithPrefix(server.getCommandSource(), command);
|
||||
}
|
||||
|
||||
private void loadConfig() {
|
||||
if (!CONFIG_FILE.exists()) {
|
||||
saveConfig();
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
MyModConfig config = GSON.fromJson(FileUtils.readFileToString(CONFIG_FILE, StandardCharsets.UTF_8), MyModConfig.class);
|
||||
configChatMessageUrl = config.chatMessageUrl;
|
||||
configGameMessageUrl = config.gameMessageUrl;
|
||||
configVerifyUrl = config.verifyUrl;
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private void saveConfig() {
|
||||
try {
|
||||
FileUtils.writeStringToFile(CONFIG_FILE, GSON.toJson(new MyModConfig(configChatMessageUrl, configGameMessageUrl, configVerifyUrl)), StandardCharsets.UTF_8);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public static class MyModConfig {
|
||||
public String chatMessageUrl;
|
||||
public String gameMessageUrl;
|
||||
public String verifyUrl;
|
||||
|
||||
public MyModConfig(String chatMessageUrl, String gameMessageUrl,String verifyUrl) {
|
||||
this.chatMessageUrl = chatMessageUrl;
|
||||
this.gameMessageUrl = gameMessageUrl;
|
||||
this.verifyUrl = verifyUrl;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,27 @@
|
||||
package com.xeovalyte.polarcraft.mixin;
|
||||
|
||||
import com.xeovalyte.polarcraft.util.messageFunctions;
|
||||
import net.minecraft.entity.damage.DamageSource;
|
||||
import net.minecraft.server.network.ServerPlayerEntity;
|
||||
import net.minecraft.text.Text;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
|
||||
|
||||
@Mixin(ServerPlayerEntity.class)
|
||||
public class MixinPlayerEntity {
|
||||
@Inject(method = "onDeath",
|
||||
at = @At(
|
||||
target = "Lnet/minecraft/server/network/ServerPlayNetworkHandler;sendPacket(Lnet/minecraft/network/packet/Packet;Lnet/minecraft/network/PacketCallbacks;)V",
|
||||
value = "INVOKE",
|
||||
ordinal = 0),
|
||||
locals = LocalCapture.CAPTURE_FAILSOFT
|
||||
)
|
||||
private void onDeath(DamageSource damageSource, CallbackInfo ci, boolean bl, Text text){
|
||||
ServerPlayerEntity serverPlayerEntity = (ServerPlayerEntity) (Object) this;
|
||||
|
||||
messageFunctions.sendGameMessage(serverPlayerEntity.getUuid(), text.getString());
|
||||
}
|
||||
}
|
@@ -0,0 +1,74 @@
|
||||
package com.xeovalyte.polarcraft.util;
|
||||
|
||||
import com.xeovalyte.polarcraft.PolarcraftMod;
|
||||
|
||||
import net.minecraft.network.message.SignedMessage;
|
||||
import net.minecraft.server.network.ServerPlayerEntity;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.OutputStream;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URL;
|
||||
import java.util.UUID;
|
||||
|
||||
public class messageFunctions {
|
||||
public static void sendGameMessage(UUID uuid, String message) {
|
||||
try {
|
||||
// Create a URL object for the server endpoint
|
||||
URL url = new URL(PolarcraftMod.configGameMessageUrl);
|
||||
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
|
||||
|
||||
connection.setRequestMethod("POST");
|
||||
connection.setRequestProperty("Content-Type", "application/json");
|
||||
connection.setDoOutput(true);
|
||||
|
||||
String requestBody = "{\"content\":\"" + message + "\", \"uuid\":\"" + uuid + "\"}";
|
||||
|
||||
OutputStream outputStream = connection.getOutputStream();
|
||||
outputStream.write(requestBody.getBytes());
|
||||
outputStream.flush();
|
||||
outputStream.close();
|
||||
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
|
||||
String line;
|
||||
StringBuilder response = new StringBuilder();
|
||||
while ((line = reader.readLine()) != null) {
|
||||
response.append(line);
|
||||
}
|
||||
reader.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public static void sendChatMessage( SignedMessage message, ServerPlayerEntity sender) {
|
||||
try {
|
||||
// Create a URL object for the server endpoint
|
||||
URL url = new URL(PolarcraftMod.configChatMessageUrl);
|
||||
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
|
||||
|
||||
connection.setRequestMethod("POST");
|
||||
connection.setRequestProperty("Content-Type", "application/json");
|
||||
connection.setDoOutput(true);
|
||||
|
||||
String requestBody = "{\"content\":\"" + message.getSignedContent() + "\", \"uuid\":\"" + sender.getUuid() + "\"}";
|
||||
|
||||
OutputStream outputStream = connection.getOutputStream();
|
||||
outputStream.write(requestBody.getBytes());
|
||||
outputStream.flush();
|
||||
outputStream.close();
|
||||
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
|
||||
String line;
|
||||
StringBuilder response = new StringBuilder();
|
||||
while ((line = reader.readLine()) != null) {
|
||||
response.append(line);
|
||||
}
|
||||
reader.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,69 @@
|
||||
package com.xeovalyte.polarcraft.util;
|
||||
|
||||
import com.xeovalyte.polarcraft.PolarcraftMod;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.OutputStream;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URL;
|
||||
import java.util.UUID;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.network.ServerPlayerEntity;
|
||||
import net.minecraft.text.Text;
|
||||
|
||||
public class verifyFunction {
|
||||
public static void onPlayerJoin(ServerPlayerEntity player, MinecraftServer server) {
|
||||
UUID uuid = player.getUuid();
|
||||
|
||||
try {
|
||||
URL url = new URL(PolarcraftMod.configVerifyUrl);
|
||||
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
|
||||
|
||||
connection.setRequestMethod("POST");
|
||||
connection.setRequestProperty("Content-Type", "application/json");
|
||||
connection.setDoOutput(true);
|
||||
|
||||
String requestBody = "{\"uuid\":\"" + uuid + "\"}";
|
||||
|
||||
OutputStream outputStream = connection.getOutputStream();
|
||||
outputStream.write(requestBody.getBytes());
|
||||
outputStream.flush();
|
||||
outputStream.close();
|
||||
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
|
||||
String line;
|
||||
StringBuilder response = new StringBuilder();
|
||||
while ((line = reader.readLine()) != null) {
|
||||
response.append(line);
|
||||
}
|
||||
reader.close();
|
||||
|
||||
Gson gson = new Gson();
|
||||
JsonElement element = gson.fromJson(response.toString(), JsonElement.class);
|
||||
JsonObject jsonResponse = element.getAsJsonObject();
|
||||
|
||||
boolean whitelisted = jsonResponse.get("whitelisted").getAsBoolean();
|
||||
|
||||
if (!whitelisted) {
|
||||
int code = jsonResponse.get("code").getAsInt();
|
||||
|
||||
player.networkHandler.disconnect(Text.literal("Whitelist yourself by using the /whitelist command in Discord with this code: " + code));
|
||||
} else {
|
||||
server.getCommandManager().executeWithPrefix(server.getCommandSource(), "/lp user " + player.getUuid() + " meta set display " + "\"" + jsonResponse.get("username").getAsString() + "\"");
|
||||
|
||||
messageFunctions.sendGameMessage(player.getUuid(), jsonResponse.get("rawUsername").getAsString() + " joined the game");
|
||||
}
|
||||
} catch (IOException e) {
|
||||
player.networkHandler.disconnect(Text.literal("There was an error while verifing your account"));
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@@ -10,6 +10,7 @@ import org.slf4j.LoggerFactory;
|
||||
|
||||
import net.fabricmc.fabric.api.networking.v1.ServerPlayConnectionEvents;
|
||||
import net.fabricmc.loader.api.FabricLoader;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.network.ServerPlayerEntity;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
@@ -18,6 +19,9 @@ import java.io.File;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
|
||||
import static spark.Spark.*;
|
||||
|
||||
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents;
|
||||
import net.fabricmc.fabric.api.message.v1.ServerMessageEvents;
|
||||
|
||||
public class PolarcraftMod implements ModInitializer {
|
||||
@@ -29,9 +33,10 @@ public class PolarcraftMod implements ModInitializer {
|
||||
private static final Gson GSON = new GsonBuilder().setPrettyPrinting().create();
|
||||
private static final File CONFIG_FILE = new File(FabricLoader.getInstance().getConfigDir().toFile(), "polarcraft.json");
|
||||
|
||||
public static String configChatMessageUrl = "https://example.com/api/minecraft/message/chattodiscord";
|
||||
public static String configGameMessageUrl = "https://example.com/api/minecraft/message/gametodiscord";
|
||||
public static String configVerifyUrl = "https://example.com/api/minecraft/verifyuuid";
|
||||
public static String configChatMessageUrl = "https://example.com/message/player";
|
||||
public static String configGameMessageUrl = "https://example.com/message/game";
|
||||
public static String configVerifyUrl = "https://example.com/verifyminecraft";
|
||||
|
||||
|
||||
@Override
|
||||
public void onInitialize() {
|
||||
@@ -54,6 +59,28 @@ public class PolarcraftMod implements ModInitializer {
|
||||
ServerMessageEvents.CHAT_MESSAGE.register((message, sender, params) -> {
|
||||
messageFunctions.sendChatMessage(message, sender);
|
||||
});
|
||||
|
||||
ServerLifecycleEvents.SERVER_STARTED.register((MinecraftServer server) -> {
|
||||
port(8080); // Choose a suitable port for your web server
|
||||
|
||||
// Define the /console POST endpoint
|
||||
post("/console", (req, res) -> {
|
||||
String command = req.body(); // Get the command from the request body
|
||||
// Validate and sanitize the command if needed
|
||||
|
||||
// Execute the console command in the Minecraft environment
|
||||
executeConsoleCommand(command, server);
|
||||
|
||||
res.status(200);
|
||||
return "Command executed successfully.";
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
private static void executeConsoleCommand(String command, MinecraftServer server) {
|
||||
// Code to execute the console command within the Minecraft environment.
|
||||
|
||||
server.getCommandManager().executeWithPrefix(server.getCommandSource(), command);
|
||||
}
|
||||
|
||||
private void loadConfig() {
|
||||
@@ -74,7 +101,7 @@ public class PolarcraftMod implements ModInitializer {
|
||||
|
||||
private void saveConfig() {
|
||||
try {
|
||||
FileUtils.writeStringToFile(CONFIG_FILE, GSON.toJson(new MyModConfig(configChatMessageUrl, configGameMessageUrl,configVerifyUrl)), StandardCharsets.UTF_8);
|
||||
FileUtils.writeStringToFile(CONFIG_FILE, GSON.toJson(new MyModConfig(configChatMessageUrl, configGameMessageUrl, configVerifyUrl)), StandardCharsets.UTF_8);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
@@ -91,4 +118,4 @@ public class PolarcraftMod implements ModInitializer {
|
||||
this.verifyUrl = verifyUrl;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -8,20 +8,15 @@ import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
|
||||
|
||||
@Mixin(ServerPlayerEntity.class)
|
||||
public class MixinPlayerEntity {
|
||||
@Inject(method = "onDeath",
|
||||
at = @At(
|
||||
target = "Lnet/minecraft/server/network/ServerPlayNetworkHandler;sendPacket(Lnet/minecraft/network/packet/Packet;Lnet/minecraft/network/PacketCallbacks;)V",
|
||||
value = "INVOKE",
|
||||
ordinal = 0),
|
||||
locals = LocalCapture.CAPTURE_FAILSOFT
|
||||
)
|
||||
private void onDeath(DamageSource damageSource, CallbackInfo ci, boolean bl, Text text){
|
||||
@Inject(method = "onDeath", at = @At("HEAD"))
|
||||
private void onDeath(DamageSource damageSource, CallbackInfo ci){
|
||||
ServerPlayerEntity serverPlayerEntity = (ServerPlayerEntity) (Object) this;
|
||||
|
||||
messageFunctions.sendGameMessage(serverPlayerEntity.getUuid(), text.getString());
|
||||
Text deathMessage = damageSource.getDeathMessage(serverPlayerEntity);
|
||||
|
||||
messageFunctions.sendGameMessage(serverPlayerEntity.getUuid(), deathMessage.getString());
|
||||
}
|
||||
}
|
||||
|
@@ -49,16 +49,16 @@ public class verifyFunction {
|
||||
JsonElement element = gson.fromJson(response.toString(), JsonElement.class);
|
||||
JsonObject jsonResponse = element.getAsJsonObject();
|
||||
|
||||
boolean verified = jsonResponse.get("verified").getAsBoolean();
|
||||
boolean whitelisted = jsonResponse.get("whitelisted").getAsBoolean();
|
||||
|
||||
if (!verified) {
|
||||
if (!whitelisted) {
|
||||
int code = jsonResponse.get("code").getAsInt();
|
||||
|
||||
player.networkHandler.disconnect(Text.literal("Whitelist yourself by using this code: " + code));
|
||||
player.networkHandler.disconnect(Text.literal("Whitelist yourself by using the /whitelist command in Discord with this code: " + code));
|
||||
} else {
|
||||
server.getCommandManager().executeWithPrefix(server.getCommandSource(), "/lp user " + player.getUuid() + " meta set display " + "\"" + jsonResponse.get("username").getAsString() + "\"");
|
||||
|
||||
messageFunctions.sendGameMessage(player.getUuid(), jsonResponse.get("usernameWithoutStyle").getAsString() + " joined the game");
|
||||
messageFunctions.sendGameMessage(player.getUuid(), jsonResponse.get("rawUsername").getAsString() + " joined the game");
|
||||
}
|
||||
} catch (IOException e) {
|
||||
player.networkHandler.disconnect(Text.literal("There was an error while verifing your account"));
|
||||
|
@@ -24,7 +24,7 @@
|
||||
],
|
||||
"depends": {
|
||||
"fabricloader": ">=0.14.19",
|
||||
"minecraft": "~1.19.4",
|
||||
"minecraft": ">=1.20.1",
|
||||
"java": ">=17",
|
||||
"fabric-api": "*"
|
||||
},
|
||||
|
@@ -3,7 +3,6 @@
|
||||
"package": "com.xeovalyte.polarcraft.mixin",
|
||||
"compatibilityLevel": "JAVA_17",
|
||||
"mixins": [
|
||||
"MixinPlayerAdvancementTracker",
|
||||
"MixinPlayerEntity"
|
||||
],
|
||||
"injectors": {
|
||||
|
2
modpack-server/.gitattributes
vendored
Normal file
2
modpack-server/.gitattributes
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
# Disable Git line ending conversion, to prevent packwiz index hashes changing when committing from Windows
|
||||
* -text
|
5
modpack-server/.gitignore
vendored
Normal file
5
modpack-server/.gitignore
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
# Exclude exported CurseForge zip files
|
||||
*.zip
|
||||
|
||||
# Exclude exported Modrinth modpacks
|
||||
*.mrpack
|
@@ -1,101 +1,171 @@
|
||||
hash-format = "sha256"
|
||||
|
||||
[[files]]
|
||||
file = "mods/alternate-current.pw.toml"
|
||||
hash = "fda319290cfe268fdc7c6c6ca8dcad24e51c1de98442f23f2a41d657b26fc8d0"
|
||||
metafile = true
|
||||
|
||||
[[files]]
|
||||
file = "mods/anti-xray.pw.toml"
|
||||
hash = "d8833b2961beb076df826ac3a34634260fa9828923a9a327da882065fa3b2f84"
|
||||
hash = "f0e3f0178d1f8da2487cbb0cea687f441b84109e9f1030e2974d88fe10210aab"
|
||||
metafile = true
|
||||
|
||||
[[files]]
|
||||
file = "mods/banhammer.pw.toml"
|
||||
hash = "40a4d80590660eadaa6002f006f0738136fa35583686ea1fb163f98c63d72bac"
|
||||
hash = "1126dd7cb63d5e4086d74d0fe521156ab9ee0f2d53cd75f3926ffcf256c32953"
|
||||
metafile = true
|
||||
|
||||
[[files]]
|
||||
file = "mods/c2me-fabric.pw.toml"
|
||||
hash = "9ab9f1ada10bc693019cdfea96fa09bcbaa3f27c8350e2e23fc45927f838cd9b"
|
||||
metafile = true
|
||||
|
||||
[[files]]
|
||||
file = "mods/carpet.pw.toml"
|
||||
hash = "bc125da2af00e14613ca7d6582bbfff0ce63632dac134da4e9cfcf2d724bd856"
|
||||
metafile = true
|
||||
|
||||
[[files]]
|
||||
file = "mods/chunky.pw.toml"
|
||||
hash = "c176a0f84b0c3c03423e68b988cd43f51a6b1cf13a844574b19e003324533da0"
|
||||
metafile = true
|
||||
|
||||
[[files]]
|
||||
file = "mods/debugify.pw.toml"
|
||||
hash = "d02024521821336e40652c36c675ee520b4137ed73953e98f21bcf8a55f6a583"
|
||||
hash = "ebc95d8dac761549f43c49938b8d1a0044a43af4484f492959de83a2bdc9e267"
|
||||
metafile = true
|
||||
|
||||
[[files]]
|
||||
file = "mods/fabric-api.pw.toml"
|
||||
hash = "e87a52fb14288a8c503c76a40a18fb901de532b2805e84799c63d6202b3ce037"
|
||||
hash = "d2b04b985ed22bb26338837b0547f08a41b82b23c3136f1fff9582b1748b7954"
|
||||
metafile = true
|
||||
|
||||
[[files]]
|
||||
file = "mods/fabric-language-kotlin.pw.toml"
|
||||
hash = "0fe83c99b29c952f464c7bfba9cc86cc4f834bef7834821433fe23ce3dd230e6"
|
||||
hash = "6f95b9e670d557f852a798489d7b5ec48ed8ddc7e8e1809ff06d4b187d17aac9"
|
||||
metafile = true
|
||||
|
||||
[[files]]
|
||||
file = "mods/fastback.pw.toml"
|
||||
hash = "5b7e58e98cafdc851a3f86d9044b8a69a0d719c98fd9a64ab8a492b791861c81"
|
||||
metafile = true
|
||||
|
||||
[[files]]
|
||||
file = "mods/fastload.pw.toml"
|
||||
hash = "9ab7092cb7e27bec8bb02d195e8f0c6a207b3f1383da7179a57ebd3328778a24"
|
||||
hash = "0e72ac12907f4fb5a499a459cc2c64f9225a0c77ee59e76c9360ff0d3479aea2"
|
||||
metafile = true
|
||||
|
||||
[[files]]
|
||||
file = "mods/ferrite-core.pw.toml"
|
||||
hash = "4c1b893d87c51588985c483fe33193ca03cf3673de998eef6eeb850d8928e7ab"
|
||||
hash = "03e174cf691b52da20bd973b955fae6f3720d3d2120f9d6cc1de5fdf3180013c"
|
||||
metafile = true
|
||||
|
||||
[[files]]
|
||||
file = "mods/headindex.pw.toml"
|
||||
hash = "48e4d5004d63bf599c62daf73c36f7bfaccd770c7cc8645c2d03e5cddede167d"
|
||||
file = "mods/forge-config-api-port.pw.toml"
|
||||
hash = "e00070f0db00ebcd304f8f68fd44e59ceaedbc8c27743c9c195134aae57c5fde"
|
||||
metafile = true
|
||||
|
||||
[[files]]
|
||||
file = "mods/invview.pw.toml"
|
||||
hash = "fc6c71feb98476fa7cc0c683a52993bc751772171372fde95b0d823da0c6a2b7"
|
||||
hash = "9c440b128787446aceeac944eb692793dd24e4596c23d0adfd64a76706ca774d"
|
||||
metafile = true
|
||||
|
||||
[[files]]
|
||||
file = "mods/krypton.pw.toml"
|
||||
hash = "f999930809222b57898da25a30aad2135b02894f42c0e1d2832c4670272fbd1d"
|
||||
metafile = true
|
||||
|
||||
[[files]]
|
||||
file = "mods/lazydfu.pw.toml"
|
||||
hash = "b4ca05b39b85c27cd97ccb65d5fb832f5e9fd7ee5710542a3e69dfa30a97ea7d"
|
||||
metafile = true
|
||||
|
||||
[[files]]
|
||||
file = "mods/ledger-databases.pw.toml"
|
||||
hash = "d8c5d10864c6ee4a5ffdcf775ef6325fb88e6441db9c5c7874be1a6f1d714250"
|
||||
metafile = true
|
||||
|
||||
[[files]]
|
||||
file = "mods/ledger.pw.toml"
|
||||
hash = "badf7e1fb371f1cdac13ce547794339a58c64d87793ce4d5bf4151f99d5e2e00"
|
||||
hash = "e988cb120a107e8d0a3ad501beda973e1b247b290421667a67d95fce146e5dcc"
|
||||
metafile = true
|
||||
|
||||
[[files]]
|
||||
file = "mods/lithium.pw.toml"
|
||||
hash = "feaedf6b6d73530c0289d9c7aa4149823343d2a7f9893f7b81e8c7c003763f31"
|
||||
hash = "ed27ecb297016accc41e9894b6e11d6c46b455211e358afa6218ce629ef56978"
|
||||
metafile = true
|
||||
|
||||
[[files]]
|
||||
file = "mods/maintenancemode.pw.toml"
|
||||
hash = "ed2ff97cf59a6c5b9f4e509edbc8c48944bb3c98795f6738c8dfec353cbe350d"
|
||||
metafile = true
|
||||
|
||||
[[files]]
|
||||
file = "mods/memoryleakfix.pw.toml"
|
||||
hash = "5b43c0fc6904ad4480c8ed596411c6e24172f8320ccd63de97b4ce2e7e0f90a5"
|
||||
hash = "8e42842f48b3227733bafced612212eee2298f567ca599ac6a55b9878ae661da"
|
||||
metafile = true
|
||||
|
||||
[[files]]
|
||||
file = "mods/minimotd.pw.toml"
|
||||
hash = "c24df3c6860014bab5f2b5998b26a34e93461679b1c22e88c4eebfe992b5d756"
|
||||
metafile = true
|
||||
|
||||
[[files]]
|
||||
file = "mods/no-chat-reports.pw.toml"
|
||||
hash = "df11b66e152011f96cc5a4dbf35d2dec99c4373cb19a8c1c761368170d425cf4"
|
||||
hash = "293f06651cc903947ae422f5e612c73d66154453ad1390bda63920370671b968"
|
||||
metafile = true
|
||||
|
||||
[[files]]
|
||||
file = "mods/smoothboot-fabric.pw.toml"
|
||||
hash = "971e8b0bef16bd6ce88c7f940b30fdc1debff7b715058f4d331d54beb58a4314"
|
||||
file = "mods/ordered-player-list.pw.toml"
|
||||
hash = "261eb8ac6dcc730afd8643a6486d6b013bbbe2f1200dacc88d7c495e4a588aa5"
|
||||
metafile = true
|
||||
|
||||
[[files]]
|
||||
file = "mods/pl3xmap.pw.toml"
|
||||
hash = "53febdce710c35a2c12fe58a55a4d97ee50b0e4cc9ae8bf56e0d436b31602c3b"
|
||||
metafile = true
|
||||
|
||||
[[files]]
|
||||
file = "mods/servercore.pw.toml"
|
||||
hash = "17b4cf782db225c145f5c2ababe1042deb0fed021f410d42691829673fa916c3"
|
||||
metafile = true
|
||||
|
||||
[[files]]
|
||||
file = "mods/slime.pw.toml"
|
||||
hash = "cbd8c0b34192c5db74644840e2954be757698c805ed95bfb8007253c9783fab0"
|
||||
metafile = true
|
||||
|
||||
[[files]]
|
||||
file = "mods/spark.pw.toml"
|
||||
hash = "9f7ce104c709103550148f4ff79acd17f9f93901224166445de1052b681c09da"
|
||||
hash = "1f922cadccd8b79e824e78d5e2e691e65127e7a500723121a6a6ccc6a1060289"
|
||||
metafile = true
|
||||
|
||||
[[files]]
|
||||
file = "mods/starlight.pw.toml"
|
||||
hash = "0a78a506125c0edc97d2292d26c6eab310106c60a5a4e64d73ff67bb619f5a4c"
|
||||
metafile = true
|
||||
|
||||
[[files]]
|
||||
file = "mods/styled-chat.pw.toml"
|
||||
hash = "1555d923f1277dfd8c1c55bf1ad8fa109718b717ee2f528fdaa80978e25e74e3"
|
||||
hash = "06f08304d7ce0221440ece1277be678c17dceb80ff982d19eaa9599345e92328"
|
||||
metafile = true
|
||||
|
||||
[[files]]
|
||||
file = "mods/styledplayerlist.pw.toml"
|
||||
hash = "77b0faa9fdcbaf2d0b11358b34a659fd99e00dd5a7f150e0ad69a38259df81a7"
|
||||
hash = "8a3e2e84597cef453b7f1c46e09764139db8c0915c662c2df9e738bc3efb14b3"
|
||||
metafile = true
|
||||
|
||||
[[files]]
|
||||
file = "mods/thorium.pw.toml"
|
||||
hash = "61e2a941621007c901c96fe1474b3c07f208712fa6130151771d5235b6cc8adb"
|
||||
file = "mods/vanish.pw.toml"
|
||||
hash = "95886b6bc392072bf3ff366a19dc913745ec24fd86639012c49d50c13ca71cd1"
|
||||
metafile = true
|
||||
|
||||
[[files]]
|
||||
file = "mods/vmp-fabric.pw.toml"
|
||||
hash = "4acfdcf28a7214490664892807bdb6c2d73b8d09295677e5629e5c896c3f9fbb"
|
||||
metafile = true
|
||||
|
||||
[[files]]
|
||||
file = "mods/worldedit.pw.toml"
|
||||
hash = "a9ef701727ae9dd5baab92af7474cc57e34111b5858941fd5a96c89cacc6a30b"
|
||||
metafile = true
|
||||
|
||||
[[files]]
|
||||
file = "mods/yacl.pw.toml"
|
||||
hash = "c66028d555a347562589645179fe8834bd04d48b78c9a667f20b4178211dfbb3"
|
||||
hash = "46d3f8c4c1bfc8f92858d7e405aed9d1a23e554a783f8977662cbeca06eda5f2"
|
||||
metafile = true
|
||||
|
@@ -1,13 +0,0 @@
|
||||
name = "Alternate Current"
|
||||
filename = "alternate-current-mc1.19-1.4.0.jar"
|
||||
side = "server"
|
||||
|
||||
[download]
|
||||
url = "https://cdn.modrinth.com/data/r0v8vy1s/versions/mc1.19-1.4.0/alternate-current-mc1.19-1.4.0.jar"
|
||||
hash-format = "sha1"
|
||||
hash = "108344ed05830948e6ab1414efa4f7ab34e6dba9"
|
||||
|
||||
[update]
|
||||
[update.modrinth]
|
||||
mod-id = "r0v8vy1s"
|
||||
version = "4QElEqe4"
|
@@ -1,13 +1,13 @@
|
||||
name = "AntiXray"
|
||||
filename = "anti-xray-1.3.0-Fabric-1.19.3.jar"
|
||||
filename = "anti-xray-1.3.1-Fabric-1.20.2.jar"
|
||||
side = "server"
|
||||
|
||||
[download]
|
||||
url = "https://cdn.modrinth.com/data/sml2FMaA/versions/WPaK6kfx/anti-xray-1.3.0-Fabric-1.19.3.jar"
|
||||
url = "https://cdn.modrinth.com/data/sml2FMaA/versions/asevPA28/anti-xray-1.3.1-Fabric-1.20.2.jar"
|
||||
hash-format = "sha1"
|
||||
hash = "a7cdba2fd9a2801cba56e74bedf6c6ee63a461a1"
|
||||
hash = "9af6c8fe101e9a44500661078386c20cb68c92a4"
|
||||
|
||||
[update]
|
||||
[update.modrinth]
|
||||
mod-id = "sml2FMaA"
|
||||
version = "WPaK6kfx"
|
||||
version = "asevPA28"
|
||||
|
@@ -1,13 +1,13 @@
|
||||
name = "BanHammer"
|
||||
filename = "banhammer-0.6.3+1.19.3.jar"
|
||||
filename = "banhammer-0.8.0+1.20.2.jar"
|
||||
side = "server"
|
||||
|
||||
[download]
|
||||
url = "https://cdn.modrinth.com/data/Wpqg0ciI/versions/LFwC8Fix/banhammer-0.6.3%2B1.19.3.jar"
|
||||
url = "https://cdn.modrinth.com/data/Wpqg0ciI/versions/Ia1ERLRG/banhammer-0.8.0%2B1.20.2.jar"
|
||||
hash-format = "sha1"
|
||||
hash = "8c2bcb4aa5b8aeec6066d96f5675225cb625820a"
|
||||
hash = "c7e5c4f334063eedad673cee228d35106ff5bfbf"
|
||||
|
||||
[update]
|
||||
[update.modrinth]
|
||||
mod-id = "Wpqg0ciI"
|
||||
version = "LFwC8Fix"
|
||||
version = "Ia1ERLRG"
|
||||
|
13
modpack-server/mods/c2me-fabric.pw.toml
Normal file
13
modpack-server/mods/c2me-fabric.pw.toml
Normal file
@@ -0,0 +1,13 @@
|
||||
name = "Concurrent Chunk Management Engine (Fabric)"
|
||||
filename = "c2me-fabric-mc1.20.2-0.2.0+alpha.10.126.jar"
|
||||
side = "both"
|
||||
|
||||
[download]
|
||||
url = "https://cdn.modrinth.com/data/VSNURh3q/versions/ilKwGRiJ/c2me-fabric-mc1.20.2-0.2.0%2Balpha.10.126.jar"
|
||||
hash-format = "sha1"
|
||||
hash = "fef69c623f5bfc6c10c86f2790a7c1ac2da3cf32"
|
||||
|
||||
[update]
|
||||
[update.modrinth]
|
||||
mod-id = "VSNURh3q"
|
||||
version = "ilKwGRiJ"
|
13
modpack-server/mods/carpet.pw.toml
Normal file
13
modpack-server/mods/carpet.pw.toml
Normal file
@@ -0,0 +1,13 @@
|
||||
name = "Carpet"
|
||||
filename = "fabric-carpet-1.20.2-1.4.119+v230928.jar"
|
||||
side = "both"
|
||||
|
||||
[download]
|
||||
url = "https://cdn.modrinth.com/data/TQTTVgYE/versions/iGHB3B1y/fabric-carpet-1.20.2-1.4.119%2Bv230928.jar"
|
||||
hash-format = "sha1"
|
||||
hash = "bfda47816a14ed51f646802ba97ead8e08e4eaa5"
|
||||
|
||||
[update]
|
||||
[update.modrinth]
|
||||
mod-id = "TQTTVgYE"
|
||||
version = "iGHB3B1y"
|
13
modpack-server/mods/chunky.pw.toml
Normal file
13
modpack-server/mods/chunky.pw.toml
Normal file
@@ -0,0 +1,13 @@
|
||||
name = "Chunky"
|
||||
filename = "Chunky-1.3.92.jar"
|
||||
side = "both"
|
||||
|
||||
[download]
|
||||
url = "https://cdn.modrinth.com/data/fALzjamp/versions/t8SbUchF/Chunky-1.3.92.jar"
|
||||
hash-format = "sha1"
|
||||
hash = "91f8daeeaab0f3114016fb1d45822179701862bf"
|
||||
|
||||
[update]
|
||||
[update.modrinth]
|
||||
mod-id = "fALzjamp"
|
||||
version = "t8SbUchF"
|
@@ -1,13 +1,13 @@
|
||||
name = "Debugify"
|
||||
filename = "Debugify-1.19.3+1.1.jar"
|
||||
filename = "Debugify-1.20.2+1.0.jar"
|
||||
side = "both"
|
||||
|
||||
[download]
|
||||
url = "https://cdn.modrinth.com/data/QwxR6Gcd/versions/fgjgGIfI/Debugify-1.19.3%2B1.1.jar"
|
||||
url = "https://cdn.modrinth.com/data/QwxR6Gcd/versions/ZSI78Xd3/Debugify-1.20.2%2B1.0.jar"
|
||||
hash-format = "sha1"
|
||||
hash = "d7f9cbf11bb36ef360de2b898a5a5e224eaef9e3"
|
||||
hash = "5afa015e026de8acb4622e6e1429221e0b26e05e"
|
||||
|
||||
[update]
|
||||
[update.modrinth]
|
||||
mod-id = "QwxR6Gcd"
|
||||
version = "fgjgGIfI"
|
||||
version = "ZSI78Xd3"
|
||||
|
@@ -1,13 +1,13 @@
|
||||
name = "Fabric API"
|
||||
filename = "fabric-api-0.74.0+1.19.3.jar"
|
||||
filename = "fabric-api-0.89.3+1.20.2.jar"
|
||||
side = "both"
|
||||
|
||||
[download]
|
||||
url = "https://cdn.modrinth.com/data/P7dR8mSH/versions/1ld37x4U/fabric-api-0.74.0%2B1.19.3.jar"
|
||||
url = "https://cdn.modrinth.com/data/P7dR8mSH/versions/Hi8quJUM/fabric-api-0.89.3%2B1.20.2.jar"
|
||||
hash-format = "sha1"
|
||||
hash = "119d1710004834d83f34d2b8519aebedba981979"
|
||||
hash = "de8d59b597ee5bbf1434e495c0cbc3772b1a414a"
|
||||
|
||||
[update]
|
||||
[update.modrinth]
|
||||
mod-id = "P7dR8mSH"
|
||||
version = "1ld37x4U"
|
||||
version = "Hi8quJUM"
|
||||
|
@@ -1,13 +1,13 @@
|
||||
name = "Fabric Language Kotlin"
|
||||
filename = "fabric-language-kotlin-1.9.1+kotlin.1.8.10.jar"
|
||||
filename = "fabric-language-kotlin-1.10.10+kotlin.1.9.10.jar"
|
||||
side = "both"
|
||||
|
||||
[download]
|
||||
url = "https://cdn.modrinth.com/data/Ha28R6CL/versions/lgFl3olb/fabric-language-kotlin-1.9.1%2Bkotlin.1.8.10.jar"
|
||||
url = "https://cdn.modrinth.com/data/Ha28R6CL/versions/48ri5y9r/fabric-language-kotlin-1.10.10%2Bkotlin.1.9.10.jar"
|
||||
hash-format = "sha1"
|
||||
hash = "12f265ea91e73ac2c74c6f66d446671122bbb1c8"
|
||||
hash = "c708f3f4e94f0f66e72c6e96858368f0512c3b38"
|
||||
|
||||
[update]
|
||||
[update.modrinth]
|
||||
mod-id = "Ha28R6CL"
|
||||
version = "lgFl3olb"
|
||||
version = "48ri5y9r"
|
||||
|
13
modpack-server/mods/fastback.pw.toml
Normal file
13
modpack-server/mods/fastback.pw.toml
Normal file
@@ -0,0 +1,13 @@
|
||||
name = "Fast Backups"
|
||||
filename = "fastback-0.16.1+1.20.2-fabric.jar"
|
||||
side = "both"
|
||||
|
||||
[download]
|
||||
url = "https://cdn.modrinth.com/data/ZHKrK8Rp/versions/yuRPpkVE/fastback-0.16.1%2B1.20.2-fabric.jar"
|
||||
hash-format = "sha1"
|
||||
hash = "13f07b16c9311da033fe38ae93ef34cc0d19c7c4"
|
||||
|
||||
[update]
|
||||
[update.modrinth]
|
||||
mod-id = "ZHKrK8Rp"
|
||||
version = "yuRPpkVE"
|
@@ -1,13 +1,13 @@
|
||||
name = "Fastload"
|
||||
filename = "Fastload+1.19.3-2.6.11.jar"
|
||||
filename = "Fastload+1.18.2-1.20-3.4.0.jar"
|
||||
side = "both"
|
||||
|
||||
[download]
|
||||
url = "https://cdn.modrinth.com/data/kCpssoSb/versions/GCH0zDV1/Fastload%2B1.19.3-2.6.11.jar"
|
||||
url = "https://cdn.modrinth.com/data/kCpssoSb/versions/ys9T20o4/Fastload%2B1.18.2-1.20-3.4.0.jar"
|
||||
hash-format = "sha1"
|
||||
hash = "a796a3d17378e943a45caf576e9749aaa157d174"
|
||||
hash = "b57e4d594031638b0dc076a3b6e501f417700577"
|
||||
|
||||
[update]
|
||||
[update.modrinth]
|
||||
mod-id = "kCpssoSb"
|
||||
version = "GCH0zDV1"
|
||||
version = "ys9T20o4"
|
||||
|
@@ -1,13 +1,13 @@
|
||||
name = "FerriteCore"
|
||||
filename = "ferritecore-5.1.0-fabric.jar"
|
||||
filename = "ferritecore-6.0.0-fabric.jar"
|
||||
side = "both"
|
||||
|
||||
[download]
|
||||
url = "https://cdn.modrinth.com/data/uXXizFIs/versions/GHcKib6J/ferritecore-5.1.0-fabric.jar"
|
||||
url = "https://cdn.modrinth.com/data/uXXizFIs/versions/FCnCG6PS/ferritecore-6.0.0-fabric.jar"
|
||||
hash-format = "sha1"
|
||||
hash = "4c45e0e8981374d6c98304c3de90e813eb930673"
|
||||
hash = "5a57ea73c3c7c0cc300d69611a9cad93baf8e9ab"
|
||||
|
||||
[update]
|
||||
[update.modrinth]
|
||||
mod-id = "uXXizFIs"
|
||||
version = "GHcKib6J"
|
||||
version = "FCnCG6PS"
|
||||
|
13
modpack-server/mods/forge-config-api-port.pw.toml
Normal file
13
modpack-server/mods/forge-config-api-port.pw.toml
Normal file
@@ -0,0 +1,13 @@
|
||||
name = "Forge Config API Port"
|
||||
filename = "ForgeConfigAPIPort-v9.0.0-1.20.2-Fabric.jar"
|
||||
side = "both"
|
||||
|
||||
[download]
|
||||
url = "https://cdn.modrinth.com/data/ohNO6lps/versions/f5d9VI72/ForgeConfigAPIPort-v9.0.0-1.20.2-Fabric.jar"
|
||||
hash-format = "sha1"
|
||||
hash = "e9471a5836daab325aaa9bd08759705f8de94545"
|
||||
|
||||
[update]
|
||||
[update.modrinth]
|
||||
mod-id = "ohNO6lps"
|
||||
version = "f5d9VI72"
|
@@ -1,13 +0,0 @@
|
||||
name = "Head Index"
|
||||
filename = "headindex-1.1.1.jar"
|
||||
side = "both"
|
||||
|
||||
[download]
|
||||
url = "https://cdn.modrinth.com/data/mEPmyd7J/versions/smDwseAG/headindex-1.1.1.jar"
|
||||
hash-format = "sha1"
|
||||
hash = "0f6ed3d568acd55fcdb4814bdfb4256031254fac"
|
||||
|
||||
[update]
|
||||
[update.modrinth]
|
||||
mod-id = "mEPmyd7J"
|
||||
version = "smDwseAG"
|
@@ -1,13 +1,13 @@
|
||||
name = "Inv View"
|
||||
filename = "InvView-1.4.10-1.19.3+.jar"
|
||||
filename = "InvView-1.4.12-1.20+.jar"
|
||||
side = "both"
|
||||
|
||||
[download]
|
||||
url = "https://cdn.modrinth.com/data/jrDKjZP7/versions/rv8bhw5X/InvView-1.4.10-1.19.3%2B.jar"
|
||||
url = "https://cdn.modrinth.com/data/jrDKjZP7/versions/mQnjqDOd/InvView-1.4.12-1.20%2B.jar"
|
||||
hash-format = "sha1"
|
||||
hash = "99dd21d6aab9c65d9b1135bce9c912e6bfd48feb"
|
||||
hash = "f6775526021843c16dc7847bbf0b8dbcca434454"
|
||||
|
||||
[update]
|
||||
[update.modrinth]
|
||||
mod-id = "jrDKjZP7"
|
||||
version = "rv8bhw5X"
|
||||
version = "mQnjqDOd"
|
||||
|
13
modpack-server/mods/krypton.pw.toml
Normal file
13
modpack-server/mods/krypton.pw.toml
Normal file
@@ -0,0 +1,13 @@
|
||||
name = "Krypton"
|
||||
filename = "krypton-0.2.4.jar"
|
||||
side = "both"
|
||||
|
||||
[download]
|
||||
url = "https://cdn.modrinth.com/data/fQEb0iXm/versions/cQ60Ouax/krypton-0.2.4.jar"
|
||||
hash-format = "sha1"
|
||||
hash = "cffdf89a438b83215ddbac2a29c56a2cd68b7d57"
|
||||
|
||||
[update]
|
||||
[update.modrinth]
|
||||
mod-id = "fQEb0iXm"
|
||||
version = "cQ60Ouax"
|
13
modpack-server/mods/lazydfu.pw.toml
Normal file
13
modpack-server/mods/lazydfu.pw.toml
Normal file
@@ -0,0 +1,13 @@
|
||||
name = "LazyDFU"
|
||||
filename = "lazydfu-0.1.3.jar"
|
||||
side = "both"
|
||||
|
||||
[download]
|
||||
url = "https://cdn.modrinth.com/data/hvFnDODi/versions/0.1.3/lazydfu-0.1.3.jar"
|
||||
hash-format = "sha1"
|
||||
hash = "0dfa8b03ed408fb7fdada29e01cfebba02af1049"
|
||||
|
||||
[update]
|
||||
[update.modrinth]
|
||||
mod-id = "hvFnDODi"
|
||||
version = "4SHylIO9"
|
13
modpack-server/mods/ledger-databases.pw.toml
Normal file
13
modpack-server/mods/ledger-databases.pw.toml
Normal file
@@ -0,0 +1,13 @@
|
||||
name = "Ledger Databases"
|
||||
filename = "ledger-databases-1.1.1.jar"
|
||||
side = "both"
|
||||
|
||||
[download]
|
||||
hash-format = "sha1"
|
||||
hash = "d806fed8fea5f3f5a3dc892d605bd6720c86f43e"
|
||||
mode = "metadata:curseforge"
|
||||
|
||||
[update]
|
||||
[update.curseforge]
|
||||
file-id = 3834676
|
||||
project-id = 529404
|
@@ -1,13 +1,13 @@
|
||||
name = "Ledger"
|
||||
filename = "ledger-1.2.6.jar"
|
||||
filename = "ledger-1.2.9.jar"
|
||||
side = "server"
|
||||
|
||||
[download]
|
||||
url = "https://cdn.modrinth.com/data/LVN9ygNV/versions/ykSbFGkA/ledger-1.2.6.jar"
|
||||
url = "https://cdn.modrinth.com/data/LVN9ygNV/versions/8WSkA7qO/ledger-1.2.9.jar"
|
||||
hash-format = "sha1"
|
||||
hash = "636857df039d3cec623843844abb72c670590d61"
|
||||
hash = "8b67c3f918dc655bada6fec3cffcb76628a21a96"
|
||||
|
||||
[update]
|
||||
[update.modrinth]
|
||||
mod-id = "LVN9ygNV"
|
||||
version = "ykSbFGkA"
|
||||
version = "8WSkA7qO"
|
||||
|
@@ -1,13 +1,13 @@
|
||||
name = "Lithium"
|
||||
filename = "lithium-fabric-mc1.19.3-0.10.4.jar"
|
||||
filename = "lithium-fabric-mc1.20.2-0.12.0.jar"
|
||||
side = "both"
|
||||
|
||||
[download]
|
||||
url = "https://cdn.modrinth.com/data/gvQqBUqZ/versions/XS6vJwop/lithium-fabric-mc1.19.3-0.10.4.jar"
|
||||
url = "https://cdn.modrinth.com/data/gvQqBUqZ/versions/qdzL5Hkg/lithium-fabric-mc1.20.2-0.12.0.jar"
|
||||
hash-format = "sha1"
|
||||
hash = "a1b521e18f7857a2fd327c7bebeed3128418e3c9"
|
||||
hash = "9b713d4909582d900274dcd7ca01abd195b53520"
|
||||
|
||||
[update]
|
||||
[update.modrinth]
|
||||
mod-id = "gvQqBUqZ"
|
||||
version = "XS6vJwop"
|
||||
version = "qdzL5Hkg"
|
||||
|
13
modpack-server/mods/maintenancemode.pw.toml
Normal file
13
modpack-server/mods/maintenancemode.pw.toml
Normal file
@@ -0,0 +1,13 @@
|
||||
name = "Maintenance Mode"
|
||||
filename = "mmode-fabric-1.20-1.1.1.jar"
|
||||
side = "server"
|
||||
|
||||
[download]
|
||||
url = "https://cdn.modrinth.com/data/QOkEkSap/versions/TT7eUrpf/mmode-fabric-1.20-1.1.1.jar"
|
||||
hash-format = "sha1"
|
||||
hash = "da772889aaff617e9d85fd1ff4637663219f38c3"
|
||||
|
||||
[update]
|
||||
[update.modrinth]
|
||||
mod-id = "QOkEkSap"
|
||||
version = "TT7eUrpf"
|
@@ -1,13 +1,13 @@
|
||||
name = "Memory Leak Fix"
|
||||
filename = "memoryleakfix-1.19.3-0.7.0.jar"
|
||||
filename = "memoryleakfix-fabric-1.17+-1.1.2.jar"
|
||||
side = "both"
|
||||
|
||||
[download]
|
||||
url = "https://cdn.modrinth.com/data/NRjRiSSD/versions/YtNQP5gX/memoryleakfix-1.19.3-0.7.0.jar"
|
||||
url = "https://cdn.modrinth.com/data/NRjRiSSD/versions/dGlflhb6/memoryleakfix-fabric-1.17%2B-1.1.2.jar"
|
||||
hash-format = "sha1"
|
||||
hash = "9fae1093c64b47d6b97ee825ed3d9b725490700c"
|
||||
hash = "b0eecb140bd124c781469aa0f48bc888072b4ac5"
|
||||
|
||||
[update]
|
||||
[update.modrinth]
|
||||
mod-id = "NRjRiSSD"
|
||||
version = "YtNQP5gX"
|
||||
version = "dGlflhb6"
|
||||
|
13
modpack-server/mods/minimotd.pw.toml
Normal file
13
modpack-server/mods/minimotd.pw.toml
Normal file
@@ -0,0 +1,13 @@
|
||||
name = "MiniMOTD"
|
||||
filename = "minimotd-fabric-mc1.20.2-2.0.14.jar"
|
||||
side = "server"
|
||||
|
||||
[download]
|
||||
url = "https://cdn.modrinth.com/data/16vhQOQN/versions/3stGUvKr/minimotd-fabric-mc1.20.2-2.0.14.jar"
|
||||
hash-format = "sha1"
|
||||
hash = "060e0cfdcbe2d7fcf35373ec01cf0a3d468dd28b"
|
||||
|
||||
[update]
|
||||
[update.modrinth]
|
||||
mod-id = "16vhQOQN"
|
||||
version = "3stGUvKr"
|
@@ -1,13 +1,13 @@
|
||||
name = "No Chat Reports"
|
||||
filename = "NoChatReports-FABRIC-1.19.3-v2.0.0.jar"
|
||||
filename = "NoChatReports-FABRIC-1.20.2-v2.3.1.jar"
|
||||
side = "both"
|
||||
|
||||
[download]
|
||||
url = "https://cdn.modrinth.com/data/qQyHxfxd/versions/uVt4LKvF/NoChatReports-FABRIC-1.19.3-v2.0.0.jar"
|
||||
url = "https://cdn.modrinth.com/data/qQyHxfxd/versions/xQyq2W5g/NoChatReports-FABRIC-1.20.2-v2.3.1.jar"
|
||||
hash-format = "sha1"
|
||||
hash = "2eaa80b4480ca6c0d8b1180fdb742ebcb43ac300"
|
||||
hash = "cb77c14bfc458066eda3c7962c3286e0f973725e"
|
||||
|
||||
[update]
|
||||
[update.modrinth]
|
||||
mod-id = "qQyHxfxd"
|
||||
version = "uVt4LKvF"
|
||||
version = "xQyq2W5g"
|
||||
|
13
modpack-server/mods/ordered-player-list.pw.toml
Normal file
13
modpack-server/mods/ordered-player-list.pw.toml
Normal file
@@ -0,0 +1,13 @@
|
||||
name = "Ordered Player List"
|
||||
filename = "orderedplayerlist-0.1.3+1.20.2.jar"
|
||||
side = "server"
|
||||
|
||||
[download]
|
||||
url = "https://cdn.modrinth.com/data/IX99VLW9/versions/DL7rAiJr/orderedplayerlist-0.1.3%2B1.20.2.jar"
|
||||
hash-format = "sha1"
|
||||
hash = "2902406910f397bcd8236d51b7b54f9f74c4ba5c"
|
||||
|
||||
[update]
|
||||
[update.modrinth]
|
||||
mod-id = "IX99VLW9"
|
||||
version = "DL7rAiJr"
|
13
modpack-server/mods/pl3xmap.pw.toml
Normal file
13
modpack-server/mods/pl3xmap.pw.toml
Normal file
@@ -0,0 +1,13 @@
|
||||
name = "Pl3xMap"
|
||||
filename = "Pl3xMap-1.20.2-470.jar"
|
||||
side = "both"
|
||||
|
||||
[download]
|
||||
url = "https://cdn.modrinth.com/data/YMXhf1UJ/versions/XrSXxwyn/Pl3xMap-1.20.2-470.jar"
|
||||
hash-format = "sha1"
|
||||
hash = "1e7b36c914c49f5febd86426ca528556d22479bd"
|
||||
|
||||
[update]
|
||||
[update.modrinth]
|
||||
mod-id = "YMXhf1UJ"
|
||||
version = "XrSXxwyn"
|
13
modpack-server/mods/servercore.pw.toml
Normal file
13
modpack-server/mods/servercore.pw.toml
Normal file
@@ -0,0 +1,13 @@
|
||||
name = "ServerCore"
|
||||
filename = "servercore-fabric-1.3.8+1.20.2.jar"
|
||||
side = "both"
|
||||
|
||||
[download]
|
||||
url = "https://cdn.modrinth.com/data/4WWQxlQP/versions/LrB49Mln/servercore-fabric-1.3.8%2B1.20.2.jar"
|
||||
hash-format = "sha1"
|
||||
hash = "e99fb454665cd298f44bfb5b415b4b54c02224f9"
|
||||
|
||||
[update]
|
||||
[update.modrinth]
|
||||
mod-id = "4WWQxlQP"
|
||||
version = "LrB49Mln"
|
13
modpack-server/mods/slime.pw.toml
Normal file
13
modpack-server/mods/slime.pw.toml
Normal file
@@ -0,0 +1,13 @@
|
||||
name = "Slime"
|
||||
filename = "slime-1.6.jar"
|
||||
side = "both"
|
||||
|
||||
[download]
|
||||
url = "https://cdn.modrinth.com/data/qpnMRvwM/versions/sQ9J9gE1/slime-1.6.jar"
|
||||
hash-format = "sha1"
|
||||
hash = "ace6e6b4538eaae4e9142023c67b1d5a83928d62"
|
||||
|
||||
[update]
|
||||
[update.modrinth]
|
||||
mod-id = "qpnMRvwM"
|
||||
version = "sQ9J9gE1"
|
@@ -1,13 +0,0 @@
|
||||
name = "Smooth Boot (Fabric)"
|
||||
filename = "smoothboot-fabric-1.19-1.7.1.jar"
|
||||
side = "both"
|
||||
|
||||
[download]
|
||||
url = "https://cdn.modrinth.com/data/FWumhS4T/versions/1.19-1.7.1/smoothboot-fabric-1.19-1.7.1.jar"
|
||||
hash-format = "sha1"
|
||||
hash = "8414cbce145a5f48102e6cc811dfd1459afe44f3"
|
||||
|
||||
[update]
|
||||
[update.modrinth]
|
||||
mod-id = "FWumhS4T"
|
||||
version = "r8xRVPEI"
|
@@ -1,13 +1,13 @@
|
||||
name = "spark"
|
||||
filename = "spark-1.10.29-fabric.jar"
|
||||
filename = "spark-1.10.54-fabric.jar"
|
||||
side = "both"
|
||||
|
||||
[download]
|
||||
url = "https://cdn.modrinth.com/data/l6YH9Als/versions/1K3xO8TS/spark-1.10.29-fabric.jar"
|
||||
url = "https://cdn.modrinth.com/data/l6YH9Als/versions/tCU9VuzX/spark-1.10.54-fabric.jar"
|
||||
hash-format = "sha1"
|
||||
hash = "680b8ed890e05ed0811065a381a7924d536e0508"
|
||||
hash = "cc6d6dd27e2d6612e848330b5525026709590239"
|
||||
|
||||
[update]
|
||||
[update.modrinth]
|
||||
mod-id = "l6YH9Als"
|
||||
version = "1K3xO8TS"
|
||||
version = "tCU9VuzX"
|
||||
|
13
modpack-server/mods/starlight.pw.toml
Normal file
13
modpack-server/mods/starlight.pw.toml
Normal file
@@ -0,0 +1,13 @@
|
||||
name = "Starlight (Fabric)"
|
||||
filename = "starlight-1.1.2+fabric.bdaeb21.jar"
|
||||
side = "both"
|
||||
|
||||
[download]
|
||||
url = "https://cdn.modrinth.com/data/H8CaAYZC/versions/98VOoYPX/starlight-1.1.2%2Bfabric.bdaeb21.jar"
|
||||
hash-format = "sha1"
|
||||
hash = "6cf71105561a6893f76ae561fdbef839c404b8b5"
|
||||
|
||||
[update]
|
||||
[update.modrinth]
|
||||
mod-id = "H8CaAYZC"
|
||||
version = "98VOoYPX"
|
@@ -1,13 +1,13 @@
|
||||
name = "Styled Chat"
|
||||
filename = "styled-chat-2.1.2+1.19.3.jar"
|
||||
filename = "styled-chat-2.3.0+1.20.2.jar"
|
||||
side = "both"
|
||||
|
||||
[download]
|
||||
url = "https://cdn.modrinth.com/data/doqSKB0e/versions/BriPIjGV/styled-chat-2.1.2%2B1.19.3.jar"
|
||||
url = "https://cdn.modrinth.com/data/doqSKB0e/versions/J9nCzhiG/styled-chat-2.3.0%2B1.20.2.jar"
|
||||
hash-format = "sha1"
|
||||
hash = "f54c649adb0b4cfccdfca71ddd0a2f4afe761947"
|
||||
hash = "a6401354c9d393914930556827abe01e090d33df"
|
||||
|
||||
[update]
|
||||
[update.modrinth]
|
||||
mod-id = "doqSKB0e"
|
||||
version = "BriPIjGV"
|
||||
version = "J9nCzhiG"
|
||||
|
@@ -1,13 +1,13 @@
|
||||
name = "Styled Player List"
|
||||
filename = "styledplayerlist-2.3.0+1.19.3.jar"
|
||||
side = "server"
|
||||
filename = "styledplayerlist-3.2.0+1.20.2.jar"
|
||||
side = "both"
|
||||
|
||||
[download]
|
||||
url = "https://cdn.modrinth.com/data/DQIfKUHf/versions/cEi0Qx95/styledplayerlist-2.3.0%2B1.19.3.jar"
|
||||
url = "https://cdn.modrinth.com/data/DQIfKUHf/versions/8c1ZipKd/styledplayerlist-3.2.0%2B1.20.2.jar"
|
||||
hash-format = "sha1"
|
||||
hash = "1edd1c021991f26ab42ea3eb49153d719153a582"
|
||||
hash = "82895d8776b10b927e503c3f79ece0d8a12eb839"
|
||||
|
||||
[update]
|
||||
[update.modrinth]
|
||||
mod-id = "DQIfKUHf"
|
||||
version = "cEi0Qx95"
|
||||
version = "8c1ZipKd"
|
||||
|
@@ -1,13 +0,0 @@
|
||||
name = "thorium"
|
||||
filename = "thorium-1.4.0.jar"
|
||||
side = "both"
|
||||
|
||||
[download]
|
||||
url = "https://cdn.modrinth.com/data/ImUQFWcy/versions/ChzyZR8C/thorium-1.4.0.jar"
|
||||
hash-format = "sha1"
|
||||
hash = "dc5d3176cf60ee669ef0f5ca0fc151cd403aa64a"
|
||||
|
||||
[update]
|
||||
[update.modrinth]
|
||||
mod-id = "ImUQFWcy"
|
||||
version = "ChzyZR8C"
|
13
modpack-server/mods/vanish.pw.toml
Normal file
13
modpack-server/mods/vanish.pw.toml
Normal file
@@ -0,0 +1,13 @@
|
||||
name = "Vanish"
|
||||
filename = "vanish-1.4.2+1.20.2.jar"
|
||||
side = "server"
|
||||
|
||||
[download]
|
||||
url = "https://cdn.modrinth.com/data/UL4bJFDY/versions/hqxpO8Cn/vanish-1.4.2%2B1.20.2.jar"
|
||||
hash-format = "sha1"
|
||||
hash = "cfa3fc2cdebb3fd4c88fa0b691651c797dc1ddf6"
|
||||
|
||||
[update]
|
||||
[update.modrinth]
|
||||
mod-id = "UL4bJFDY"
|
||||
version = "hqxpO8Cn"
|
13
modpack-server/mods/vmp-fabric.pw.toml
Normal file
13
modpack-server/mods/vmp-fabric.pw.toml
Normal file
@@ -0,0 +1,13 @@
|
||||
name = "Very Many Players (Fabric)"
|
||||
filename = "vmp-fabric-mc1.20.2-0.2.0+beta.7.115-all.jar"
|
||||
side = "both"
|
||||
|
||||
[download]
|
||||
url = "https://cdn.modrinth.com/data/wnEe9KBa/versions/XHRLuI9m/vmp-fabric-mc1.20.2-0.2.0%2Bbeta.7.115-all.jar"
|
||||
hash-format = "sha1"
|
||||
hash = "39322ddb12deb6c59599109733adc6435fe12ef7"
|
||||
|
||||
[update]
|
||||
[update.modrinth]
|
||||
mod-id = "wnEe9KBa"
|
||||
version = "XHRLuI9m"
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user