def enterSetAccount(self): # First, if there's anybody on the account, kill 'em for redundant login: dg = PyDatagram() dg.addServerHeader(self.csm.GetAccountConnectionChannel(int(self.databaseId)), self.csm.air.ourChannel, CLIENTAGENT_EJECT) dg.addUint16(100) dg.addString('This account has been logged in elsewhere.') self.csm.air.send(dg) # Next, add this connection to the account channel. dg = PyDatagram() dg.addServerHeader(self.target, self.csm.air.ourChannel, CLIENTAGENT_OPEN_CHANNEL) dg.addChannel(self.csm.GetAccountConnectionChannel(self.databaseId)) self.csm.air.send(dg) # Now set their sender channel to represent their account affiliation: dg = PyDatagram() dg.addServerHeader(self.target, self.csm.air.ourChannel, CLIENTAGENT_SET_CLIENT_ID) dg.addChannel(self.databaseId << 32) # accountId in high 32 bits, 0 in low (no avatar) self.csm.air.send(dg) # Un-sandbox them! dg = PyDatagram() dg.addServerHeader(self.target, self.csm.air.ourChannel, CLIENTAGENT_SET_STATE) dg.addUint16(2) # ESTABLISHED state. BIG FAT SECURITY RISK!!! self.csm.air.send(dg) # We're done. self.csm.sendUpdateToChannel(self.target, 'acceptLogin', []) self.demand('Off')
def killConnection(self, connId, reason): datagram = PyDatagram() datagram.addServerHeader(connId, self.air.ourChannel, CLIENTAGENT_EJECT) datagram.addUint16(122) datagram.addString(reason) self.air.send(datagram)
def login(self, cookie, sig): self.notify.debug("Received login cookie %r from %d" % (cookie, self.air.getMsgSender())) sender = self.air.getMsgSender() if not self.loginsEnabled: # Logins are currently disabled... RIP! dg = PyDatagram() dg.addServerHeader(sender, self.air.ourChannel, CLIENTAGENT_EJECT) dg.addUint16(200) dg.addString("Logins are currently disabled. Please try again later.") self.air.send(dg) if sender >> 32: # Oops, they have an account ID on their connection already! self.killConnection(sender, "Client is already logged in.") return # Test the signature key = ( config.GetString("csmud-secret", "streetlamps") + config.GetString("server-version", "no_version_set") + FIXED_KEY ) computedSig = hmac.new(key, cookie, hashlib.sha256).digest() if sig != computedSig: self.killConnection(sender, "The accounts database rejected your cookie") return if sender in self.connection2fsm: self.killConnectionFSM(sender) return self.connection2fsm[sender] = LoginAccountFSM(self, sender) self.connection2fsm[sender].request("Start", cookie)
def bootClient(self, reason, av): dg = PyDatagram() dg.addServerHeader(self.GetPuppetConnectionChannel(av), self.air.ourChannel, CLIENTAGENT_EJECT) dg.addUint16(106) dg.addString(reason) self.air.send(dg)
def enterSetAccount(self): if self.accessLevel: self.csm.air.dbInterface.updateObject( self.csm.air.dbId, self.accountId, self.csm.air.dclassesByName['AccountUD'], {'ACCESS_LEVEL': self.accessLevel}) datagram = PyDatagram() datagram.addServerHeader( self.csm.GetAccountConnectionChannel(self.accountId), self.csm.air.ourChannel, CLIENTAGENT_EJECT) datagram.addUint16(100) datagram.addString('This account has been logged in from elsewhere.') self.csm.air.send(datagram) datagram = PyDatagram() datagram.addServerHeader(self.target, self.csm.air.ourChannel, CLIENTAGENT_OPEN_CHANNEL) datagram.addChannel( self.csm.GetAccountConnectionChannel(self.accountId)) self.csm.air.send(datagram) access = self.account.get('ACCESS_LEVEL', 0) if access >= 200: dg = PyDatagram() dg.addServerHeader(self.target, self.csm.air.ourChannel, CLIENTAGENT_OPEN_CHANNEL) dg.addChannel(OtpDoGlobals.OTP_MOD_CHANNEL) self.csm.air.send(dg) if access >= 400: dg = PyDatagram() dg.addServerHeader(self.target, self.csm.air.ourChannel, CLIENTAGENT_OPEN_CHANNEL) dg.addChannel(OtpDoGlobals.OTP_ADMIN_CHANNEL) self.csm.air.send(dg) if access >= 500: dg = PyDatagram() dg.addServerHeader(self.target, self.csm.air.ourChannel, CLIENTAGENT_OPEN_CHANNEL) dg.addChannel(OtpDoGlobals.OTP_SYSADMIN_CHANNEL) self.csm.air.send(dg) datagram = PyDatagram() datagram.addServerHeader(self.target, self.csm.air.ourChannel, CLIENTAGENT_SET_CLIENT_ID) datagram.addChannel(self.accountId << 32) self.csm.air.send(datagram) datagram = PyDatagram() datagram.addServerHeader(self.target, self.csm.air.ourChannel, CLIENTAGENT_SET_STATE) datagram.addUint16(2) self.csm.air.send(datagram) self.csm.air.dbInterface.updateObject( self.csm.air.dbId, self.accountId, self.csm.air.dclassesByName['AccountUD'], { 'LAST_LOGIN': time.ctime(), 'ACCOUNT_ID': str(self.userId) }) self.csm.air.writeServerEvent('accountLogin', self.target, self.accountId, self.userId) self.csm.sendUpdateToChannel(self.target, 'acceptLogin', [int(time.time())]) self.demand('Off')
def killConnection(self, connectionId, reason): # Sends CLIENTAGENT_EJECT to the given connectionId with the given reason. datagram = PyDatagram() datagram.addServerHeader(connectionId, self.air.ourChannel, CLIENTAGENT_EJECT) datagram.addUint16(OTPGlobals.BootedReason["connectionKilled"]) datagram.addString(reason) self.air.send(datagram)
def killConnection(self, connId, code=122, reason=''): self.notify.info('Booting client: %d out for reason(%d): %s' % (int(connId), int(code), str(reason))) dg = PyDatagram() dg.addServerHeader(connId, self.air.ourChannel, CLIENTAGENT_EJECT) dg.addUint16(int(code)) dg.addString(str(reason)) self.air.send(dg)
def inviteeFriendResponse(self, response, context): avId = self.air.getAvatarIdFromSender() if not context in self.requests: self.air.writeServerEvent( 'suspicious', avId=avId, issue= 'Player tried to respond to a friend request that doesn\'t exist!' ) return if avId != self.requests[context][0][1]: self.air.writeServerEvent( 'suspicious', avId=avId, issue='Player tried to respond to someone else\'s request!') return if self.requests[context][1] == 'cancelled': self.air.writeServerEvent( 'suspicious', avId=avId, issue='Player tried to respond to non-active friend request!') return self.sendUpdateToAvatarId(self.requests[context][0][0], 'friendResponse', [response, context]) if response == 1: requested = self.air.doId2do.get(self.requests[context][0][1]) requester = self.air.doId2do.get(self.requests[context][0][0]) if not (requested and requester): # Likely they logged off just before a response was sent. RIP. return # Allow both toons to teleport to each other. dg = PyDatagram() dg.addServerHeader( self.GetPuppetConnectionChannel(requested.getDoId()), self.air.ourChannel, CLIENTAGENT_DECLARE_OBJECT) dg.addUint32(requester.getDoId()) dg.addUint16( self.air.dclassesByName['DistributedToonAI'].getNumber()) self.air.send(dg) dg = PyDatagram() dg.addServerHeader( self.GetPuppetConnectionChannel(requester.getDoId()), self.air.ourChannel, CLIENTAGENT_DECLARE_OBJECT) dg.addUint32(requested.getDoId()) dg.addUint16( self.air.dclassesByName['DistributedToonAI'].getNumber()) self.air.send(dg) requested.extendFriendsList(requester.getDoId(), 0) requester.extendFriendsList(requested.getDoId(), 0) requested.d_setFriendsList(requested.getFriendsList()) requester.d_setFriendsList(requester.getFriendsList()) del self.requests[context]
def killConnection(self, connId, reason): datagram = PyDatagram() datagram.addServerHeader( connId, self.air.ourChannel, CLIENTAGENT_EJECT) datagram.addUint16(122) datagram.addString(reason) self.air.send(datagram)
def killConnection(self, connectionId, reason, code=OTPGlobals.BootedConnectionKilled): datagram = PyDatagram() datagram.addServerHeader(connectionId, self.air.ourChannel, CLIENTAGENT_EJECT) datagram.addUint16(code) datagram.addString(reason) self.air.send(datagram)
def login(self, cookie): target = self.air.getMsgSender() datagram = PyDatagram() datagram.addServerHeader(target, self.air.ourChannel, CLIENTAGENT_SET_STATE) datagram.addUint16(2) self.air.send(datagram) self.sendUpdateToChannel(target, 'acceptLogin', [])
def enterSetAccount(self): # If somebody's already logged into this account, disconnect them. datagram = PyDatagram() datagram.addServerHeader( self.gameServicesManager.GetAccountConnectionChannel( self.accountId), self.gameServicesManager.air.ourChannel, CLIENTAGENT_EJECT) datagram.addUint16(OTPGlobals.BootedReason["loggedInElsewhere"]) datagram.addString('This account has been logged into elsewhere.') self.gameServicesManager.air.send(datagram) # Now we'll add this connection to the account channel. datagram = PyDatagram() datagram.addServerHeader(self.target, self.gameServicesManager.air.ourChannel, CLIENTAGENT_OPEN_CHANNEL) datagram.addChannel( self.gameServicesManager.GetAccountConnectionChannel( self.accountId)) self.gameServicesManager.air.send(datagram) # Set their sender channel to represent their account affiliation. datagram = PyDatagram() datagram.addServerHeader(self.target, self.gameServicesManager.air.ourChannel, CLIENTAGENT_SET_CLIENT_ID) datagram.addChannel( self.accountId << 32) # accountId in high 32 bits, 0 in low (no avatar). self.gameServicesManager.air.send(datagram) # We can now un-sandbox the sender. self.gameServicesManager.air.setClientState(self.target, 2) # ESTABLISHED state. # Update the last login timestamp. self.gameServicesManager.air.dbInterface.updateObject( self.gameServicesManager.air.dbId, self.accountId, self.gameServicesManager.air.dclassesByName['AccountUD'], { 'LAST_LOGIN': time.ctime(), 'ACCOUNT_ID': str(self.databaseId), 'ACCESS_LEVEL': self.accessLevel }) # We're done. self.gameServicesManager.air.writeServerEvent('account-login', clientId=self.target, accId=self.accountId, dbId=self.databaseId, playToken=self.playToken) # Send the acceptLogin update through the GameServicesManager & set this operation's state to Off. self.gameServicesManager.sendUpdateToChannel(self.target, 'acceptLogin', []) self.demand('Off')
def login(self, cookie): target = self.air.getMsgSender() datagram = PyDatagram() datagram.addServerHeader( target, self.air.ourChannel, CLIENTAGENT_SET_STATE) datagram.addUint16(2) self.air.send(datagram) self.sendUpdateToChannel(target, 'acceptLogin', [])
def inviteeFriendResponse(self, response, context): avId = self.air.getAvatarIdFromSender() if not avId: return if context not in self.requests: self.air.writeServerEvent( 'suspicious', avId, "Player tried to respond to a friend request that doesn't exist!" ) return if avId != self.requests[context][0][1]: self.air.writeServerEvent( 'suspicious', avId, "Player tried to respond to someone else's request!") return if self.requests[context][1] == 'cancelled': self.air.writeServerEvent( 'suspicious', avId, 'Player tried to respond to a non-active friend request!') return self.sendUpdateToAvatarId(self.requests[context][0][0], 'friendResponse', [response, context]) if response == 1: requestedAv = self.air.doId2do.get(self.requests[context][0][1]) if not requestedAv: del self.requests[context] return requesterAv = self.air.doId2do.get(self.requests[context][0][0]) if not requesterAv: del self.requests[context] return dg = PyDatagram() dg.addServerHeader( self.GetPuppetConnectionChannel(requestedAv.getDoId()), self.air.ourChannel, CLIENTAGENT_DECLARE_OBJECT) dg.addUint32(requesterAv.getDoId()) dg.addUint16( self.air.dclassesByName['DistributedToonAI'].getNumber()) self.air.send(dg) dg = PyDatagram() dg.addServerHeader( self.GetPuppetConnectionChannel(requesterAv.getDoId()), self.air.ourChannel, CLIENTAGENT_DECLARE_OBJECT) dg.addUint32(requestedAv.getDoId()) dg.addUint16( self.air.dclassesByName['DistributedToonAI'].getNumber()) self.air.send(dg) requestedAv.extendFriendsList(requesterAv.getDoId(), 0) requesterAv.extendFriendsList(requestedAv.getDoId(), 0) requestedAv.d_setFriendsList(requestedAv.getFriendsList()) requesterAv.d_setFriendsList(requesterAv.getFriendsList()) del self.requests[context]
def packGardenData(plants, statuary, started = True): dg = PyDatagram() for plant in plants: a, b, c, d, e = plant dg.addUint32(a) dg.addInt8(b) dg.addUint32(c) dg.addInt8(d) dg.addUint16(e) dg.addUint8(statuary) dg.addBool(started) return dg.getMessage()
def packGardenData(plants, statuary, started=True): dg = PyDatagram() for plant in plants: a, b, c, d, e = plant dg.addUint32(a) dg.addInt8(b) dg.addUint32(c) dg.addInt8(d) dg.addUint16(e) dg.addUint8(statuary) dg.addBool(started) return dg.getMessage()
def enterSetAccount(self): # First, if there's anybody on the account, kill 'em for redundant login: dg = PyDatagram() dg.addServerHeader( self.csm.GetAccountConnectionChannel(self.accountId), self.csm.air.ourChannel, CLIENTAGENT_EJECT) dg.addUint16(100) dg.addString('This account has been logged in elsewhere.') self.csm.air.send(dg) # Next, add this connection to the account channel. dg = PyDatagram() dg.addServerHeader(self.target, self.csm.air.ourChannel, CLIENTAGENT_OPEN_CHANNEL) dg.addChannel(self.csm.GetAccountConnectionChannel(self.accountId)) self.csm.air.send(dg) # Now set their sender channel to represent their account affiliation: dg = PyDatagram() dg.addServerHeader(self.target, self.csm.air.ourChannel, CLIENTAGENT_SET_CLIENT_ID) dg.addChannel(self.accountId << 32) # accountId in high 32 bits, 0 in low (no avatar) self.csm.air.send(dg) # Un-sandbox them! dg = PyDatagram() dg.addServerHeader(self.target, self.csm.air.ourChannel, CLIENTAGENT_SET_STATE) dg.addUint16(2) # ESTABLISHED state. self.csm.air.send(dg) fields = { 'LAST_LOGIN': time.ctime(), 'ACCOUNT_ID': str(self.databaseId) } if self.adminAccess != -1: fields.update({'ADMIN_ACCESS': self.adminAccess}) # Update the last login timestamp: self.csm.air.dbInterface.updateObject( self.csm.air.dbId, self.accountId, self.csm.air.dclassesByName['AccountUD'], fields) # We're done. self.csm.air.writeServerEvent('accountLogin', self.target, self.accountId, self.databaseId) self.csm.sendUpdateToChannel(self.target, 'acceptLogin', []) self.csm.account2username[self.target] = self.username self.demand('Off')
def enterSetAccount(self): # First, if there's anybody on the account, kill them for redundant login: datagram = PyDatagram() datagram.addServerHeader( self.csm.GetAccountConnectionChannel(self.accountId), self.csm.air.ourChannel, CLIENTAGENT_EJECT) datagram.addUint16(100) datagram.addString('This account has been logged in from elsewhere.') self.csm.air.send(datagram) # Next, add this connection to the account channel. datagram = PyDatagram() datagram.addServerHeader( self.target, self.csm.air.ourChannel, CLIENTAGENT_OPEN_CHANNEL) datagram.addChannel(self.csm.GetAccountConnectionChannel(self.accountId)) self.csm.air.send(datagram) # Now set their sender channel to represent their account affiliation: datagram = PyDatagram() datagram.addServerHeader( self.target, self.csm.air.ourChannel, CLIENTAGENT_SET_CLIENT_ID) # Account ID in high 32 bits, 0 in low (no avatar): datagram.addChannel(self.accountId << 32) self.csm.air.send(datagram) # Un-sandbox them! datagram = PyDatagram() datagram.addServerHeader( self.target, self.csm.air.ourChannel, CLIENTAGENT_SET_STATE) datagram.addUint16(2) # ESTABLISHED self.csm.air.send(datagram) # Update the last login timestamp: self.csm.air.dbInterface.updateObject( self.csm.air.dbId, self.accountId, self.csm.air.dclassesByName['AccountUD'], {'LAST_LOGIN': time.ctime(time.mktime(time.gmtime())), 'ACCOUNT_ID': str(self.userId)}) # We're done. self.csm.air.writeServerEvent('accountLogin', self.target, self.accountId, self.userId) self.csm.sendUpdateToChannel(self.target, 'acceptLogin', [int(time.mktime(time.gmtime()))]) self.demand('Off')
def enterSetAccount(self): dg = PyDatagram() dg.addServerHeader( self.csm.GetAccountConnectionChannel(self.accountId), self.csm.air.ourChannel, CLIENTAGENT_EJECT) dg.addUint16(100) dg.addString('This account has been logged in elsewhere.') self.csm.air.send(dg) dg = PyDatagram() dg.addServerHeader(self.target, self.csm.air.ourChannel, CLIENTAGENT_OPEN_CHANNEL) dg.addChannel(self.csm.GetAccountConnectionChannel(self.accountId)) self.csm.air.send(dg) access = self.account.get('ADMIN_ACCESS', 0) if access >= 400: dg = PyDatagram() dg.addServerHeader(self.target, self.csm.air.ourChannel, CLIENTAGENT_OPEN_CHANNEL) dg.addChannel(OtpDoGlobals.OTP_MOD_CHANNEL) self.csm.air.send(dg) if access >= 500: dg = PyDatagram() dg.addServerHeader(self.target, self.csm.air.ourChannel, CLIENTAGENT_OPEN_CHANNEL) dg.addChannel(OtpDoGlobals.OTP_ADMIN_CHANNEL) self.csm.air.send(dg) dg = PyDatagram() dg.addServerHeader(self.target, self.csm.air.ourChannel, CLIENTAGENT_SET_CLIENT_ID) dg.addChannel(self.accountId << 32) self.csm.air.send(dg) dg = PyDatagram() dg.addServerHeader(self.target, self.csm.air.ourChannel, CLIENTAGENT_SET_STATE) dg.addUint16(2) self.csm.air.send(dg) self.csm.air.dbInterface.updateObject( self.csm.air.dbId, self.accountId, self.csm.air.dclassesByName['AccountUD'], { 'LAST_LOGIN': time.ctime(), 'ACCOUNT_ID': str(self.databaseId), 'ADMIN_ACCESS': self.adminAccess }) self.csm.air.writeServerEvent('account-login', clientId=self.target, accId=self.accountId, webAccId=self.databaseId, cookie=self.cookie) self.csm.sendUpdateToChannel(self.target, 'acceptLogin', []) self.demand('Off')
def login(self, cookie, sessionKey): self.notify.debug('Received login cookie %r from %d' % (cookie, self.air.getMsgSender())) sender = self.air.getMsgSender() if not self.loginsEnabled: # Logins are currently disabled... RIP! dg = PyDatagram() dg.addServerHeader(sender, self.air.ourChannel, CLIENTAGENT_EJECT) dg.addUint16(200) dg.addString( 'Logins are currently disabled. Please try again later.') self.air.send(dg) if sender >> 32: # Oops, they have an account ID on their connection already! self.killConnection(sender, 'Client is already logged in.') return if sender in self.connection2fsm: # Hot fix for potential toons that's FSM is stuck in state. self.connection2fsm[sender].demand('Off') # kick the client because there is a major issue! self.killConnection( sender, 'Failed to login, because your account is already in FSM state!' ) return if sessionKey != self.sessionKey: self.killConnection( sender, 'Failed to login, recieved a bad login cookie!') # notify the admin that someone tried to login with a custom client. self.notify.warning( '%s: Tried to login with a custom client using sessionKey, %s!' % (sender, str(sessionKey))) return if self.banManager.getToonBanned(cookie): self.killConnection(sender, self.banManager.getToonBanReason(cookie)) return self.connection2fsm[sender] = LoginAccountFSM(self, sender) self.connection2fsm[sender].request('Start', cookie)
def __handleSetAccount(self): # if somebody's already logged into this account, disconnect them datagram = PyDatagram() datagram.addServerHeader( self.loginManager.GetAccountConnectionChannel(self.accountId), self.loginManager.air.ourChannel, CLIENTAGENT_EJECT) datagram.addUint16(100) datagram.addString('This account has been logged in elsewhere.') self.loginManager.air.send(datagram) # add connection to account channel datagram = PyDatagram() datagram.addServerHeader(self.sender, self.loginManager.air.ourChannel, CLIENTAGENT_OPEN_CHANNEL) datagram.addChannel( self.loginManager.GetAccountConnectionChannel(self.accountId)) self.loginManager.air.send(datagram) # set sender channel to represent account affiliation datagram = PyDatagram() datagram.addServerHeader(self.sender, self.loginManager.air.ourChannel, CLIENTAGENT_SET_CLIENT_ID) datagram.addChannel( self.accountId << 32) # accountId is in high 32 bits, 0 in low (no avatar). self.loginManager.air.send(datagram) # set client state to established, thus un-sandboxing the sender self.loginManager.air.setClientState(self.sender, 2) responseData = { 'returnCode': 0, 'respString': '', 'accountNumber': self.sender, 'createFriendsWithChat': 'YES', 'chatCodeCreationRule': 'YES', 'access': 'FULL', 'WhiteListResponse': 'YES', 'lastLoggedInStr': self.getLastLoggedInStr(), 'accountDays': self.getAccountDays(), 'serverTime': int(time.time()), 'toonAccountType': 'NO_PARENT_ACCOUNT', 'userName': str(self.databaseId) } responseBlob = json.dumps(responseData) self.loginManager.sendUpdateToChannel(self.sender, 'loginResponse', [responseBlob]) self._handleDone()
def __comingOnlineFriendOnline(self, avId, activated, otherId=None): if not (otherId and activated): return dg = PyDatagram() dg.addServerHeader(self.GetPuppetConnectionChannel(avId), self.air.ourChannel, CLIENTAGENT_DECLARE_OBJECT) dg.addUint32(otherId) dg.addUint16(self.air.dclassesByName['DistributedToonUD'].getNumber()) self.air.send(dg) dg = PyDatagram() dg.addServerHeader(self.GetPuppetConnectionChannel(otherId), self.air.ourChannel, CLIENTAGENT_DECLARE_OBJECT) dg.addUint32(avId) dg.addUint16(self.air.dclassesByName['DistributedToonUD'].getNumber()) self.air.send(dg) self.sendUpdateToAvatarId(avId, 'friendOnline', [otherId, 0, 0])
def setAllowClientSend(self, avId, distObj, fieldNameList=[]): dg = PyDatagram() dg.addServerHeader(distObj.GetPuppetConnectionChannel(avId), self.ourChannel, CLIENTAGENT_SET_FIELDS_SENDABLE) fieldIds = [] for fieldName in fieldNameList: field = distObj.dclass.getFieldByName(fieldName) if field: fieldIds.append(field.getNumber()) dg.addUint32(distObj.getDoId()) dg.addUint16(len(fieldIds)) for fieldId in fieldIds: dg.addUint16(fieldId) self.send(dg)
def enterSetAccount(self): # First, if there's anybody on the account, kill them for redundant login: datagram = PyDatagram() datagram.addServerHeader( self.csm.GetAccountConnectionChannel(self.accountId), self.csm.air.ourChannel, CLIENTAGENT_EJECT) datagram.addUint16(100) datagram.addString('This account has been logged in from elsewhere.') self.csm.air.send(datagram) # Next, add this connection to the account channel. datagram = PyDatagram() datagram.addServerHeader(self.target, self.csm.air.ourChannel, CLIENTAGENT_OPEN_CHANNEL) datagram.addChannel( self.csm.GetAccountConnectionChannel(self.accountId)) self.csm.air.send(datagram) # Now set their sender channel to represent their account affiliation: datagram = PyDatagram() datagram.addServerHeader(self.target, self.csm.air.ourChannel, CLIENTAGENT_SET_CLIENT_ID) # Account ID in high 32 bits, 0 in low (no avatar): datagram.addChannel(self.accountId << 32) self.csm.air.send(datagram) # Un-sandbox them! datagram = PyDatagram() datagram.addServerHeader(self.target, self.csm.air.ourChannel, CLIENTAGENT_SET_STATE) datagram.addUint16(2) # ESTABLISHED self.csm.air.send(datagram) # Update the last login timestamp: self.csm.air.dbInterface.updateObject( self.csm.air.dbId, self.accountId, self.csm.air.dclassesByName['AccountUD'], { 'LAST_LOGIN': time.ctime(time.mktime(time.gmtime())), 'ACCOUNT_ID': str(self.userId) }) # We're done. self.csm.air.writeServerEvent('accountLogin', self.target, self.accountId, self.userId) self.csm.sendUpdateToChannel(self.target, 'acceptLogin', [int(time.mktime(time.gmtime()))]) self.demand('Off')
def enterSetAccount(self): # First, if there's anybody on the account, kill 'em for redundant login: dg = PyDatagram() dg.addServerHeader(self.csm.GetAccountConnectionChannel(self.accountId), self.csm.air.ourChannel, CLIENTAGENT_EJECT) dg.addUint16(100) dg.addString('This account has been logged in elsewhere.') self.csm.air.send(dg) # Next, add this connection to the account channel. dg = PyDatagram() dg.addServerHeader(self.target, self.csm.air.ourChannel, CLIENTAGENT_OPEN_CHANNEL) dg.addChannel(self.csm.GetAccountConnectionChannel(self.accountId)) self.csm.air.send(dg) # Now set their sender channel to represent their account affiliation: dg = PyDatagram() dg.addServerHeader(self.target, self.csm.air.ourChannel, CLIENTAGENT_SET_CLIENT_ID) dg.addChannel(self.accountId << 32) # accountId in high 32 bits, 0 in low (no avatar) self.csm.air.send(dg) # Un-sandbox them! dg = PyDatagram() dg.addServerHeader(self.target, self.csm.air.ourChannel, CLIENTAGENT_SET_STATE) dg.addUint16(2) # ESTABLISHED state. self.csm.air.send(dg) fields = {'LAST_LOGIN': time.ctime(), 'ACCOUNT_ID': str(self.databaseId)} if self.adminAccess != -1: fields.update({'ADMIN_ACCESS': self.adminAccess}) # Update the last login timestamp: self.csm.air.dbInterface.updateObject( self.csm.air.dbId, self.accountId, self.csm.air.dclassesByName['AccountUD'], fields) # We're done. self.csm.air.writeServerEvent('accountLogin', self.target, self.accountId, self.databaseId) self.csm.sendUpdateToChannel(self.target, 'acceptLogin', []) self.csm.account2username[self.target] = self.username self.demand('Off')
def login(self, cookie, sessionKey): sender = self.air.getMsgSender() #if not self.AccountFirewallUD.checkPlayerLogin(cookie): # self.killConnection(sender, 'Your account has been disallowed login to Project Altis. Please try again later.') # return self.notify.debug('Received login cookie %r from %d' % (cookie, sender)) if not self.loginsEnabled: # Logins are currently disabled... RIP! dg = PyDatagram() dg.addServerHeader(sender, self.air.ourChannel, CLIENTAGENT_EJECT) dg.addUint16(200) dg.addString( 'Logins are currently disabled. Please try again later.') self.air.send(dg) if sender >> 32: # Oops, they have an account ID on their connection already! self.killConnection(sender, 'Client is already logged in.') return if sender in self.connection2fsm: # hot fix, remove the sender from the fsm and request the fsm state OFF self.connection2fsm[sender].demand('Off') if sessionKey != self.sessionKey: self.killConnection( sender, 'Failed to login, recieved a bad login cookie!') # notify the admin that someone tried to login with a custom client. self.notify.warning('%s: Tried to login with a custom client!' % (sender)) return if self.banManager.getToonBanned(cookie): self.killConnection(sender, self.banManager.getToonBanReason(cookie)) return self.connection2fsm[sender] = LoginAccountFSM(self, sender) self.connection2fsm[sender].request('Start', cookie)
def __comingOnlineFriendOnline(self, avId, activated, otherId=None): if not (otherId and activated): #??!?!? return # Declare our avatar to their friend. dg = PyDatagram() dg.addServerHeader(self.GetPuppetConnectionChannel(avId), self.air.ourChannel, CLIENTAGENT_DECLARE_OBJECT) dg.addUint32(otherId) dg.addUint16(self.air.dclassesByName['DistributedToonUD'].getNumber()) self.air.send(dg) # Declare the friend to the avatar. dg = PyDatagram() dg.addServerHeader(self.GetPuppetConnectionChannel(otherId), self.air.ourChannel, CLIENTAGENT_DECLARE_OBJECT) dg.addUint32(avId) dg.addUint16(self.air.dclassesByName['DistributedToonUD'].getNumber()) self.air.send(dg) # Tell the client their friend is online. self.sendUpdateToAvatarId(avId, 'friendOnline', [otherId, 0, 0])
def login(self, cookie, sig, secret): self.notify.debug('Received login cookie %r from %d' % (cookie, self.air.getMsgSender())) sender = self.air.getMsgSender() if not self.loginsEnabled: # Logins are currently disabled... RIP! dg = PyDatagram() dg.addServerHeader(sender, self.air.ourChannel, CLIENTAGENT_EJECT) dg.addUint16(200) dg.addString( 'Logins are currently disabled. Please try again later.') self.air.send(dg) if sender >> 32: # Oops, they have an account ID on their connection already! self.killConnection(sender, 'Client is already logged in.') return # Test Server Secret serversecret = config.GetString('csmud-secret', 'streetlamps') if secret != serversecret: self.killConnection(sender, 'The accounts database rejcts you secret key') return # Test the signature key = config.GetString( 'csmud-secret', 'streetlamps') + config.GetString( 'server-version', 'no_version_set') + FIXED_KEY computedSig = hmac.new(key, cookie, hashlib.sha256).digest() if sig != computedSig: self.killConnection(sender, 'The accounts database rejected your cookie') return if sender in self.connection2fsm: self.killConnectionFSM(sender) return self.connection2fsm[sender] = LoginAccountFSM(self, sender) self.connection2fsm[sender].request('Start', cookie)
def inviteeFriendResponse(self, response, context): avId = self.air.getAvatarIdFromSender() if not context in self.requests: self.air.writeServerEvent('suspicious', avId=avId, issue='Player tried to respond to a friend request that doesn\'t exist!') return if avId != self.requests[context][0][1]: self.air.writeServerEvent('suspicious', avId=avId, issue='Player tried to respond to someone else\'s request!') return if self.requests[context][1] == 'cancelled': self.air.writeServerEvent('suspicious', avId=avId, issue='Player tried to respond to non-active friend request!') return self.sendUpdateToAvatarId(self.requests[context][0][0], 'friendResponse', [response, context]) if response == 1: requested = self.air.doId2do.get(self.requests[context][0][1]) requester = self.air.doId2do.get(self.requests[context][0][0]) if not (requested and requester): # Likely they logged off just before a response was sent. RIP. return # Allow both toons to teleport to each other. dg = PyDatagram() dg.addServerHeader(self.GetPuppetConnectionChannel(requested.getDoId()), self.air.ourChannel, CLIENTAGENT_DECLARE_OBJECT) dg.addUint32(requester.getDoId()) dg.addUint16(self.air.dclassesByName['DistributedToonAI'].getNumber()) self.air.send(dg) dg = PyDatagram() dg.addServerHeader(self.GetPuppetConnectionChannel(requester.getDoId()), self.air.ourChannel, CLIENTAGENT_DECLARE_OBJECT) dg.addUint32(requested.getDoId()) dg.addUint16(self.air.dclassesByName['DistributedToonAI'].getNumber()) self.air.send(dg) requested.extendFriendsList(requester.getDoId(), 0) requester.extendFriendsList(requested.getDoId(), 0) requested.d_setFriendsList(requested.getFriendsList()) requester.d_setFriendsList(requester.getFriendsList()) del self.requests[context]
def enterSetAccount(self): datagram = PyDatagram() datagram.addServerHeader( self.gameServicesManager.GetAccountConnectionChannel( self.accountId), self.gameServicesManager.air.ourChannel, CLIENTAGENT_EJECT) datagram.addUint16(OTPGlobals.BootedLoggedInElsewhere) datagram.addString('This account has been logged into elsewhere.') self.gameServicesManager.air.send(datagram) datagram = PyDatagram() datagram.addServerHeader(self.target, self.gameServicesManager.air.ourChannel, CLIENTAGENT_OPEN_CHANNEL) datagram.addChannel( self.gameServicesManager.GetAccountConnectionChannel( self.accountId)) self.gameServicesManager.air.send(datagram) datagram = PyDatagram() datagram.addServerHeader(self.target, self.gameServicesManager.air.ourChannel, CLIENTAGENT_SET_CLIENT_ID) datagram.addChannel(self.accountId << 32) self.gameServicesManager.air.send(datagram) self.gameServicesManager.air.setClientState(self.target, 2) self.gameServicesManager.air.dbInterface.updateObject( self.gameServicesManager.air.dbId, self.accountId, self.gameServicesManager.air.dclassesByName['AccountUD'], { 'LAST_LOGIN': time.ctime(), 'ACCOUNT_ID': str(self.databaseId), 'ACCESS_LEVEL': self.accessLevel }) self.gameServicesManager.air.writeServerEvent('account-login', clientId=self.target, accId=self.accountId, dbId=self.databaseId, playToken=self.playToken) self.gameServicesManager.sendUpdateToChannel(self.target, 'acceptLogin', []) self.demand('Off')
def d_setShardData(self): dg = PyDatagram() self.context += 1 self.context %= 200 dg.addUint8(self.context) buildings = self.air.doFindAllInstances( DistributedBuildingAI.DistributedBuildingAI) for bldg in buildings: if bldg.__class__ in ( DistributedBuildingAI.DistributedBuildingAI, DistributedAnimBuildingAI.DistributedAnimBuildingAI): if not bldg.zoneId % 1000: # sz bldg, ignore continue if bldg.zoneId // 1000 == 7: # ff bldg, ignore now continue data = bldg.getPickleData() dg.addString("block") dg.addUint16(bldg.zoneId - (bldg.zoneId % 1000)) dg.addUint16(bldg.zoneId) dg.addUint8(int(data['block'])) dg.addString(data['state'].lower()) dg.addUint8(ord(data['track'])) dg.addUint8(int(data['difficulty'])) dg.addInt8(int(data['numFloors'])) self.bldgs.add(bldg) self.writeInvasion(dg) self.sendUpdate("setShardData", [dg.getMessage()]) self.air.notify.info("Sent shard data to UD") taskMgr.doMethodLater(60, self.__timeout, 'UD-sync-timeout')
def __handleSetAvatar(self): channel = self.loginManager.GetAccountConnectionChannel(self.sender) cleanupDatagram = PyDatagram() cleanupDatagram.addServerHeader(self.avId, channel, STATESERVER_OBJECT_DELETE_RAM) cleanupDatagram.addUint32(self.avId) datagram = PyDatagram() datagram.addServerHeader(channel, self.loginManager.air.ourChannel, CLIENTAGENT_ADD_POST_REMOVE) datagram.addUint16(cleanupDatagram.getLength()) datagram.appendData(cleanupDatagram.getMessage()) self.loginManager.air.send(datagram) self.loginManager.air.sendActivate( self.avId, 0, 0, self.loginManager.air.dclassesByName['DistributedToonUD']) datagram = PyDatagram() datagram.addServerHeader(channel, self.loginManager.air.ourChannel, CLIENTAGENT_OPEN_CHANNEL) datagram.addChannel( self.loginManager.GetPuppetConnectionChannel(self.avId)) self.loginManager.air.send(datagram) self.loginManager.air.clientAddSessionObject(channel, self.avId) datagram = PyDatagram() datagram.addServerHeader(channel, self.loginManager.air.ourChannel, CLIENTAGENT_SET_CLIENT_ID) datagram.addChannel( self.sender << 32 | self.avId) # accountId in high 32 bits, avatar in low. self.loginManager.air.send(datagram) self.loginManager.air.setOwner(self.avId, channel) self._handleDone()
def d_updateBlock(self, bldg): if not bldg in self.bldgs: return data = bldg.getPickleData() dg = PyDatagram() dg.addUint16(bldg.zoneId - (bldg.zoneId % 1000)) dg.addUint16(bldg.zoneId) dg.addUint8(int(data['block'])) state = data['state'].lower() if state.startswith('clear'): state = 'cogdo' if state.endswith('cogdo') else 'suit' dg.addString(state) dg.addUint8(ord(data['track'])) dg.addUint8(int(data['difficulty'])) dg.addInt8(int(data['numFloors'])) self.sendUpdate("doUpdate", ["block", dg.getMessage()])
def d_setShardData(self): dg = PyDatagram() self.context += 1 self.context %= 200 dg.addUint8(self.context) buildings = self.air.doFindAllInstances(DistributedBuildingAI.DistributedBuildingAI) for bldg in buildings: if bldg.__class__ in (DistributedBuildingAI.DistributedBuildingAI, DistributedAnimBuildingAI.DistributedAnimBuildingAI): if not bldg.zoneId % 1000: # sz bldg, ignore continue if bldg.zoneId // 1000 == 7: # ff bldg, ignore now continue data = bldg.getPickleData() dg.addString("block") dg.addUint16(bldg.zoneId - (bldg.zoneId % 1000)) dg.addUint16(bldg.zoneId) dg.addUint8(int(data['block'])) dg.addString(data['state'].lower()) dg.addUint8(ord(data['track'])) dg.addUint8(int(data['difficulty'])) dg.addInt8(int(data['numFloors'])) self.bldgs.add(bldg) self.writeInvasion(dg) self.sendUpdate("setShardData", [dg.getMessage()]) self.air.notify.info("Sent shard data to UD") taskMgr.doMethodLater(60, self.__timeout, 'UD-sync-timeout')
def enterSetAccount(self): # First, if there's anybody on the account, kill 'em for redundant login: dg = PyDatagram() dg.addServerHeader( self.csm.GetAccountConnectionChannel(self.accountId), self.csm.air.ourChannel, CLIENTAGENT_EJECT ) dg.addUint16(100) dg.addString("This account has been logged in elsewhere.") self.csm.air.send(dg) # Next, add this connection to the account channel. dg = PyDatagram() dg.addServerHeader(self.target, self.csm.air.ourChannel, CLIENTAGENT_OPEN_CHANNEL) dg.addChannel(self.csm.GetAccountConnectionChannel(self.accountId)) self.csm.air.send(dg) # Subscribe to any "staff" channels that the account has access to. access = self.account.get("ADMIN_ACCESS", 0) if access >= 200: # Subscribe to the moderator channel. dg = PyDatagram() dg.addServerHeader(self.target, self.csm.air.ourChannel, CLIENTAGENT_OPEN_CHANNEL) dg.addChannel(OtpDoGlobals.OTP_MOD_CHANNEL) self.csm.air.send(dg) if access >= 400: # Subscribe to the administrator channel. dg = PyDatagram() dg.addServerHeader(self.target, self.csm.air.ourChannel, CLIENTAGENT_OPEN_CHANNEL) dg.addChannel(OtpDoGlobals.OTP_ADMIN_CHANNEL) self.csm.air.send(dg) if access >= 500: # Subscribe to the system administrator channel. dg = PyDatagram() dg.addServerHeader(self.target, self.csm.air.ourChannel, CLIENTAGENT_OPEN_CHANNEL) dg.addChannel(OtpDoGlobals.OTP_SYSADMIN_CHANNEL) self.csm.air.send(dg) # Now set their sender channel to represent their account affiliation: dg = PyDatagram() dg.addServerHeader(self.target, self.csm.air.ourChannel, CLIENTAGENT_SET_CLIENT_ID) dg.addChannel(self.accountId << 32) # accountId in high 32 bits, 0 in low (no avatar) self.csm.air.send(dg) # Un-sandbox them! dg = PyDatagram() dg.addServerHeader(self.target, self.csm.air.ourChannel, CLIENTAGENT_SET_STATE) dg.addUint16(2) # ESTABLISHED state. BIG FAT SECURITY RISK!!! self.csm.air.send(dg) # Update the last login timestamp: self.csm.air.dbInterface.updateObject( self.csm.air.dbId, self.accountId, self.csm.air.dclassesByName["AccountUD"], { "LAST_LOGIN": time.ctime(), "ACCOUNT_ID": self.databaseId, "ADMIN_ACCESS": self.adminAccess, "BETA_KEY_QUEST": self.betaKeyQuest, }, ) # Add a POST_REMOVE to the connection channel to execute the NetMessenger # message when the account connection goes RIP on the Client Agent. dgcleanup = self.csm.air.netMessenger.prepare("accountDisconnected", [self.accountId]) dg = PyDatagram() dg.addServerHeader(self.target, self.csm.air.ourChannel, CLIENTAGENT_ADD_POST_REMOVE) dg.addString(dgcleanup.getMessage()) self.csm.air.send(dg) # We're done. self.csm.air.writeServerEvent( "account-login", clientId=self.target, accId=self.accountId, webAccId=self.databaseId, cookie=self.cookie ) self.csm.sendUpdateToChannel(self.target, "acceptLogin", []) self.demand("Off")
def enterSetAccount(self): # If necessary, update their account information: if self.accessLevel: self.csm.air.dbInterface.updateObject( self.csm.air.dbId, self.accountId, self.csm.air.dclassesByName['AccountUD'], {'ACCESS_LEVEL': self.accessLevel}) # If there's anybody on the account, kill them for redundant login: datagram = PyDatagram() datagram.addServerHeader( self.csm.GetAccountConnectionChannel(self.accountId), self.csm.air.ourChannel, CLIENTAGENT_EJECT) datagram.addUint16(100) datagram.addString('This account has been logged in from elsewhere.') self.csm.air.send(datagram) # Next, add this connection to the account channel. datagram = PyDatagram() datagram.addServerHeader(self.target, self.csm.air.ourChannel, CLIENTAGENT_OPEN_CHANNEL) datagram.addChannel( self.csm.GetAccountConnectionChannel(self.accountId)) self.csm.air.send(datagram) # Subscribe to any "staff" channels that the account has access to. access = self.account.get('ADMIN_ACCESS', 0) if access >= 200: # Subscribe to the moderator channel. dg = PyDatagram() dg.addServerHeader(self.target, self.csm.air.ourChannel, CLIENTAGENT_OPEN_CHANNEL) dg.addChannel(OtpDoGlobals.OTP_MOD_CHANNEL) self.csm.air.send(dg) if access >= 400: # Subscribe to the administrator channel. dg = PyDatagram() dg.addServerHeader(self.target, self.csm.air.ourChannel, CLIENTAGENT_OPEN_CHANNEL) dg.addChannel(OtpDoGlobals.OTP_ADMIN_CHANNEL) self.csm.air.send(dg) if access >= 500: # Subscribe to the system administrator channel. dg = PyDatagram() dg.addServerHeader(self.target, self.csm.air.ourChannel, CLIENTAGENT_OPEN_CHANNEL) dg.addChannel(OtpDoGlobals.OTP_SYSADMIN_CHANNEL) self.csm.air.send(dg) # Now set their sender channel to represent their account affiliation: datagram = PyDatagram() datagram.addServerHeader(self.target, self.csm.air.ourChannel, CLIENTAGENT_SET_CLIENT_ID) # Account ID in high 32 bits, 0 in low (no avatar): datagram.addChannel(self.accountId << 32) self.csm.air.send(datagram) # Un-sandbox them! datagram = PyDatagram() datagram.addServerHeader(self.target, self.csm.air.ourChannel, CLIENTAGENT_SET_STATE) datagram.addUint16(2) # ESTABLISHED self.csm.air.send(datagram) # Update the last login timestamp: self.csm.air.dbInterface.updateObject( self.csm.air.dbId, self.accountId, self.csm.air.dclassesByName['AccountUD'], { 'LAST_LOGIN': time.ctime(), 'LAST_LOGIN_TS': time.time(), 'ACCOUNT_ID': str(self.userId) }) # We're done. self.csm.air.writeServerEvent('accountLogin', self.target, self.accountId, self.userId) self.csm.sendUpdateToChannel(self.target, 'acceptLogin', [int(time.time())]) self.demand('Off')
def enterSetAccount(self): # If necessary, update their account information: if self.accessLevel: self.csm.air.dbInterface.updateObject( self.csm.air.dbId, self.accountId, self.csm.air.dclassesByName['AccountUD'], {'ACCESS_LEVEL': self.accessLevel}) # If there's anybody on the account, kill them for redundant login: datagram = PyDatagram() datagram.addServerHeader( self.csm.GetAccountConnectionChannel(self.accountId), self.csm.air.ourChannel, CLIENTAGENT_EJECT) datagram.addUint16(100) datagram.addString('This account has been logged in from elsewhere.') self.csm.air.send(datagram) # Next, add this connection to the account channel. datagram = PyDatagram() datagram.addServerHeader( self.target, self.csm.air.ourChannel, CLIENTAGENT_OPEN_CHANNEL) datagram.addChannel(self.csm.GetAccountConnectionChannel(self.accountId)) self.csm.air.send(datagram) # Subscribe to any "staff" channels that the account has access to. access = self.account.get('ADMIN_ACCESS', 0) if access >= 200: # Subscribe to the moderator channel. dg = PyDatagram() dg.addServerHeader(self.target, self.csm.air.ourChannel, CLIENTAGENT_OPEN_CHANNEL) dg.addChannel(OtpDoGlobals.OTP_MOD_CHANNEL) self.csm.air.send(dg) if access >= 400: # Subscribe to the administrator channel. dg = PyDatagram() dg.addServerHeader(self.target, self.csm.air.ourChannel, CLIENTAGENT_OPEN_CHANNEL) dg.addChannel(OtpDoGlobals.OTP_ADMIN_CHANNEL) self.csm.air.send(dg) if access >= 500: # Subscribe to the system administrator channel. dg = PyDatagram() dg.addServerHeader(self.target, self.csm.air.ourChannel, CLIENTAGENT_OPEN_CHANNEL) dg.addChannel(OtpDoGlobals.OTP_SYSADMIN_CHANNEL) self.csm.air.send(dg) # Now set their sender channel to represent their account affiliation: datagram = PyDatagram() datagram.addServerHeader( self.target, self.csm.air.ourChannel, CLIENTAGENT_SET_CLIENT_ID) # Account ID in high 32 bits, 0 in low (no avatar): datagram.addChannel(self.accountId << 32) self.csm.air.send(datagram) # Un-sandbox them! datagram = PyDatagram() datagram.addServerHeader( self.target, self.csm.air.ourChannel, CLIENTAGENT_SET_STATE) datagram.addUint16(2) # ESTABLISHED self.csm.air.send(datagram) # Update the last login timestamp: self.csm.air.dbInterface.updateObject( self.csm.air.dbId, self.accountId, self.csm.air.dclassesByName['AccountUD'], {'LAST_LOGIN': time.ctime(), 'LAST_LOGIN_TS': time.time(), 'ACCOUNT_ID': str(self.userId)}) # We're done. self.csm.air.writeServerEvent('accountLogin', self.target, self.accountId, self.userId) self.csm.sendUpdateToChannel(self.target, 'acceptLogin', [int(time.time())]) self.demand('Off')
def enterSetAccount(self): # First, if there's anybody on the account, kill 'em for redundant login: dg = PyDatagram() dg.addServerHeader( self.csm.GetAccountConnectionChannel(self.accountId), self.csm.air.ourChannel, CLIENTAGENT_EJECT) dg.addUint16(100) dg.addString('This account has been logged in elsewhere.') self.csm.air.send(dg) # Next, add this connection to the account channel. dg = PyDatagram() dg.addServerHeader(self.target, self.csm.air.ourChannel, CLIENTAGENT_OPEN_CHANNEL) dg.addChannel(self.csm.GetAccountConnectionChannel(self.accountId)) self.csm.air.send(dg) # Subscribe to any "staff" channels that the account has access to. access = self.account.get('ADMIN_ACCESS', 0) if access >= 200: # Subscribe to the moderator channel. dg = PyDatagram() dg.addServerHeader(self.target, self.csm.air.ourChannel, CLIENTAGENT_OPEN_CHANNEL) dg.addChannel(OtpDoGlobals.OTP_MOD_CHANNEL) self.csm.air.send(dg) if access >= 400: # Subscribe to the administrator channel. dg = PyDatagram() dg.addServerHeader(self.target, self.csm.air.ourChannel, CLIENTAGENT_OPEN_CHANNEL) dg.addChannel(OtpDoGlobals.OTP_ADMIN_CHANNEL) self.csm.air.send(dg) if access >= 405: # Subscribe to the developer channel. dg = PyDatagram() dg.addServerHeader(self.target, self.csm.air.ourChannel, CLIENTAGENT_OPEN_CHANNEL) dg.addChannel(OtpDoGlobals.OTP_DEV_CHANNEL) self.csm.air.send(dg) if access >= 500: # Subscribe to the system administrator channel. dg = PyDatagram() dg.addServerHeader(self.target, self.csm.air.ourChannel, CLIENTAGENT_OPEN_CHANNEL) dg.addChannel(OtpDoGlobals.OTP_SYSADMIN_CHANNEL) self.csm.air.send(dg) # Now set their sender channel to represent their account affiliation: dg = PyDatagram() dg.addServerHeader(self.target, self.csm.air.ourChannel, CLIENTAGENT_SET_CLIENT_ID) dg.addChannel(self.accountId << 32) # accountId in high 32 bits, 0 in low (no avatar) self.csm.air.send(dg) # Un-sandbox them! dg = PyDatagram() dg.addServerHeader(self.target, self.csm.air.ourChannel, CLIENTAGENT_SET_STATE) dg.addUint16(2) # ESTABLISHED state. BIG FAT SECURITY RISK!!! self.csm.air.send(dg) # Update the last login timestamp: self.csm.air.dbInterface.updateObject( self.csm.air.dbId, self.accountId, self.csm.air.dclassesByName['AccountUD'], { 'LAST_LOGIN': time.ctime(), 'ACCOUNT_ID': str(self.databaseId), 'BETA_KEY_QUEST': self.betaKeyQuest }) # Add a POST_REMOVE to the connection channel to execute the NetMessenger # message when the account connection goes RIP on the Client Agent. dgcleanup = self.csm.air.netMessenger.prepare('accountDisconnected', [self.accountId]) dg = PyDatagram() dg.addServerHeader(self.target, self.csm.air.ourChannel, CLIENTAGENT_ADD_POST_REMOVE) dg.addString(dgcleanup.getMessage()) self.csm.air.send(dg) # We're done. self.csm.air.writeServerEvent('account-login', clientId=self.target, accId=self.accountId, webAccId=self.databaseId, cookie=self.cookie) self.csm.sendUpdateToChannel(self.target, 'acceptLogin', []) self.demand('Off')
def submitSecret(self, secret): avId = self.air.getAvatarIdFromSender() av = self.air.doId2do.get(avId) if not av: return secretInfo = self.tfCodes.get(secret) if not secretInfo: self.d_submitSecretResponse(avId, 0, 0) return friendId = secretInfo[0] friend = self.air.doId2do.get(friendId) if av: if friend: if avId == friendId: self.d_submitSecretResponse(avId, 3, 0) self.removeSecret(secret) elif len(friend.getFriendsList() ) >= OTPGlobals.MaxFriends or len( av.getFriendsList()) >= OTPGlobals.MaxFriends: self.d_submitSecretResponse(avId, 2, friendId) else: dg = PyDatagram() dg.addServerHeader( self.GetPuppetConnectionChannel(friendId), self.air.ourChannel, CLIENTAGENT_DECLARE_OBJECT) dg.addUint32(avId) dg.addUint16(self.air.dclassesByName['DistributedToonAI']. getNumber()) self.air.send(dg) dg = PyDatagram() dg.addServerHeader(self.GetPuppetConnectionChannel(avId), self.air.ourChannel, CLIENTAGENT_DECLARE_OBJECT) dg.addUint32(friendId) dg.addUint16(self.air.dclassesByName['DistributedToonAI']. getNumber()) self.air.send(dg) friend.extendFriendsList(avId, 1) av.extendFriendsList(friendId, 1) friend.d_setFriendsList(friend.getFriendsList()) av.d_setFriendsList(av.getFriendsList()) self.d_submitSecretResponse(avId, 1, friendId) self.removeSecret(secret) else: # Friend is offline! def handleAvatar(dclass, fields): if dclass != self.air.dclassesByName['DistributedToonAI']: return newFriendsList = [] oldFriendsList = fields['setFriendsList'][0] if len(oldFriendsList) >= OTPGlobals.MaxFriends: self.d_submitSecretResponse(avId, 2, friendId) return for oldFriend in oldFriendsList: newFriendsList.append(oldFriend) newFriendsList.append((avId, 1)) self.air.dbInterface.updateObject( self.air.dbId, friendId, self.air.dclassesByName['DistributedToonAI'], {'setFriendsList': [newFriendsList]}) av.extendFriendsList(friendId, 1) av.d_setFriendsList(av.getFriendsList()) self.d_submitSecretResponse(avId, 1, friendId) self.removeSecret(secret) self.air.dbInterface.queryObject(self.air.dbId, friendId, handleAvatar) self.air.writeServerEvent('tf-code-submitted', avId=avId, friendId=friendId, tfCode=secret)