import net from 'net' ; import { ExtendedSocket } from 'extendedsocket' ; import { Channel } from 'channel/channel' ; import { User } from 'user/user' ; import { UserInventory } from 'user/userinventory' ; import { UserSession } from 'user/usersession' ; import { ChannelManager } from 'channel/channelmanager' ; import { ChatMessageType } from 'packets/definitions' ; import { FavoritePacketType } from 'packets/definitions' ; import { OptionPacketType } from 'packets/definitions' ; import { UnlockCurrency } from 'gametypes/unlockitem' ; import { InFavoritePacket } from 'packets/in/favorite' ; import { InFavoriteSetCosmetics } from 'packets/in/favorite/setcosmetics' ; import { InFavoriteSetLoadout } from 'packets/in/favorite/setloadout' ; import { InLoginPacket } from 'packets/in/login' ; import { InOptionPacket } from 'packets/in/option' ; import { InOptionBuyMenu } from 'packets/in/option/buymenu' ; import { OutChatPacket } from 'packets/out/chat' ; import { OutFavoritePacket } from 'packets/out/favorite' ; import { OutInventoryPacket } from 'packets/out/inventory' ; import { OutOptionPacket } from 'packets/out/option' ; import { OutUserInfoPacket } from 'packets/out/userinfo' ; import { OutUserStartPacket } from 'packets/out/userstart' ; import { OutUnlockPacket } from 'packets/out/unlock' ; import { AboutMeHandler } from 'handlers/aboutmehandler' ; import { UserService } from 'services/userservice' ; import { ActiveConnections } from 'storage/activeconnections' ; import { GAME_LOGIN_BAD_PASSWORD , GAME_LOGIN_BAD_USERNAME , GAME_LOGIN_INVALID_USERINFO } from 'gamestrings' ; const aboutMeHandler = new AboutMeHandler ( ) ; /**
 * handles the user logic
 */ export class UserManager { public static async OnSocketClosed ( conn ) { const session = conn . session ; if ( session == null ) { return ; } const curChannel = session . currentChannel ; if ( curChannel != null ) { curChannel . OnUserLeft ( conn ) ; } await UserService . Logout ( session . user . id ) ; } param loginData param connection param server public static async onLoginPacket ( loginData , connection , holepunchPort ) { const loginPacket = new InLoginPacket ( loginData ) ; const loggedUserId = await UserService . Login ( loginPacket . gameUsername , loginPacket . password ) ; if ( loggedUserId === 0 ) { this . SendUserDialogBox ( connection , GAME_LOGIN_BAD_USERNAME ) ; console . warn ( 'Could not create session for user %s' , loginPacket . gameUsername ) ; return false ; } if ( loggedUserId === - 1 ) { this . SendUserDialogBox ( connection , GAME_LOGIN_BAD_PASSWORD ) ; console . warn ( `Login attempt for user ${ loginPacket . gameUsername } failed` ) ; return false ; } loginPacket . password = null ; const user = await UserService . GetUserById ( loggedUserId ) ; if ( user == null ) { this . SendUserDialogBox ( connection , GAME_LOGIN_INVALID_USERINFO ) ; console . error ( `Couldn't get user ID ${ loggedUserId }'s information` ) ; return false ; } const newSession = new UserSession ( user , connection . address ( ) as net . AddressInfo ) ; connection . session = newSession ; console . log ( `user ${ user . username } logged in (uuid: ${ connection . uuid })` ) ; ActiveConnections . Singleton ( ) . Add ( connection ) ; UserManager . sendUserInfoToSelf ( user , connection , holepunchPort ) ; await UserManager . sendInventory ( newSession . user . id , connection ) ; ChannelManager . sendChannelListTo ( connection ) ; return true ; } public static async onAboutmePacket ( packetData , connection ) { return await aboutMeHandler . OnPacket ( packetData , connection ) ; } param optionData param conn public static async onOptionPacket ( optionData , conn ) { if ( conn . session == null ) { console . warn ( `connection ${ conn . uuid } sent an option packet without a session` ) ; return false ; } const optPacket = new InOptionPacket ( optionData ) ; switch ( optPacket . packetType ) { case OptionPacketType . SetBuyMenu : return this . onOptionSetBuyMenu ( optPacket , conn ) ; } console . warn ( 'UserManager::onOptionPacket: unknown packet type %i' , optPacket . packetType ) ; return false ; } public static async onOptionSetBuyMenu ( optPacket , conn ) { const buyMenuData = new InOptionBuyMenu ( optPacket ) ; const session = conn . session ; if ( session == null ) { console . warn ( `Could not get connection "${ conn . uuid }"'s session` ) ; return false ; } console . log ( `Setting user ID ${ session . user . id }'s buy menu` ) ; await UserInventory . setBuyMenu ( session . user . id , buyMenuData . buyMenu ) ; return true ; } public static async onFavoritePacket ( favoriteData , sourceConn ) { if ( sourceConn . session == null ) { console . warn ( `connection ${ sourceConn . uuid } sent a favorite packet without a session` ) ; return false ; } const favPacket = new InFavoritePacket ( favoriteData ) ; switch ( favPacket . packetType ) { case FavoritePacketType . SetLoadout : return this . onFavoriteSetLoadout ( favPacket , sourceConn ) ; case FavoritePacketType . SetCosmetics : return this . onFavoriteSetCosmetics ( favPacket , sourceConn ) ; } console . warn ( 'UserManager::onFavoritePacket: unknown packet type %i' , favPacket . packetType ) ; return false ; } public static async onFavoriteSetLoadout ( favPacket , sourceConn ) { const loadoutData = new InFavoriteSetLoadout ( favPacket ) ; const session = sourceConn . session ; if ( session == null ) { console . warn ( `Could not get connection "${ sourceConn . uuid }"'s session` ) ; return false ; } const loadoutNum = loadoutData . loadout ; const slot = loadoutData . weaponSlot ; const itemId = loadoutData . itemId ; console . log ( `Setting user ID ${ session . user . id }'s new weapon ${ itemId } to slot ${ slot } in loadout ${ loadoutNum }` ) ; await UserInventory . setLoadoutWeapon ( session . user . id , loadoutNum , slot , itemId ) ; return true ; } public static async onFavoriteSetCosmetics ( favPacket , sourceConn ) { const cosmeticsData = new InFavoriteSetCosmetics ( favPacket ) ; const session = sourceConn . session ; if ( session == null ) { console . warn ( `Could not get connection "${ sourceConn . uuid }"'s session` ) ; return false ; } const slot = cosmeticsData . slot ; const itemId = cosmeticsData . itemId ; console . debug ( `Setting user ID ${ session . user . id }'s new cosmetic ${ itemId } to slot ${ slot }` ) ; await UserInventory . setCosmeticSlot ( session . user . id , slot , itemId ) ; return true ; } param user param conn param holepunchPort private static sendUserInfoToSelf ( user , conn , holepunchPort ) { conn . send ( new OutUserStartPacket ( user . id , user . username , user . playername , holepunchPort ) ) ; conn . send ( OutUserInfoPacket . fullUserUpdate ( user ) ) ; } param userId param conn private static async sendInventory ( userId , conn ) { const [ inventory , cosmetics , loadouts , buyMenu ] = await Promise . all ( [ UserInventory . getInventory ( userId ) , UserInventory . getCosmetics ( userId ) , UserInventory . getAllLoadouts ( userId ) , UserInventory . getBuyMenu ( userId ) ] ) ; if ( inventory == null || cosmetics == null || loadouts == null || buyMenu == null ) { return ; } conn . send ( OutInventoryPacket . createInventory ( inventory . items ) ) ; conn . send ( OutUnlockPacket . createUnlockInfo ( [ ] , [ ] ) ) ; conn . send ( OutFavoritePacket . setCosmetics ( cosmetics . ct_item , cosmetics . ter_item , cosmetics . head_item , cosmetics . glove_item , cosmetics . back_item , cosmetics . steps_item , cosmetics . card_item , cosmetics . spray_item ) ) ; conn . send ( OutFavoritePacket . setLoadout ( loadouts ) ) ; conn . send ( OutOptionPacket . setBuyMenu ( buyMenu ) ) ; } private static SendUserDialogBox ( userConn , msg ) { const badDialogData = OutChatPacket . systemMessage ( msg , ChatMessageType . DialogBox ) ; userConn . send ( badDialogData ) ; } }