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) {
|
||||
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
|
||||
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
|
||||
const userInfo = await shared.userInfoRepository.getByUsername(loginInfo.username);
|
||||
const userInfo = await shared.userInfoRepository.selectByUsername(loginInfo.username);
|
||||
if (userInfo == null) {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import Channel from "../objects/Channel";
|
||||
import User from "../objects/User";
|
||||
import { RankingModes } from "../enums/RankingModes";
|
||||
import { RankingMode } from "../enums/RankingMode";
|
||||
import BaseCommand from "./BaseCommand";
|
||||
|
||||
export default class RankingCommand extends BaseCommand {
|
||||
|
@ -18,15 +18,15 @@ export default class RankingCommand extends BaseCommand {
|
|||
|
||||
switch (args[0].toLowerCase()) {
|
||||
case "pp":
|
||||
sender.rankingMode = RankingModes.PP;
|
||||
sender.rankingMode = RankingMode.PP;
|
||||
channel.SendBotMessage("Set ranking mode to pp.");
|
||||
break;
|
||||
case "score":
|
||||
sender.rankingMode = RankingModes.RANKED_SCORE;
|
||||
sender.rankingMode = RankingMode.RANKED_SCORE;
|
||||
channel.SendBotMessage("Set ranking mode to score.");
|
||||
break;
|
||||
case "acc":
|
||||
sender.rankingMode = RankingModes.AVG_ACCURACY;
|
||||
sender.rankingMode = RankingMode.AVG_ACCURACY;
|
||||
channel.SendBotMessage("Set ranking mode to accuracy.");
|
||||
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,
|
||||
RANKED_SCORE,
|
||||
AVG_ACCURACY
|
|
@ -12,6 +12,7 @@ import Bot from "../Bot";
|
|||
import { ConsoleHelper } from "../../ConsoleHelper";
|
||||
import UserInfoRepository from "../repos/UserInfoRepository";
|
||||
import { Permissions } from "../enums/Permissions";
|
||||
import UserModesInfoRepository from "../repos/UserModesInfoRepository";
|
||||
|
||||
export default class Shared {
|
||||
public readonly chatManager:ChatManager;
|
||||
|
@ -24,6 +25,7 @@ export default class Shared {
|
|||
public readonly bot:Bot;
|
||||
|
||||
public readonly userInfoRepository:UserInfoRepository;
|
||||
public readonly userModesInfoRepository:UserModesInfoRepository;
|
||||
|
||||
public constructor() {
|
||||
if (!existsSync("./config.json")) {
|
||||
|
@ -53,5 +55,6 @@ export default class Shared {
|
|||
|
||||
// DB Repos
|
||||
this.userInfoRepository = new UserInfoRepository(this);
|
||||
this.userModesInfoRepository = new UserModesInfoRepository(this);
|
||||
}
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
import LatLng from "./LatLng";
|
||||
import { RankingModes } from "../enums/RankingModes";
|
||||
import { RankingMode } from "../enums/RankingMode";
|
||||
import Match from "./Match";
|
||||
import DataStream from "./DataStream";
|
||||
import StatusUpdate from "../packets/StatusUpdate";
|
||||
|
@ -9,12 +9,6 @@ import Channel from "./Channel";
|
|||
import PresenceData from "../interfaces/packetTypes/PresenceData";
|
||||
import { Permissions } from "../enums/Permissions";
|
||||
|
||||
const rankingModes = [
|
||||
"pp_raw",
|
||||
"ranked_score",
|
||||
"avg_accuracy"
|
||||
];
|
||||
|
||||
export default class User {
|
||||
public shared:Shared;
|
||||
|
||||
|
@ -26,7 +20,7 @@ export default class User {
|
|||
public queue:Buffer = Buffer.allocUnsafe(0);
|
||||
|
||||
// Binato data
|
||||
public rankingMode:RankingModes = RankingModes.PP;
|
||||
public rankingMode:RankingMode = RankingMode.PP;
|
||||
public spectatorStream?:DataStream;
|
||||
public spectatingUser?:User;
|
||||
public permissions:Permissions;
|
||||
|
@ -101,26 +95,27 @@ export default class User {
|
|||
|
||||
// Gets the user's score information from the database and caches it
|
||||
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 mappedRankingMode = rankingModes[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]);
|
||||
const userScoreDB = await this.shared.userModesInfoRepository.selectByUserIdModeId(this.id, this.playMode);
|
||||
const userRank = await this.shared.userModesInfoRepository.selectRankByIdModeIdRankingMode(this.id, this.playMode, this.rankingMode);
|
||||
|
||||
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
|
||||
let userScoreUpdate = false;
|
||||
switch (this.rankingMode) {
|
||||
case RankingModes.PP:
|
||||
case RankingMode.PP:
|
||||
if (this.pp != userScoreDB.pp_raw)
|
||||
userScoreUpdate = true;
|
||||
break;
|
||||
|
||||
case RankingModes.RANKED_SCORE:
|
||||
case RankingMode.RANKED_SCORE:
|
||||
if (this.rankedScore != userScoreDB.ranked_score)
|
||||
userScoreUpdate = true;
|
||||
break;
|
||||
|
||||
case RankingModes.AVG_ACCURACY:
|
||||
case RankingMode.AVG_ACCURACY:
|
||||
if (this.accuracy != userScoreDB.avg_accuracy)
|
||||
userScoreUpdate = true;
|
||||
break;
|
||||
|
@ -131,14 +126,6 @@ export default class User {
|
|||
this.accuracy = userScoreDB.avg_accuracy;
|
||||
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
|
||||
if (this.rankingMode == 0) this.pp = userScoreDB.pp_raw;
|
||||
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 { RankingModes } from "../enums/RankingModes";
|
||||
import { RankingMode } from "../enums/RankingMode";
|
||||
import User from "../objects/User";
|
||||
import osu from "../../osuTyping";
|
||||
|
||||
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
|
||||
const osuPacketWriter = osu.Bancho.Writer();
|
||||
|
@ -18,7 +21,9 @@ export default function StatusUpdate(arg0:User | Shared, id:number) {
|
|||
// Get user's class
|
||||
const userData = shared.users.getById(id);
|
||||
|
||||
if (userData == null) return;
|
||||
if (userData == null) {
|
||||
return Buffer.allocUnsafe(0);
|
||||
}
|
||||
|
||||
osuPacketWriter.HandleOsuUpdate({
|
||||
userId: userData.id,
|
||||
|
@ -33,7 +38,7 @@ export default function StatusUpdate(arg0:User | Shared, id:number) {
|
|||
playCount: userData.playCount,
|
||||
totalScore: userData.totalScore,
|
||||
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
|
||||
|
|
|
@ -9,11 +9,11 @@ export default class UserInfoRepository {
|
|||
this.database = shared.database;
|
||||
}
|
||||
|
||||
public async getById(id:number) {
|
||||
const query = await this.database.query("SELECT * FROM users_info WHERE id = ? AND is_deleted = 0 LIMIT 1", [id]);
|
||||
public async selectById(id:number) {
|
||||
const query = await this.database.query("CALL SelectUserInfoById(?)", [id]);
|
||||
if (query != null) {
|
||||
const userInfo = new UserInfo();
|
||||
populateUserInfoFromRowDataPacket(userInfo, query[0]);
|
||||
populateUserInfoFromRowDataPacket(userInfo, query[0][0]);
|
||||
|
||||
return userInfo;
|
||||
}
|
||||
|
@ -21,11 +21,11 @@ export default class UserInfoRepository {
|
|||
return null;
|
||||
}
|
||||
|
||||
public async getByUsername(username:string) {
|
||||
const query = await this.database.query("SELECT * FROM users_info WHERE username = ? AND is_deleted = 0 LIMIT 1", [username]);
|
||||
public async selectByUsername(username:string) {
|
||||
const query = await this.database.query("CALL SelectUserInfoByUsername(?)", [username]);
|
||||
if (query != null) {
|
||||
const userInfo = new UserInfo();
|
||||
populateUserInfoFromRowDataPacket(userInfo, query[0]);
|
||||
populateUserInfoFromRowDataPacket(userInfo, query[0][0]);
|
||||
|
||||
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