Code quality improvements.

This commit is contained in:
Holly Stubbs 2023-10-04 12:28:47 +01:00
parent 93da399fa5
commit 686e6001b2
12 changed files with 316 additions and 303 deletions

View file

@ -81,8 +81,6 @@ setInterval(() => {
}
}, 10000);
const EMPTY_BUFFER = Buffer.alloc(0);
export default async function HandleRequest(req:IncomingMessage, res:ServerResponse, packet:Buffer) {
// Get the client's token string and request data
const requestTokenString = typeof(req.headers["osu-token"]) === "string" ? req.headers["osu-token"] : undefined;
@ -94,7 +92,7 @@ export default async function HandleRequest(req:IncomingMessage, res:ServerRespo
await LoginProcess(req, res, packet, shared);
shared.database.query("UPDATE osu_info SET value = ? WHERE name = 'online_now'", [shared.users.getLength() - 1]);
} else {
let responseData = EMPTY_BUFFER;
let responseData = Buffer.allocUnsafe(0);
// Client has a token, let's see what they want.
try {

View file

@ -1,269 +1,261 @@
enum CountryCodes {
LV = 132,
AD = 3,
LT = 130,
KM = 116,
QA = 182,
VA = 0,
PK = 173,
KI = 115,
SS = 0,
KH = 114,
NZ = 166,
TO = 215,
KZ = 122,
BW = 35,
GA = 76,
AX = 247,
GE = 79,
UA = 222,
CR = 50,
AE = 0,
NE = 157,
ZA = 240,
SK = 196,
BV = 34,
SH = 0,
PT = 179,
SC = 189,
CO = 49,
GP = 86,
GY = 93,
CM = 47,
TJ = 211,
AF = 5,
IE = 101,
AL = 8,
BG = 24,
JO = 110,
MU = 149,
PM = 0,
LA = 0,
IO = 104,
KY = 121,
SA = 187,
KN = 0,
OM = 167,
CY = 54,
BQ = 0,
BT = 33,
WS = 236,
ES = 67,
LR = 128,
RW = 186,
AQ = 12,
PW = 180,
JE = 250,
TN = 214,
ZW = 243,
JP = 111,
BB = 20,
VN = 233,
HN = 96,
KP = 0,
WF = 235,
EC = 62,
HU = 99,
GF = 80,
GQ = 87,
TW = 220,
MC = 135,
BE = 22,
PN = 176,
SZ = 205,
CZ = 55,
LY = 0,
IN = 103,
FM = 0,
PY = 181,
PH = 172,
MN = 142,
GG = 248,
CC = 39,
ME = 242,
DO = 60,
KR = 0,
PL = 174,
MT = 148,
MM = 141,
AW = 17,
MV = 150,
BD = 21,
NR = 164,
AT = 15,
GW = 92,
FR = 74,
LI = 126,
CF = 41,
DZ = 61,
MA = 134,
VG = 0,
NC = 156,
IQ = 105,
BN = 0,
BF = 23,
BO = 30,
GB = 77,
CU = 51,
LU = 131,
YT = 238,
NO = 162,
SM = 198,
GL = 83,
IS = 107,
AO = 11,
MH = 138,
SE = 191,
ZM = 241,
FJ = 70,
SL = 197,
CH = 43,
RU = 0,
CW = 0,
CX = 53,
TF = 208,
NL = 161,
AU = 16,
FI = 69,
MS = 147,
GH = 81,
BY = 36,
IL = 102,
VC = 0,
NG = 159,
HT = 98,
LS = 129,
MR = 146,
YE = 237,
MP = 144,
SX = 0,
RE = 183,
RO = 184,
NP = 163,
CG = 0,
FO = 73,
CI = 0,
TH = 210,
HK = 94,
TK = 212,
XK = 0,
DM = 59,
LC = 0,
ID = 100,
MG = 137,
JM = 109,
IT = 108,
CA = 38,
TZ = 221,
GI = 82,
KG = 113,
NU = 165,
TV = 219,
LB = 124,
SY = 0,
PR = 177,
NI = 160,
KE = 112,
MO = 0,
SR = 201,
VI = 0,
SV = 203,
HM = 0,
CD = 0,
BI = 26,
BM = 28,
MW = 151,
TM = 213,
GT = 90,
AG = 0,
UM = 0,
US = 225,
AR = 13,
DJ = 57,
KW = 120,
MY = 153,
FK = 71,
EG = 64,
BA = 0,
CN = 48,
GN = 85,
PS = 178,
SO = 200,
IM = 249,
GS = 0,
BR = 31,
GM = 84,
PF = 170,
PA = 168,
PG = 171,
BH = 25,
TG = 209,
GU = 91,
CK = 45,
MF = 252,
VE = 230,
CL = 46,
TR = 217,
UG = 223,
GD = 78,
TT = 218,
TL = 0,
MD = 0,
MK = 0,
ST = 202,
CV = 52,
MQ = 145,
GR = 88,
HR = 97,
BZ = 37,
UZ = 227,
DK = 58,
SN = 199,
ET = 68,
VU = 234,
ER = 66,
BJ = 27,
LK = 127,
NA = 155,
AS = 14,
SG = 192,
PE = 169,
IR = 0,
MX = 152,
TD = 207,
AZ = 18,
AM = 9,
BL = 0,
SJ = 195,
SB = 188,
NF = 158,
RS = 239,
DE = 56,
EH = 65,
EE = 63,
SD = 190,
ML = 140,
TC = 206,
MZ = 154,
BS = 32,
UY = 226,
SI = 194,
AI = 7
}
const countryCodes:{ [id: string]: number } = {
"LV": 132,
"AD": 3,
"LT": 130,
"KM": 116,
"QA": 182,
"VA": 0,
"PK": 173,
"KI": 115,
"SS": 0,
"KH": 114,
"NZ": 166,
"TO": 215,
"KZ": 122,
"BW": 35,
"GA": 76,
"AX": 247,
"GE": 79,
"UA": 222,
"CR": 50,
"AE": 0,
"NE": 157,
"ZA": 240,
"SK": 196,
"BV": 34,
"SH": 0,
"PT": 179,
"SC": 189,
"CO": 49,
"GP": 86,
"GY": 93,
"CM": 47,
"TJ": 211,
"AF": 5,
"IE": 101,
"AL": 8,
"BG": 24,
"JO": 110,
"MU": 149,
"PM": 0,
"LA": 0,
"IO": 104,
"KY": 121,
"SA": 187,
"KN": 0,
"OM": 167,
"CY": 54,
"BQ": 0,
"BT": 33,
"WS": 236,
"ES": 67,
"LR": 128,
"RW": 186,
"AQ": 12,
"PW": 180,
"JE": 250,
"TN": 214,
"ZW": 243,
"JP": 111,
"BB": 20,
"VN": 233,
"HN": 96,
"KP": 0,
"WF": 235,
"EC": 62,
"HU": 99,
"GF": 80,
"GQ": 87,
"TW": 220,
"MC": 135,
"BE": 22,
"PN": 176,
"SZ": 205,
"CZ": 55,
"LY": 0,
"IN": 103,
"FM": 0,
"PY": 181,
"PH": 172,
"MN": 142,
"GG": 248,
"CC": 39,
"ME": 242,
"DO": 60,
"KR": 0,
"PL": 174,
"MT": 148,
"MM": 141,
"AW": 17,
"MV": 150,
"BD": 21,
"NR": 164,
"AT": 15,
"GW": 92,
"FR": 74,
"LI": 126,
"CF": 41,
"DZ": 61,
"MA": 134,
"VG": 0,
"NC": 156,
"IQ": 105,
"BN": 0,
"BF": 23,
"BO": 30,
"GB": 77,
"CU": 51,
"LU": 131,
"YT": 238,
"NO": 162,
"SM": 198,
"GL": 83,
"IS": 107,
"AO": 11,
"MH": 138,
"SE": 191,
"ZM": 241,
"FJ": 70,
"SL": 197,
"CH": 43,
"RU": 0,
"CW": 0,
"CX": 53,
"TF": 208,
"NL": 161,
"AU": 16,
"FI": 69,
"MS": 147,
"GH": 81,
"BY": 36,
"IL": 102,
"VC": 0,
"NG": 159,
"HT": 98,
"LS": 129,
"MR": 146,
"YE": 237,
"MP": 144,
"SX": 0,
"RE": 183,
"RO": 184,
"NP": 163,
"CG": 0,
"FO": 73,
"CI": 0,
"TH": 210,
"HK": 94,
"TK": 212,
"XK": 0,
"DM": 59,
"LC": 0,
"ID": 100,
"MG": 137,
"JM": 109,
"IT": 108,
"CA": 38,
"TZ": 221,
"GI": 82,
"KG": 113,
"NU": 165,
"TV": 219,
"LB": 124,
"SY": 0,
"PR": 177,
"NI": 160,
"KE": 112,
"MO": 0,
"SR": 201,
"VI": 0,
"SV": 203,
"HM": 0,
"CD": 0,
"BI": 26,
"BM": 28,
"MW": 151,
"TM": 213,
"GT": 90,
"AG": 0,
"UM": 0,
"US": 225,
"AR": 13,
"DJ": 57,
"KW": 120,
"MY": 153,
"FK": 71,
"EG": 64,
"BA": 0,
"CN": 48,
"GN": 85,
"PS": 178,
"SO": 200,
"IM": 249,
"GS": 0,
"BR": 31,
"GM": 84,
"PF": 170,
"PA": 168,
"PG": 171,
"BH": 25,
"TG": 209,
"GU": 91,
"CK": 45,
"MF": 252,
"VE": 230,
"CL": 46,
"TR": 217,
"UG": 223,
"GD": 78,
"TT": 218,
"TL": 0,
"MD": 0,
"MK": 0,
"ST": 202,
"CV": 52,
"MQ": 145,
"GR": 88,
"HR": 97,
"BZ": 37,
"UZ": 227,
"DK": 58,
"SN": 199,
"ET": 68,
"VU": 234,
"ER": 66,
"BJ": 27,
"LK": 127,
"NA": 155,
"AS": 14,
"SG": 192,
"PE": 169,
"IR": 0,
"MX": 152,
"TD": 207,
"AZ": 18,
"AM": 9,
"BL": 0,
"SJ": 195,
"SB": 188,
"NF": 158,
"RS": 239,
"DE": 56,
"EH": 65,
"EE": 63,
"SD": 190,
"ML": 140,
"TC": 206,
"MZ": 154,
"BS": 32,
"UY": 226,
"SI": 194,
"AI": 7
};
const keys = Object.keys(CountryCodes);
const values = Object.values(CountryCodes);
export default function getCountryID(code:string) : number {
// Get id of a country from a 2 char code
const upperCode:string = code.toUpperCase();
if (upperCode in CountryCodes) {
const code = values[keys.indexOf(upperCode)];
if (typeof(code) === "string") {
return 0;
}
return code;
// Get id of a country from a 2 char code
export function getCountryID(code:string) : number {
const upperCode = code.toUpperCase();
if (upperCode in countryCodes) {
return countryCodes[upperCode];
}
return 0;

View file

@ -1,6 +1,6 @@
import { ConsoleHelper } from "../ConsoleHelper";
import fetch from "node-fetch";
import getCountryID from "./Country";
import { getCountryID } from "./Country";
import { generateSession } from "./Util";
import LatLng from "./objects/LatLng";
import LoginInfo from "./objects/LoginInfo";
@ -14,6 +14,7 @@ import Shared from "./objects/Shared";
import osu from "../osuTyping";
import IpZxqResponse from "./interfaces/IpZxqResponse";
import { IncomingMessage, ServerResponse } from "http";
import UserInfo from "./objects/database/UserInfo";
const { decrypt: aesDecrypt } = require("aes256");
const incorrectLoginResponse:Buffer = osu.Bancho.Writer().LoginReply(-1).toBuffer;
@ -36,7 +37,7 @@ enum LoginResult {
function TestLogin(loginInfo:LoginInfo, shared:Shared) {
return new Promise<LoginResult>(async (resolve, reject) => {
const userDBData:any = await shared.database.query("SELECT * FROM users_info WHERE username = ? LIMIT 1", [loginInfo.username]);
const userDBData:UserInfo = await shared.database.query("SELECT * FROM users_info WHERE username = ? LIMIT 1", [loginInfo.username]);
// Make sure a user was found in the database
if (userDBData == null) return resolve(LoginResult.INCORRECT);
@ -122,7 +123,7 @@ export default async function LoginProcess(req:IncomingMessage, res:ServerRespon
}
// Get information about the user from the database
const userDB = await shared.database.query("SELECT id FROM users_info WHERE username = ? LIMIT 1", [loginInfo.username]);
const userId:number = (await shared.database.query("SELECT id FROM users_info WHERE username = ? LIMIT 1", [loginInfo.username])).id;
// Create a token for the client
const newClientToken:string = await generateSession();
@ -135,7 +136,7 @@ export default async function LoginProcess(req:IncomingMessage, res:ServerRespon
}
// Retreive the newly created user
newUser = shared.users.add(newClientToken, new User(userDB.id, loginInfo.username, newClientToken, shared));
newUser = shared.users.add(newClientToken, new User(userId, loginInfo.username, newClientToken, shared));
// Set tourney client flag
newUser.isTourneyUser = isTourneyClient;
newUser.location = userLocation;
@ -203,7 +204,7 @@ export default async function LoginProcess(req:IncomingMessage, res:ServerRespon
const writerBuffer:Buffer = osuPacketWriter.toBuffer;
if (newUser === undefined) {
res.writeHead(200, {
"cho-token": "no",
"cho-token": "no", // NOTE: You have to specify a token even if it's an incorrect login for some reason.
"Connection": "keep-alive",
"Keep-Alive": "timeout=5, max=100"
});

View file

@ -14,6 +14,6 @@ export default class BaseCommand implements ICommand {
}
public exec(channel:Channel, sender:User, args:Array<string>) {
channel.SendBotMessage(`Sorry ${sender.username}! This command has no functionality yet. Args: ["${args.join('", "')}"]`);
}
}

View file

@ -6,8 +6,7 @@ import BaseCommand from "./BaseCommand";
export default class MultiplayerCommands extends BaseCommand {
public readonly helpText:string = `Multiplayer Subcommands:
!mp start - Starts a multiplayer match with a delay (optional)
!mp abort - Aborts the currently running round / countdown
!mp obr - Toggles Battle Royale mode`;
!mp abort - Aborts the currently running round / countdown`;
public readonly helpDescription:string = "Command for use in multiplayer matches.";
public readonly helpArguments:Array<string> = ["subCommand"];
@ -36,9 +35,6 @@ export default class MultiplayerCommands extends BaseCommand {
case "abort":
return mpAbort(channel, sender.match);
case "obr":
return mpOBR(channel, sender.match);
}
}
}
@ -89,8 +85,4 @@ function mpAbort(channel:Channel, match:Match) {
match.finishMatch();
channel.SendBotMessage("Aborted current round");
}
}
function mpOBR(channel:Channel, match:Match) {
}

View file

@ -1,5 +1,7 @@
import MatchData from "./MatchData"
import MatchScoreData from "./MatchScoreData"
import MessageData from "./MessageData"
import StatusUpdateData from "./StatusUpdateData"
export default interface OsuPacketWriter {
// Functions
@ -9,7 +11,7 @@ export default interface OsuPacketWriter {
Ping() : OsuPacketWriter,
HandleIrcChangeUsername(data:any) : OsuPacketWriter,
HandleIrcQuit() : OsuPacketWriter,
HandleOsuUpdate(data:any) : OsuPacketWriter,
HandleOsuUpdate(data:StatusUpdateData) : OsuPacketWriter,
HandleUserQuit(data:any) : OsuPacketWriter,
SpectatorJoined(data:any) : OsuPacketWriter,
SpectatorLeft(data:any) : OsuPacketWriter,
@ -19,14 +21,14 @@ export default interface OsuPacketWriter {
GetAttention() : OsuPacketWriter,
Announce(data:string) : OsuPacketWriter,
MatchUpdate(data:MatchData) : OsuPacketWriter,
MatchNew(data:any) : OsuPacketWriter,
MatchNew(data:MatchData) : OsuPacketWriter,
MatchDisband(data:any) : OsuPacketWriter,
MatchJoinSuccess(data:any) : OsuPacketWriter,
MatchJoinSuccess(data:MatchData) : OsuPacketWriter,
MatchJoinFail() : OsuPacketWriter,
FellowSpectatorJoined(data:any) : OsuPacketWriter,
FellowSpectatorLeft(data:any) : OsuPacketWriter,
MatchStart(data:any) : OsuPacketWriter,
MatchScoreUpdate(data:any) : OsuPacketWriter,
FellowSpectatorJoined(data:number) : OsuPacketWriter,
FellowSpectatorLeft(data:number) : OsuPacketWriter,
MatchStart(data:MatchData) : OsuPacketWriter,
MatchScoreUpdate(data:MatchScoreData) : OsuPacketWriter,
MatchTransferHost(data:any) : OsuPacketWriter,
MatchAllPlayersLoaded() : OsuPacketWriter,
MatchPlayerFailed(data:any) : OsuPacketWriter,
@ -43,9 +45,9 @@ export default interface OsuPacketWriter {
ProtocolNegotiation(data:number) : OsuPacketWriter,
TitleUpdate(data:string) : OsuPacketWriter,
Monitor() : OsuPacketWriter,
MatchPlayerSkipped(data:any) : OsuPacketWriter,
MatchPlayerSkipped(data:number) : OsuPacketWriter,
UserPresence(data:any) : OsuPacketWriter,
Restart(data:any) : OsuPacketWriter,
Restart(data:number) : OsuPacketWriter,
Invite(data:any) : OsuPacketWriter,
ChannelListingComplete() : OsuPacketWriter,
MatchChangePassword(data:any) : OsuPacketWriter,
@ -58,7 +60,7 @@ export default interface OsuPacketWriter {
VersionUpdateForced() : OsuPacketWriter,
SwitchServer(data:any) : OsuPacketWriter,
AccountRestricted() : OsuPacketWriter,
RTX(data:any) : OsuPacketWriter,
RTX(data:string) : OsuPacketWriter,
SwitchTourneyServer(data:any) : OsuPacketWriter
toBuffer : Buffer

View file

@ -0,0 +1,8 @@
export default interface PresenceData {
status: number,
statusText: string,
beatmapId: number,
beatmapChecksum: string,
currentMods: number,
playMode: number,
}

View file

@ -0,0 +1,15 @@
export default interface StatusUpdateData {
userId: number,
status: number,
statusText: string,
beatmapChecksum: string,
currentMods: number,
playMode: number,
beatmapId: number,
rankedScore: number,
accuracy: number,
playCount: number,
totalScore: number,
rank: number,
performance: number
}

View file

@ -1,5 +1,5 @@
export default class FunkyArray<T> {
private items:any = {};
private items:{ [id: string]: T } = {};
private itemKeys:Array<string> = Object.keys(this.items);
private iterableArray:Array<T> = new Array<T>();

View file

@ -397,11 +397,16 @@ export default class Match {
allSkipped = false;
}
const slotId = user.matchSlot?.slotId ?? Number.MIN_VALUE;
if (slotId === Number.MIN_VALUE) {
return;
}
// All players have finished playing, finish the match
if (allSkipped) {
const osuPacketWriter = osu.Bancho.Writer();
osuPacketWriter.MatchPlayerSkipped(user.id);
osuPacketWriter.MatchPlayerSkipped(slotId);
osuPacketWriter.MatchSkip();
this.matchStream.Send(osuPacketWriter.toBuffer);
@ -410,7 +415,7 @@ export default class Match {
} else {
const osuPacketWriter = osu.Bancho.Writer();
osuPacketWriter.MatchPlayerSkipped(user.id);
osuPacketWriter.MatchPlayerSkipped(slotId);
this.matchStream.Send(osuPacketWriter.toBuffer);
}
@ -593,7 +598,7 @@ export default class Match {
const osuPacketWriter = osu.Bancho.Writer();
let queryData:Array<any> = [
const queryData:Array<string | number | null> = [
this.matchId,
this.roundId++,
this.playMode,

View file

@ -6,6 +6,7 @@ import StatusUpdate from "../packets/StatusUpdate";
import Shared from "../objects/Shared";
import Slot from "./Slot";
import Channel from "./Channel";
import PresenceData from "../interfaces/PresenceData";
const rankingModes = [
"pp_raw",
@ -14,8 +15,6 @@ const rankingModes = [
];
export default class User {
private static readonly EMPTY_BUFFER = Buffer.alloc(0);
public shared:Shared;
public id:number;
@ -23,7 +22,7 @@ export default class User {
public uuid:string;
public readonly connectTime:number = Date.now();
public timeoutTime:number = Date.now() + 30000;
public queue:Buffer = User.EMPTY_BUFFER;
public queue:Buffer = Buffer.allocUnsafe(0);
// Binato data
public rankingMode:RankingModes = RankingModes.PP;
@ -80,11 +79,11 @@ export default class User {
}
clearQueue() {
this.queue = User.EMPTY_BUFFER;
this.queue = Buffer.allocUnsafe(0);
}
// Updates the user's current action
updatePresence(action:any) {
updatePresence(action:PresenceData) {
this.actionID = action.status;
this.actionText = action.statusText;
this.beatmapChecksum = action.beatmapChecksum;

View file

@ -1,7 +1,8 @@
import PresenceData from "../interfaces/PresenceData";
import User from "../objects/User";
import StatusUpdate from "./StatusUpdate";
export default function ChangeAction(user:User, data:any) {
export default function ChangeAction(user:User, data:PresenceData) {
user.updatePresence(data);
if (user.spectatorStream != null) {