DB access cleanup
This commit is contained in:
parent
877592bb94
commit
9d53d82997
10 changed files with 138 additions and 40 deletions
|
@ -37,7 +37,7 @@ enum LoginResult {
|
||||||
|
|
||||||
function TestLogin(loginInfo:LoginInfo, shared:Shared) {
|
function TestLogin(loginInfo:LoginInfo, shared:Shared) {
|
||||||
return new Promise<LoginResult>(async (resolve, reject) => {
|
return new Promise<LoginResult>(async (resolve, reject) => {
|
||||||
const userDBData = await shared.userInfoRepository.getByUsername(loginInfo.username);
|
const userDBData = await shared.userInfoRepository.selectByUsername(loginInfo.username);
|
||||||
|
|
||||||
// Make sure a user was found in the database
|
// Make sure a user was found in the database
|
||||||
if (userDBData == null) return resolve(LoginResult.INCORRECT);
|
if (userDBData == null) return resolve(LoginResult.INCORRECT);
|
||||||
|
@ -123,7 +123,7 @@ export default async function LoginProcess(req:IncomingMessage, res:ServerRespon
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get information about the user from the database
|
// Get information about the user from the database
|
||||||
const userInfo = await shared.userInfoRepository.getByUsername(loginInfo.username);
|
const userInfo = await shared.userInfoRepository.selectByUsername(loginInfo.username);
|
||||||
if (userInfo == null) {
|
if (userInfo == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import Channel from "../objects/Channel";
|
import Channel from "../objects/Channel";
|
||||||
import User from "../objects/User";
|
import User from "../objects/User";
|
||||||
import { RankingModes } from "../enums/RankingModes";
|
import { RankingMode } from "../enums/RankingMode";
|
||||||
import BaseCommand from "./BaseCommand";
|
import BaseCommand from "./BaseCommand";
|
||||||
|
|
||||||
export default class RankingCommand extends BaseCommand {
|
export default class RankingCommand extends BaseCommand {
|
||||||
|
@ -18,15 +18,15 @@ export default class RankingCommand extends BaseCommand {
|
||||||
|
|
||||||
switch (args[0].toLowerCase()) {
|
switch (args[0].toLowerCase()) {
|
||||||
case "pp":
|
case "pp":
|
||||||
sender.rankingMode = RankingModes.PP;
|
sender.rankingMode = RankingMode.PP;
|
||||||
channel.SendBotMessage("Set ranking mode to pp.");
|
channel.SendBotMessage("Set ranking mode to pp.");
|
||||||
break;
|
break;
|
||||||
case "score":
|
case "score":
|
||||||
sender.rankingMode = RankingModes.RANKED_SCORE;
|
sender.rankingMode = RankingMode.RANKED_SCORE;
|
||||||
channel.SendBotMessage("Set ranking mode to score.");
|
channel.SendBotMessage("Set ranking mode to score.");
|
||||||
break;
|
break;
|
||||||
case "acc":
|
case "acc":
|
||||||
sender.rankingMode = RankingModes.AVG_ACCURACY;
|
sender.rankingMode = RankingMode.AVG_ACCURACY;
|
||||||
channel.SendBotMessage("Set ranking mode to accuracy.");
|
channel.SendBotMessage("Set ranking mode to accuracy.");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
7
server/enums/Mode.ts
Normal file
7
server/enums/Mode.ts
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
export enum Mode {
|
||||||
|
Unknown = -1,
|
||||||
|
Osu,
|
||||||
|
Taiko,
|
||||||
|
Catch,
|
||||||
|
Mania
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
export enum RankingModes {
|
export enum RankingMode {
|
||||||
PP,
|
PP,
|
||||||
RANKED_SCORE,
|
RANKED_SCORE,
|
||||||
AVG_ACCURACY
|
AVG_ACCURACY
|
|
@ -12,6 +12,7 @@ import Bot from "../Bot";
|
||||||
import { ConsoleHelper } from "../../ConsoleHelper";
|
import { ConsoleHelper } from "../../ConsoleHelper";
|
||||||
import UserInfoRepository from "../repos/UserInfoRepository";
|
import UserInfoRepository from "../repos/UserInfoRepository";
|
||||||
import { Permissions } from "../enums/Permissions";
|
import { Permissions } from "../enums/Permissions";
|
||||||
|
import UserModesInfoRepository from "../repos/UserModesInfoRepository";
|
||||||
|
|
||||||
export default class Shared {
|
export default class Shared {
|
||||||
public readonly chatManager:ChatManager;
|
public readonly chatManager:ChatManager;
|
||||||
|
@ -24,6 +25,7 @@ export default class Shared {
|
||||||
public readonly bot:Bot;
|
public readonly bot:Bot;
|
||||||
|
|
||||||
public readonly userInfoRepository:UserInfoRepository;
|
public readonly userInfoRepository:UserInfoRepository;
|
||||||
|
public readonly userModesInfoRepository:UserModesInfoRepository;
|
||||||
|
|
||||||
public constructor() {
|
public constructor() {
|
||||||
if (!existsSync("./config.json")) {
|
if (!existsSync("./config.json")) {
|
||||||
|
@ -53,5 +55,6 @@ export default class Shared {
|
||||||
|
|
||||||
// DB Repos
|
// DB Repos
|
||||||
this.userInfoRepository = new UserInfoRepository(this);
|
this.userInfoRepository = new UserInfoRepository(this);
|
||||||
|
this.userModesInfoRepository = new UserModesInfoRepository(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,5 +1,5 @@
|
||||||
import LatLng from "./LatLng";
|
import LatLng from "./LatLng";
|
||||||
import { RankingModes } from "../enums/RankingModes";
|
import { RankingMode } from "../enums/RankingMode";
|
||||||
import Match from "./Match";
|
import Match from "./Match";
|
||||||
import DataStream from "./DataStream";
|
import DataStream from "./DataStream";
|
||||||
import StatusUpdate from "../packets/StatusUpdate";
|
import StatusUpdate from "../packets/StatusUpdate";
|
||||||
|
@ -9,12 +9,6 @@ import Channel from "./Channel";
|
||||||
import PresenceData from "../interfaces/packetTypes/PresenceData";
|
import PresenceData from "../interfaces/packetTypes/PresenceData";
|
||||||
import { Permissions } from "../enums/Permissions";
|
import { Permissions } from "../enums/Permissions";
|
||||||
|
|
||||||
const rankingModes = [
|
|
||||||
"pp_raw",
|
|
||||||
"ranked_score",
|
|
||||||
"avg_accuracy"
|
|
||||||
];
|
|
||||||
|
|
||||||
export default class User {
|
export default class User {
|
||||||
public shared:Shared;
|
public shared:Shared;
|
||||||
|
|
||||||
|
@ -26,7 +20,7 @@ export default class User {
|
||||||
public queue:Buffer = Buffer.allocUnsafe(0);
|
public queue:Buffer = Buffer.allocUnsafe(0);
|
||||||
|
|
||||||
// Binato data
|
// Binato data
|
||||||
public rankingMode:RankingModes = RankingModes.PP;
|
public rankingMode:RankingMode = RankingMode.PP;
|
||||||
public spectatorStream?:DataStream;
|
public spectatorStream?:DataStream;
|
||||||
public spectatingUser?:User;
|
public spectatingUser?:User;
|
||||||
public permissions:Permissions;
|
public permissions:Permissions;
|
||||||
|
@ -101,26 +95,27 @@ export default class User {
|
||||||
|
|
||||||
// Gets the user's score information from the database and caches it
|
// Gets the user's score information from the database and caches it
|
||||||
async updateUserInfo(forceUpdate:boolean = false) {
|
async updateUserInfo(forceUpdate:boolean = false) {
|
||||||
const userScoreDB = await this.shared.database.querySingle("SELECT * FROM users_modes_info WHERE user_id = ? AND mode_id = ? LIMIT 1", [this.id, this.playMode]);
|
const userScoreDB = await this.shared.userModesInfoRepository.selectByUserIdModeId(this.id, this.playMode);
|
||||||
const mappedRankingMode = rankingModes[this.rankingMode];
|
const userRank = await this.shared.userModesInfoRepository.selectRankByIdModeIdRankingMode(this.id, this.playMode, this.rankingMode);
|
||||||
const userRankDB = await this.shared.database.query(`SELECT user_id, ${mappedRankingMode} FROM users_modes_info WHERE mode_id = ? ORDER BY ${mappedRankingMode} DESC`, [this.playMode]);
|
|
||||||
|
|
||||||
if (userScoreDB == null || userRankDB == null) throw "fuck";
|
if (userScoreDB == null || userRank == null) throw "fuck";
|
||||||
|
|
||||||
|
this.rank = userRank;
|
||||||
|
|
||||||
// Handle "if we should update" checks for each rankingMode
|
// Handle "if we should update" checks for each rankingMode
|
||||||
let userScoreUpdate = false;
|
let userScoreUpdate = false;
|
||||||
switch (this.rankingMode) {
|
switch (this.rankingMode) {
|
||||||
case RankingModes.PP:
|
case RankingMode.PP:
|
||||||
if (this.pp != userScoreDB.pp_raw)
|
if (this.pp != userScoreDB.pp_raw)
|
||||||
userScoreUpdate = true;
|
userScoreUpdate = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RankingModes.RANKED_SCORE:
|
case RankingMode.RANKED_SCORE:
|
||||||
if (this.rankedScore != userScoreDB.ranked_score)
|
if (this.rankedScore != userScoreDB.ranked_score)
|
||||||
userScoreUpdate = true;
|
userScoreUpdate = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RankingModes.AVG_ACCURACY:
|
case RankingMode.AVG_ACCURACY:
|
||||||
if (this.accuracy != userScoreDB.avg_accuracy)
|
if (this.accuracy != userScoreDB.avg_accuracy)
|
||||||
userScoreUpdate = true;
|
userScoreUpdate = true;
|
||||||
break;
|
break;
|
||||||
|
@ -131,14 +126,6 @@ export default class User {
|
||||||
this.accuracy = userScoreDB.avg_accuracy;
|
this.accuracy = userScoreDB.avg_accuracy;
|
||||||
this.playCount = userScoreDB.playcount;
|
this.playCount = userScoreDB.playcount;
|
||||||
|
|
||||||
// Fetch rank
|
|
||||||
for (let i = 0; i < userRankDB.length; i++) {
|
|
||||||
if (userRankDB[i]["user_id"] == this.id) {
|
|
||||||
this.rank = i + 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set PP to none if ranking mode is not PP
|
// Set PP to none if ranking mode is not PP
|
||||||
if (this.rankingMode == 0) this.pp = userScoreDB.pp_raw;
|
if (this.rankingMode == 0) this.pp = userScoreDB.pp_raw;
|
||||||
else this.pp = 0;
|
else this.pp = 0;
|
||||||
|
|
24
server/objects/database/UserModeInfo.ts
Normal file
24
server/objects/database/UserModeInfo.ts
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
import { Mode } from "../../enums/Mode";
|
||||||
|
|
||||||
|
export default class UserModeInfo {
|
||||||
|
n:number = Number.MIN_VALUE;
|
||||||
|
user_id:number = Number.MIN_VALUE;
|
||||||
|
mode_id:Mode = Mode.Unknown;
|
||||||
|
count300:number = Number.MIN_VALUE;
|
||||||
|
count100:number = Number.MIN_VALUE;
|
||||||
|
count50:number = Number.MIN_VALUE;
|
||||||
|
countmiss:number = Number.MIN_VALUE;
|
||||||
|
playcount:number = Number.MIN_VALUE;
|
||||||
|
total_score:number = Number.MIN_VALUE;
|
||||||
|
ranked_score:number = Number.MIN_VALUE;
|
||||||
|
pp_rank:number = Number.MIN_VALUE;
|
||||||
|
pp_raw:number = Number.MIN_VALUE;
|
||||||
|
count_rank_ss:number = Number.MIN_VALUE;
|
||||||
|
count_rank_s:number = Number.MIN_VALUE;
|
||||||
|
count_rank_a:number = Number.MIN_VALUE;
|
||||||
|
pp_country_rank:number = Number.MIN_VALUE;
|
||||||
|
playtime:number = Number.MIN_VALUE;
|
||||||
|
avg_accuracy:number = Number.MIN_VALUE;
|
||||||
|
level:number = Number.MIN_VALUE;
|
||||||
|
is_deleted:boolean = false;
|
||||||
|
}
|
|
@ -1,10 +1,13 @@
|
||||||
import Shared from "../objects/Shared";
|
import Shared from "../objects/Shared";
|
||||||
import { RankingModes } from "../enums/RankingModes";
|
import { RankingMode } from "../enums/RankingMode";
|
||||||
import User from "../objects/User";
|
import User from "../objects/User";
|
||||||
import osu from "../../osuTyping";
|
import osu from "../../osuTyping";
|
||||||
|
|
||||||
export default function StatusUpdate(arg0:User | Shared, id:number) {
|
export default function StatusUpdate(arg0:User | Shared, id:number) {
|
||||||
if (id == 3) return; // Ignore Bot
|
// Ignore Bot
|
||||||
|
if (id == 3) {
|
||||||
|
return Buffer.allocUnsafe(0);
|
||||||
|
}
|
||||||
|
|
||||||
// Create new osu packet writer
|
// Create new osu packet writer
|
||||||
const osuPacketWriter = osu.Bancho.Writer();
|
const osuPacketWriter = osu.Bancho.Writer();
|
||||||
|
@ -18,7 +21,9 @@ export default function StatusUpdate(arg0:User | Shared, id:number) {
|
||||||
// Get user's class
|
// Get user's class
|
||||||
const userData = shared.users.getById(id);
|
const userData = shared.users.getById(id);
|
||||||
|
|
||||||
if (userData == null) return;
|
if (userData == null) {
|
||||||
|
return Buffer.allocUnsafe(0);
|
||||||
|
}
|
||||||
|
|
||||||
osuPacketWriter.HandleOsuUpdate({
|
osuPacketWriter.HandleOsuUpdate({
|
||||||
userId: userData.id,
|
userId: userData.id,
|
||||||
|
@ -33,7 +38,7 @@ export default function StatusUpdate(arg0:User | Shared, id:number) {
|
||||||
playCount: userData.playCount,
|
playCount: userData.playCount,
|
||||||
totalScore: userData.totalScore,
|
totalScore: userData.totalScore,
|
||||||
rank: userData.rank,
|
rank: userData.rank,
|
||||||
performance: (userData.rankingMode == RankingModes.PP ? userData.pp : 0)
|
performance: (userData.rankingMode == RankingMode.PP ? userData.pp : 0)
|
||||||
});
|
});
|
||||||
|
|
||||||
// Send data to user's queue
|
// Send data to user's queue
|
||||||
|
|
|
@ -9,11 +9,11 @@ export default class UserInfoRepository {
|
||||||
this.database = shared.database;
|
this.database = shared.database;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async getById(id:number) {
|
public async selectById(id:number) {
|
||||||
const query = await this.database.query("SELECT * FROM users_info WHERE id = ? AND is_deleted = 0 LIMIT 1", [id]);
|
const query = await this.database.query("CALL SelectUserInfoById(?)", [id]);
|
||||||
if (query != null) {
|
if (query != null) {
|
||||||
const userInfo = new UserInfo();
|
const userInfo = new UserInfo();
|
||||||
populateUserInfoFromRowDataPacket(userInfo, query[0]);
|
populateUserInfoFromRowDataPacket(userInfo, query[0][0]);
|
||||||
|
|
||||||
return userInfo;
|
return userInfo;
|
||||||
}
|
}
|
||||||
|
@ -21,11 +21,11 @@ export default class UserInfoRepository {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async getByUsername(username:string) {
|
public async selectByUsername(username:string) {
|
||||||
const query = await this.database.query("SELECT * FROM users_info WHERE username = ? AND is_deleted = 0 LIMIT 1", [username]);
|
const query = await this.database.query("CALL SelectUserInfoByUsername(?)", [username]);
|
||||||
if (query != null) {
|
if (query != null) {
|
||||||
const userInfo = new UserInfo();
|
const userInfo = new UserInfo();
|
||||||
populateUserInfoFromRowDataPacket(userInfo, query[0]);
|
populateUserInfoFromRowDataPacket(userInfo, query[0][0]);
|
||||||
|
|
||||||
return userInfo;
|
return userInfo;
|
||||||
}
|
}
|
||||||
|
|
72
server/repos/UserModesInfoRepository.ts
Normal file
72
server/repos/UserModesInfoRepository.ts
Normal file
|
@ -0,0 +1,72 @@
|
||||||
|
import { RowDataPacket } from "mysql2";
|
||||||
|
import Database from "../objects/Database";
|
||||||
|
import Shared from "../objects/Shared";
|
||||||
|
import UserModeInfo from "../objects/database/UserModeInfo";
|
||||||
|
import { Mode } from "fs";
|
||||||
|
import { RankingMode } from "../enums/RankingMode";
|
||||||
|
|
||||||
|
export default class UserModesInfoRepository {
|
||||||
|
private database:Database;
|
||||||
|
public constructor(shared:Shared) {
|
||||||
|
this.database = shared.database;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async selectByUserIdModeId(id:number, mode:Mode) {
|
||||||
|
const query = await this.database.query("CALL SelectUserModesInfoByUserIdModeId(?,?)", [id, mode]);
|
||||||
|
if (query != null) {
|
||||||
|
const userModeInfo = new UserModeInfo();
|
||||||
|
populateUserModeInfoFromRowDataPacket(userModeInfo, query[0][0]);
|
||||||
|
|
||||||
|
return userModeInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async selectRankByIdModeIdRankingMode(id:number, mode:Mode, rankingMode:RankingMode) : Promise<number | null> {
|
||||||
|
let query:RowDataPacket[] | undefined;
|
||||||
|
switch (rankingMode) {
|
||||||
|
case RankingMode.RANKED_SCORE:
|
||||||
|
query = await this.database.query("CALL SelectUserScoreRankByIdModeId(?,?)", [id, mode]);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RankingMode.AVG_ACCURACY:
|
||||||
|
query = await this.database.query("CALL SelectUserAccRankByIdModeId(?,?)", [id, mode]);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RankingMode.PP:
|
||||||
|
default:
|
||||||
|
query = await this.database.query("CALL SelectUserPPRankByIdModeId(?,?)", [id, mode]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (query != null && query.length != 0) {
|
||||||
|
return query[0][0].rank;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function populateUserModeInfoFromRowDataPacket(userModeInfo:UserModeInfo, rowDataPacket:RowDataPacket) {
|
||||||
|
userModeInfo.n = rowDataPacket["n"];
|
||||||
|
userModeInfo.user_id = rowDataPacket["user_id"];
|
||||||
|
userModeInfo.mode_id = rowDataPacket["mode_id"];
|
||||||
|
userModeInfo.count300 = rowDataPacket["count300"];
|
||||||
|
userModeInfo.count100 = rowDataPacket["count100"];
|
||||||
|
userModeInfo.count50 = rowDataPacket["count50"];
|
||||||
|
userModeInfo.countmiss = rowDataPacket["countmiss"];
|
||||||
|
userModeInfo.playcount = rowDataPacket["playcount"];
|
||||||
|
userModeInfo.total_score = rowDataPacket["total_score"];
|
||||||
|
userModeInfo.ranked_score = rowDataPacket["ranked_score"];
|
||||||
|
userModeInfo.pp_rank = rowDataPacket["pp_rank"];
|
||||||
|
userModeInfo.pp_raw = rowDataPacket["pp_raw"];
|
||||||
|
userModeInfo.count_rank_ss = rowDataPacket["count_rank_ss"];
|
||||||
|
userModeInfo.count_rank_s = rowDataPacket["count_rank_s"];
|
||||||
|
userModeInfo.count_rank_a = rowDataPacket["count_rank_a"];
|
||||||
|
userModeInfo.pp_country_rank = rowDataPacket["pp_country_rank"];
|
||||||
|
userModeInfo.playtime = rowDataPacket["playtime"];
|
||||||
|
userModeInfo.avg_accuracy = rowDataPacket["avg_accuracy"];
|
||||||
|
userModeInfo.level = rowDataPacket["level"];
|
||||||
|
userModeInfo.is_deleted = rowDataPacket["is_deleted"];
|
||||||
|
}
|
Loading…
Reference in a new issue