✨ Passage roles en DB pour faciliter maintenance
This commit is contained in:
parent
0a79243494
commit
2974baaaba
13
.env.example
13
.env.example
@ -1,12 +1,13 @@
|
|||||||
TOKEN="BOT_TOKEN"
|
TOKEN="BOT_TOKEN"
|
||||||
GUILD_ID="1234567890"
|
GUILD_ID="1234567890"
|
||||||
DB_DIALECT="mysql"
|
|
||||||
|
DB_DIALECT="postgres"
|
||||||
DB_HOST="localhost"
|
DB_HOST="localhost"
|
||||||
DB_NAME="gachamelia"
|
DB_NAME="gachamelia"
|
||||||
DB_USERNAME="gachamelia"
|
DB_USERNAME="postgres"
|
||||||
DB_PASSWORD="gachamelia"
|
DB_PASSWORD="gachamelia"
|
||||||
DB_PORT=3310
|
DB_PORT=5433
|
||||||
SSR_ROLE=""
|
|
||||||
SR_ROLE=""
|
|
||||||
R_ROLE=""
|
|
||||||
WELCOME_CHANNEL=""
|
WELCOME_CHANNEL=""
|
||||||
|
|
||||||
|
INIT_DB="true"
|
@ -1,15 +1,13 @@
|
|||||||
services:
|
services:
|
||||||
mysql:
|
postgres:
|
||||||
image: mysql:8
|
image: postgres:17
|
||||||
environment:
|
environment:
|
||||||
MYSQL_ROOT_PASSWORD: root
|
POSTGRES_PASSWORD: gachamelia
|
||||||
MYSQL_DATABASE: gachamelia
|
POSTGRES_DB: gachamelia
|
||||||
MYSQL_USER: gachamelia
|
|
||||||
MYSQL_PASSWORD: gachamelia
|
|
||||||
ports:
|
ports:
|
||||||
- "3310:3306"
|
- "5433:5432"
|
||||||
volumes:
|
volumes:
|
||||||
- mysql_gachamelia_data:/var/lib/mysql
|
- postgres_gachamelia_data:/var/lib/postgresql/data
|
||||||
|
|
||||||
volumes:
|
volumes:
|
||||||
mysql_gachamelia_data:
|
postgres_gachamelia_data:
|
@ -9,6 +9,7 @@ import {Database} from "./Database";
|
|||||||
import {IDatabaseConfig} from "../interfaces/IDatabaseConfig";
|
import {IDatabaseConfig} from "../interfaces/IDatabaseConfig";
|
||||||
import {Dialect} from "sequelize";
|
import {Dialect} from "sequelize";
|
||||||
import {User} from "../models/User";
|
import {User} from "../models/User";
|
||||||
|
import {Rank} from "../models/Rank";
|
||||||
|
|
||||||
export class CustomClient extends Client implements ICustomClient {
|
export class CustomClient extends Client implements ICustomClient {
|
||||||
config: IConfig;
|
config: IConfig;
|
||||||
@ -47,7 +48,20 @@ export class CustomClient extends Client implements ICustomClient {
|
|||||||
}
|
}
|
||||||
async init(): Promise<void> {
|
async init(): Promise<void> {
|
||||||
await this.database.connect();
|
await this.database.connect();
|
||||||
|
|
||||||
|
Rank.initModel(this.database.getSequelize());
|
||||||
User.initModel(this.database.getSequelize());
|
User.initModel(this.database.getSequelize());
|
||||||
|
|
||||||
|
|
||||||
|
Rank.hasMany(User, {
|
||||||
|
foreignKey: 'rankId',
|
||||||
|
as: 'users'
|
||||||
|
});
|
||||||
|
User.belongsTo(Rank, {
|
||||||
|
foreignKey: 'rankId',
|
||||||
|
as: 'rank'
|
||||||
|
});
|
||||||
|
|
||||||
await this.database.sync({
|
await this.database.sync({
|
||||||
alter: true
|
alter: true
|
||||||
});
|
});
|
||||||
|
@ -1,6 +0,0 @@
|
|||||||
export enum Rank {
|
|
||||||
SSR = 'SSR',
|
|
||||||
SR = 'SR',
|
|
||||||
R = 'R',
|
|
||||||
}
|
|
||||||
|
|
@ -1,6 +0,0 @@
|
|||||||
export enum RankChance {
|
|
||||||
SSR = 3,
|
|
||||||
SR = 17,
|
|
||||||
R = 80,
|
|
||||||
}
|
|
||||||
|
|
40
src/base/models/Rank.ts
Normal file
40
src/base/models/Rank.ts
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
import { Model, DataTypes, Sequelize } from 'sequelize';
|
||||||
|
import {User} from "./User";
|
||||||
|
|
||||||
|
export class Rank extends Model {
|
||||||
|
declare id: number;
|
||||||
|
declare name: string;
|
||||||
|
declare discordId: string;
|
||||||
|
declare percentage: number;
|
||||||
|
declare createdAt: Date;
|
||||||
|
declare updatedAt: Date;
|
||||||
|
declare users: User[];
|
||||||
|
|
||||||
|
public static initModel(sequelize: Sequelize): void {
|
||||||
|
Rank.init({
|
||||||
|
id: {
|
||||||
|
type: DataTypes.INTEGER,
|
||||||
|
autoIncrement: true,
|
||||||
|
primaryKey: true
|
||||||
|
},
|
||||||
|
name: {
|
||||||
|
type: DataTypes.STRING,
|
||||||
|
allowNull: false
|
||||||
|
},
|
||||||
|
discordId: {
|
||||||
|
type: DataTypes.STRING,
|
||||||
|
allowNull: false,
|
||||||
|
unique: true
|
||||||
|
},
|
||||||
|
percentage: {
|
||||||
|
type: DataTypes.INTEGER,
|
||||||
|
allowNull: false
|
||||||
|
},
|
||||||
|
createdAt: DataTypes.DATE,
|
||||||
|
updatedAt: DataTypes.DATE,
|
||||||
|
}, {
|
||||||
|
sequelize,
|
||||||
|
tableName: 'ranks'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
@ -1,12 +1,22 @@
|
|||||||
import { Model, DataTypes, Sequelize } from 'sequelize';
|
import {
|
||||||
import { Rank } from '../enums/Rank';
|
Model,
|
||||||
|
DataTypes,
|
||||||
|
Sequelize,
|
||||||
|
ForeignKey,
|
||||||
|
NonAttribute,
|
||||||
|
InferAttributes, InferCreationAttributes, CreationOptional, Association
|
||||||
|
} from 'sequelize';
|
||||||
|
import {Rank} from "./Rank";
|
||||||
|
|
||||||
export class User extends Model {
|
export class User extends Model<
|
||||||
declare id: number;
|
InferAttributes<User>,
|
||||||
|
InferCreationAttributes<User>> {
|
||||||
|
declare id: CreationOptional<number>;
|
||||||
declare discordId: string;
|
declare discordId: string;
|
||||||
declare rank: Rank;
|
declare rankId: ForeignKey<number>;
|
||||||
declare createdAt: Date;
|
declare rank: NonAttribute<Rank>;
|
||||||
declare updatedAt: Date;
|
declare createdAt: CreationOptional<Date>;
|
||||||
|
declare updatedAt: CreationOptional<Date>;
|
||||||
|
|
||||||
public static initModel(sequelize: Sequelize): void {
|
public static initModel(sequelize: Sequelize): void {
|
||||||
User.init({
|
User.init({
|
||||||
@ -20,9 +30,13 @@ export class User extends Model {
|
|||||||
allowNull: false,
|
allowNull: false,
|
||||||
unique: true
|
unique: true
|
||||||
},
|
},
|
||||||
rank: {
|
rankId: {
|
||||||
type: DataTypes.STRING,
|
type: DataTypes.INTEGER,
|
||||||
allowNull: false
|
allowNull: false,
|
||||||
|
references: {
|
||||||
|
model: Rank,
|
||||||
|
key: 'id'
|
||||||
|
}
|
||||||
},
|
},
|
||||||
createdAt: DataTypes.DATE,
|
createdAt: DataTypes.DATE,
|
||||||
updatedAt: DataTypes.DATE
|
updatedAt: DataTypes.DATE
|
||||||
@ -31,4 +45,10 @@ export class User extends Model {
|
|||||||
tableName: 'users'
|
tableName: 'users'
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
declare static associations: {
|
||||||
|
rank: Association<User, Rank>;
|
||||||
|
};
|
||||||
}
|
}
|
@ -1,33 +1,24 @@
|
|||||||
import {CustomClient} from "../classes/CustomClient";
|
import {CustomClient} from "../classes/CustomClient";
|
||||||
import {User} from "../models/User";
|
import {User} from "../models/User";
|
||||||
import {getRandomRank} from "./RandomUtils";
|
import {getRandomRank} from "./RandomUtils";
|
||||||
import {Rank} from "../enums/Rank";
|
|
||||||
import {GuildMember} from "discord.js";
|
import {GuildMember} from "discord.js";
|
||||||
|
import {Rank} from "../models/Rank";
|
||||||
|
|
||||||
export async function addRole(member: GuildMember, user: User, client: CustomClient): Promise<void> {
|
export async function addRole(member: GuildMember, user: User): Promise<void> {
|
||||||
try {
|
try {
|
||||||
let rRoleId = client.config.rRole;
|
let userRank = await Rank.findOne({
|
||||||
let srRoleId = client.config.srRole;
|
where: {
|
||||||
let ssrRoleId = client.config.ssrRole;
|
id: user.rankId
|
||||||
|
|
||||||
if (user.rank === Rank.R) {
|
|
||||||
const rRole = await member.guild.roles.fetch(rRoleId);
|
|
||||||
|
|
||||||
if (rRole) {
|
|
||||||
await member.roles.add(rRole);
|
|
||||||
}
|
}
|
||||||
} else if (user.rank === Rank.SR) {
|
});
|
||||||
const srRole = await member.guild.roles.fetch(srRoleId);
|
|
||||||
|
|
||||||
if (srRole) {
|
if (!userRank) {
|
||||||
await member.roles.add(srRole);
|
return;
|
||||||
}
|
}
|
||||||
} else if (user.rank === Rank.SSR) {
|
|
||||||
const ssrRole = await member.guild.roles.fetch(ssrRoleId);
|
|
||||||
|
|
||||||
if (ssrRole) {
|
const discordRank = await member.guild.roles.fetch(userRank.discordId);
|
||||||
await member.roles.add(ssrRole);
|
if (discordRank) {
|
||||||
}
|
await member.roles.add(userRank.discordId);
|
||||||
}
|
}
|
||||||
} catch (e: Error | any) {
|
} catch (e: Error | any) {
|
||||||
console.log(`Impossible d'ajouter les rôles à ${member.displayName}`);
|
console.log(`Impossible d'ajouter les rôles à ${member.displayName}`);
|
||||||
@ -43,16 +34,25 @@ export async function createAllUsers(client: CustomClient): Promise<void> {
|
|||||||
let user = await User.findOne({
|
let user = await User.findOne({
|
||||||
where: {
|
where: {
|
||||||
discordId: member.id
|
discordId: member.id
|
||||||
|
},
|
||||||
|
include: {
|
||||||
|
model: Rank,
|
||||||
|
as: 'rank'
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
if (!user) {
|
if (!user) {
|
||||||
user = await User.create({
|
user = await User.create({
|
||||||
discordId: member.id,
|
discordId: member.id,
|
||||||
rank: getRandomRank()
|
rankId: (await getRandomRank()).id
|
||||||
|
}, {
|
||||||
|
include: [{
|
||||||
|
model: Rank,
|
||||||
|
as: 'rank'
|
||||||
|
}]
|
||||||
});
|
});
|
||||||
|
|
||||||
await addRole(member, user, client);
|
await addRole(member, user);
|
||||||
|
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
|
@ -1,16 +1,20 @@
|
|||||||
import {Rank} from "../enums/Rank";
|
import {Rank} from "../models/Rank";
|
||||||
import {RankChance} from "../enums/RankChance";
|
|
||||||
|
|
||||||
export function getRandomRank(): Rank {
|
export async function getRandomRank(): Promise<Rank> {
|
||||||
const rand = Math.random() * 100;
|
const rand = Math.random() * 100;
|
||||||
let cumulativeChance = 0;
|
let cumulativeChance = 0;
|
||||||
|
const ranks = await Rank.findAll();
|
||||||
|
|
||||||
for (const rank of Object.values(Rank)) {
|
if (ranks.length === 0) {
|
||||||
cumulativeChance += RankChance[rank as keyof typeof RankChance];
|
throw new Error('No ranks found');
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const rank of ranks) {
|
||||||
|
cumulativeChance += rank.percentage;
|
||||||
if (rand <= cumulativeChance) {
|
if (rand <= cumulativeChance) {
|
||||||
return rank as Rank;
|
return rank as Rank;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return Rank.R;
|
return ranks[0] as Rank;
|
||||||
}
|
}
|
@ -3,7 +3,7 @@ import {CustomClient} from "../base/classes/CustomClient";
|
|||||||
import {Category} from "../base/enums/Category";
|
import {Category} from "../base/enums/Category";
|
||||||
import {EmbedBuilder, GuildMember, PermissionsBitField, SlashCommandUserOption} from "discord.js";
|
import {EmbedBuilder, GuildMember, PermissionsBitField, SlashCommandUserOption} from "discord.js";
|
||||||
import {User} from "../base/models/User";
|
import {User} from "../base/models/User";
|
||||||
import {Rank} from "../base/enums/Rank";
|
import {Rank} from "../base/models/Rank";
|
||||||
import {getRandomRank} from "../base/utils/RandomUtils";
|
import {getRandomRank} from "../base/utils/RandomUtils";
|
||||||
|
|
||||||
export class PingCommand extends Command {
|
export class PingCommand extends Command {
|
||||||
@ -26,19 +26,23 @@ export class PingCommand extends Command {
|
|||||||
|
|
||||||
async execute(interaction: any): Promise<void> {
|
async execute(interaction: any): Promise<void> {
|
||||||
let discordUser = (interaction.options.getMember('user') || interaction.member) as GuildMember;
|
let discordUser = (interaction.options.getMember('user') || interaction.member) as GuildMember;
|
||||||
console.log(discordUser.id);
|
|
||||||
let user = await User.findOne(
|
let user = await User.findOne(
|
||||||
{
|
{
|
||||||
where: {
|
where: {
|
||||||
discordId: discordUser.id
|
discordId: discordUser.id
|
||||||
}
|
},
|
||||||
|
include: [{
|
||||||
|
model: Rank,
|
||||||
|
as: 'rank'
|
||||||
|
}],
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!user) {
|
if (!user) {
|
||||||
user = await User.create({
|
user = await User.create({
|
||||||
discordId: discordUser.id,
|
discordId: discordUser.id,
|
||||||
rank: getRandomRank()
|
rankId: (await getRandomRank()).id
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -46,7 +50,7 @@ export class PingCommand extends Command {
|
|||||||
let embed = new EmbedBuilder()
|
let embed = new EmbedBuilder()
|
||||||
.setTitle(`Rang de ${discordUser.displayName}`)
|
.setTitle(`Rang de ${discordUser.displayName}`)
|
||||||
.setThumbnail(discordUser.displayAvatarURL())
|
.setThumbnail(discordUser.displayAvatarURL())
|
||||||
.setDescription(`Cet utilisateur est de rang : ${Rank[user.rank]}`)
|
.setDescription(`Cet utilisateur est de rang : ${user.rank.name}`)
|
||||||
.setTimestamp(new Date())
|
.setTimestamp(new Date())
|
||||||
.setColor('#0078DE')
|
.setColor('#0078DE')
|
||||||
;
|
;
|
||||||
|
@ -3,6 +3,7 @@ import {CustomClient} from "../../base/classes/CustomClient";
|
|||||||
import {Collection, Events, REST, Routes} from "discord.js";
|
import {Collection, Events, REST, Routes} from "discord.js";
|
||||||
import {Command} from "../../base/classes/Command";
|
import {Command} from "../../base/classes/Command";
|
||||||
import {createAllUsers} from "../../base/utils/GachaUtils";
|
import {createAllUsers} from "../../base/utils/GachaUtils";
|
||||||
|
import {Rank} from "../../base/models/Rank";
|
||||||
export class Ready extends Event {
|
export class Ready extends Event {
|
||||||
constructor(client: CustomClient) {
|
constructor(client: CustomClient) {
|
||||||
super(client, {
|
super(client, {
|
||||||
@ -29,7 +30,11 @@ export class Ready extends Event {
|
|||||||
|
|
||||||
console.log(`${setCommands.length} Commandes mises à jours avec succès !`);
|
console.log(`${setCommands.length} Commandes mises à jours avec succès !`);
|
||||||
|
|
||||||
await createAllUsers(this.client);
|
if (process.env.INIT_DB === 'true') {
|
||||||
|
await this.initDb();
|
||||||
|
} else {
|
||||||
|
await createAllUsers(this.client);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private getJson(commands: Collection<string, Command>): object[] {
|
private getJson(commands: Collection<string, Command>): object[] {
|
||||||
@ -47,4 +52,38 @@ export class Ready extends Event {
|
|||||||
|
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async initDb() {
|
||||||
|
// On commence par vérifier si les rangs existent déjà
|
||||||
|
const ranks = await Rank.findAll();
|
||||||
|
if (ranks.length > 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
await Rank.create({
|
||||||
|
name: '1★',
|
||||||
|
discordId: '1234567890',
|
||||||
|
percentage: 1,
|
||||||
|
});
|
||||||
|
await Rank.create({
|
||||||
|
name: '2★',
|
||||||
|
discordId: '2345678901',
|
||||||
|
percentage: 48,
|
||||||
|
});
|
||||||
|
await Rank.create({
|
||||||
|
name: '3★',
|
||||||
|
discordId: '3456789012',
|
||||||
|
percentage: 41,
|
||||||
|
});
|
||||||
|
await Rank.create({
|
||||||
|
name: '4★',
|
||||||
|
discordId: '4567890123',
|
||||||
|
percentage: 2,
|
||||||
|
});
|
||||||
|
await Rank.create({
|
||||||
|
name: '5★',
|
||||||
|
discordId: '5678901234',
|
||||||
|
percentage: 3,
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
@ -3,8 +3,8 @@ import {CustomClient} from "../../base/classes/CustomClient";
|
|||||||
import {Event} from "../../base/classes/Event";
|
import {Event} from "../../base/classes/Event";
|
||||||
import {User} from "../../base/models/User";
|
import {User} from "../../base/models/User";
|
||||||
import {getRandomRank} from "../../base/utils/RandomUtils";
|
import {getRandomRank} from "../../base/utils/RandomUtils";
|
||||||
import {Rank} from "../../base/enums/Rank";
|
|
||||||
import {addRole} from "../../base/utils/GachaUtils";
|
import {addRole} from "../../base/utils/GachaUtils";
|
||||||
|
import {Rank} from "../../base/models/Rank";
|
||||||
|
|
||||||
export class GuildMemberJoin extends Event {
|
export class GuildMemberJoin extends Event {
|
||||||
constructor(client: CustomClient) {
|
constructor(client: CustomClient) {
|
||||||
@ -26,11 +26,16 @@ export class GuildMemberJoin extends Event {
|
|||||||
if (!user) {
|
if (!user) {
|
||||||
user = await User.create({
|
user = await User.create({
|
||||||
discordId: member.id,
|
discordId: member.id,
|
||||||
rank: getRandomRank()
|
rankId: (await getRandomRank()).id
|
||||||
|
}, {
|
||||||
|
include: [{
|
||||||
|
model: Rank,
|
||||||
|
as: 'rank'
|
||||||
|
}]
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
await addRole(member, user, this.client);
|
await addRole(member, user);
|
||||||
|
|
||||||
const channel = await member.guild.channels.fetch(this.client.config.welcomeChannel);
|
const channel = await member.guild.channels.fetch(this.client.config.welcomeChannel);
|
||||||
|
|
||||||
@ -39,7 +44,7 @@ export class GuildMemberJoin extends Event {
|
|||||||
let embed = new EmbedBuilder()
|
let embed = new EmbedBuilder()
|
||||||
.setTitle(`Bienvenue sur le serveur ${member.displayName} !`)
|
.setTitle(`Bienvenue sur le serveur ${member.displayName} !`)
|
||||||
.setThumbnail(member.displayAvatarURL())
|
.setThumbnail(member.displayAvatarURL())
|
||||||
.setDescription(`Bien joué ! Tu as obtenu le rang : ${Rank[user.rank]}`)
|
.setDescription(`Bien joué ! Tu as obtenu le rang : ${user.rank.name}`)
|
||||||
.setTimestamp(new Date())
|
.setTimestamp(new Date())
|
||||||
.setColor('#0078DE')
|
.setColor('#0078DE')
|
||||||
;
|
;
|
||||||
|
Loading…
Reference in New Issue
Block a user