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