153 lines
No EOL
5.3 KiB
JavaScript
Executable file
153 lines
No EOL
5.3 KiB
JavaScript
Executable file
const osu = require("osu-packet"),
|
|
User = require("./User.js"),
|
|
uuid = require("./util/shortUUID.js"),
|
|
ahttp = require("./util/AsyncHttpRequest.js"),
|
|
consoleHelper = require("../consoleHelper.js"),
|
|
// Packets
|
|
getUserByUsername = require("./util/getUserByUsername.js"),
|
|
getUserByToken = require("./util/getUserByToken.js"),
|
|
countryHelper = require("./countryHelper.js"),
|
|
loginHelper = require("./loginHelper.js"),
|
|
Logout = require("./Packets/Logout.js"),
|
|
Streams = require("./Streams.js"),
|
|
UserPresenceBundle = require("./Packets/UserPresenceBundle.js"),
|
|
UserPresence = require("./Packets/UserPresence.js"),
|
|
StatusUpdate = require("./Packets/StatusUpdate.js");
|
|
|
|
module.exports = async function(req, res, loginInfo) {
|
|
// Get time at the start of login
|
|
const loginStartTime = Date.now(),
|
|
isTourneyClient = loginInfo.osuversion.includes("tourney");
|
|
|
|
// Check login
|
|
const loginCheck = await loginHelper.checkLogin(loginInfo);
|
|
if (loginCheck != null) {
|
|
res.removeHeader('X-Powered-By');
|
|
res.removeHeader('Date');
|
|
res.writeHead(200, loginCheck[1]);
|
|
return res.end(loginCheck[0]);
|
|
}
|
|
|
|
// Get users IP for getting location
|
|
// Get cloudflare requestee IP first
|
|
let requestIP = req.get("cf-connecting-ip");
|
|
|
|
// Get IP of requestee since we are probably behind a reverse proxy
|
|
if (requestIP == null)
|
|
requestIP = req.get("X-Real-IP");
|
|
|
|
// Just get the requestee IP (we are not behind a reverse proxy)
|
|
if (requestIP == null)
|
|
requestIP = req.remote_addr;
|
|
|
|
// Make sure requestIP is never null
|
|
if (requestIP == null)
|
|
requestIP = "";
|
|
|
|
|
|
let userLocationData = [], userLocation;
|
|
// Check if it is a local or null IP
|
|
if (requestIP.includes("192.168.") || requestIP.includes("127.0.") || requestIP == "") {
|
|
// Set location to null island
|
|
userLocationData.country = "XX";
|
|
userLocation = [0, 0];
|
|
} else {
|
|
// Get user's location using zxq
|
|
userLocationData = await ahttp(`http://ip.zxq.co/${requestIP}`, "json");
|
|
userLocation = userLocationData.loc.split(",");
|
|
}
|
|
|
|
// Get information about the user from the database
|
|
const userDB = await global.DatabaseHelper.query("SELECT id FROM users_info WHERE username = ? LIMIT 1", [loginInfo.username]);
|
|
|
|
// Create a token for the client
|
|
const newClientToken = uuid();
|
|
|
|
// Make sure user is not already connected, kick off if so.
|
|
const connectedUser = getUserByUsername(loginInfo.username);
|
|
if (connectedUser != null && !isTourneyClient && !connectedUser.isTourneyUser) {
|
|
Logout(connectedUser);
|
|
}
|
|
|
|
// Retreive the newly created user
|
|
const NewUser = global.users.add(newClientToken, new User(userDB.id, loginInfo.username, newClientToken));
|
|
// Set tourney client flag
|
|
NewUser.isTourneyUser = isTourneyClient;
|
|
|
|
// Get user's data from the database
|
|
NewUser.updateUserInfo();
|
|
|
|
try {
|
|
// Save the user's location to their class for later use
|
|
NewUser.location[0] = parseFloat(userLocation[0]);
|
|
NewUser.location[1] = parseFloat(userLocation[1]);
|
|
|
|
// Save the country id for the same reason as above
|
|
NewUser.countryID = countryHelper.getCountryID(userLocationData.country);
|
|
|
|
// We're ready to start putting together a login packet
|
|
// Create an osu! Packet writer
|
|
let osuPacketWriter = new osu.Bancho.Writer;
|
|
|
|
// The reply id is the user's id in any other case than an error in which case negative numbers are used
|
|
osuPacketWriter.LoginReply(NewUser.id);
|
|
// Current bancho protocol version. Defined in Binato.js
|
|
osuPacketWriter.ProtocolNegotiation(global.protocolVersion);
|
|
// Permission level 4 is osu!supporter
|
|
osuPacketWriter.LoginPermissions(4);
|
|
|
|
// After sending the user their friends list send them the online users
|
|
UserPresenceBundle(NewUser);
|
|
|
|
// Set title screen image
|
|
//osuPacketWriter.TitleUpdate("http://puu.sh/jh7t7/20c04029ad.png|https://osu.ppy.sh/news/123912240253");
|
|
|
|
// Add user panel data packets
|
|
UserPresence(NewUser, NewUser.id);
|
|
StatusUpdate(NewUser, NewUser.id);
|
|
|
|
// peppy pls, why
|
|
osuPacketWriter.ChannelListingComplete();
|
|
|
|
// Add user to #osu
|
|
osuPacketWriter.ChannelJoinSuccess("#osu");
|
|
if (!Streams.isUserInStream("#osu", NewUser.uuid))
|
|
Streams.addUserToStream("#osu", NewUser.uuid);
|
|
|
|
// List all channels out to the client
|
|
for (let i = 0; i < global.channels.length; i++) {
|
|
osuPacketWriter.ChannelAvailable({
|
|
channelName: global.channels[i].channelName,
|
|
channelTopic: global.channels[i].channelTopic,
|
|
channelUserCount: global.channels[i].channelUserCount
|
|
});
|
|
}
|
|
|
|
// Construct user's friends list
|
|
const userFriends = await global.DatabaseHelper.query("SELECT friendsWith FROM friends WHERE user = ?", [NewUser.id]);
|
|
let friendsArray = [];
|
|
for (let i = 0; i < userFriends.length; i++) {
|
|
friendsArray.push(userFriends[i].friendsWith);
|
|
}
|
|
// Send user's friends list
|
|
osuPacketWriter.FriendsList(friendsArray);
|
|
|
|
osuPacketWriter.Announce(`Welcome back ${loginInfo.username}!`);
|
|
|
|
global.DatabaseHelper.query("UPDATE osu_info SET value = ? WHERE name = 'online_now'", [global.users.getLength() - 1]);
|
|
|
|
res.removeHeader('X-Powered-By');
|
|
res.removeHeader('Date');
|
|
// Complete login
|
|
res.writeHead(200, {
|
|
"cho-token": NewUser.uuid,
|
|
"Connection": "keep-alive",
|
|
"Keep-Alive": "timeout=5, max=100",
|
|
});
|
|
res.end(osuPacketWriter.toBuffer, () => {
|
|
consoleHelper.printBancho(`User login finished, took ${Date.now() - loginStartTime}ms. [User: ${loginInfo.username}]`);
|
|
});
|
|
} catch (err) {
|
|
console.error(err);
|
|
}
|
|
} |