mirror of
https://github.com/Sneed-Group/Poodletooth-iLand
synced 2024-12-23 11:42:39 -06:00
csmud: adjust remotedb
This commit is contained in:
parent
0c04d9d876
commit
49b26c4103
3 changed files with 82 additions and 33 deletions
|
@ -87,7 +87,7 @@ def checkName(name, otherCheckFuncs = [], font = None):
|
|||
tn = TextNode('NameCheck')
|
||||
tn.setFont(font)
|
||||
for c in name:
|
||||
if not tn.hasCharacter(unicode(c)):
|
||||
if not tn.hasCharacter(c.decode('utf-8')):
|
||||
notify.info('name contains bad char: %s' % TextEncoder().encodeWtext(c))
|
||||
return OTPLocalizer.NCBadCharacter % TextEncoder().encodeWtext(c)
|
||||
|
||||
|
|
|
@ -1,29 +1,30 @@
|
|||
#!/usr/bin/env python2
|
||||
import json
|
||||
import os
|
||||
import requests
|
||||
from panda3d.core import *
|
||||
from pandac.PandaModules import *
|
||||
|
||||
|
||||
username = os.environ['ttsUsername']
|
||||
password = os.environ['ttsPassword']
|
||||
|
||||
accountServerEndpoint = ConfigVariableString(
|
||||
'account-server-endpoint',
|
||||
'http://tigercat1.me/tmpremote/api/').getValue()
|
||||
request = requests.post(
|
||||
accountServerEndpoint = 'http://www.toontownstride.com/api/'
|
||||
session = requests.Session()
|
||||
csrf_query = session.get(accountServerEndpoint + 'login/')
|
||||
csrf = session.cookies.get_dict().get('csrftoken', '')
|
||||
request = session.post(
|
||||
accountServerEndpoint + 'login/',
|
||||
data={'n': username, 'p': password})
|
||||
data={'username': username, 'password': password, 'csrfmiddlewaretoken': csrf})
|
||||
|
||||
try:
|
||||
response = json.loads(request.text)
|
||||
response = json.loads('{'+request.text.split('{', 1)[1]) # so that we ignore the csrf token
|
||||
except ValueError:
|
||||
print "Couldn't verify account credentials."
|
||||
else:
|
||||
if not response['success']:
|
||||
print response['reason']
|
||||
if response['status'] != 7:
|
||||
print response['message']
|
||||
else:
|
||||
os.environ['TTS_PLAYCOOKIE'] = response['token']
|
||||
os.environ['TTS_GAMESERVER'] = response['gameserver']
|
||||
|
||||
# Start the game:
|
||||
import toontown.toonbase.ClientStart
|
||||
|
|
|
@ -15,7 +15,7 @@ from panda3d.core import *
|
|||
|
||||
import hashlib, hmac, json
|
||||
import anydbm, math, os
|
||||
import urllib2, time
|
||||
import urllib2, time, urllib, base64
|
||||
|
||||
def rejectConfig(issue, securityIssue=True, retarded=True):
|
||||
print
|
||||
|
@ -42,10 +42,14 @@ def entropyIdeal(length):
|
|||
accountDBType = config.GetString('accountdb-type', 'developer')
|
||||
accountServerSecret = config.GetString('account-server-secret', 'dev')
|
||||
accountServerHashAlgo = config.GetString('account-server-hash-algo', 'sha512')
|
||||
apiSecret = accountServerSecret = config.GetString('api-key', 'dev')
|
||||
if accountDBType == 'remote':
|
||||
if accountServerSecret == 'dev':
|
||||
rejectConfig('you have not changed the secret in config/local.prc')
|
||||
|
||||
if apiSecret == 'dev':
|
||||
rejectConfig('you have not changed the api key in config/local.prc')
|
||||
|
||||
if len(accountServerSecret) < 16:
|
||||
rejectConfig('the secret is too small! Make it 16+ bytes', retarded=False)
|
||||
|
||||
|
@ -67,18 +71,17 @@ minAccessLevel = config.GetInt('min-access-level', 100)
|
|||
|
||||
def executeHttpRequest(url, **extras):
|
||||
# TO DO: THIS IS QUITE DISGUSTING
|
||||
# INSTEAD OF USING THE SAME SECRET, WE SHOULD HAVE AN API KEY EXCLUSIVE TO THAT
|
||||
# MOVE THIS TO ToontownInternalRepository (this might be interesting for AI)
|
||||
request = urllib2.Request('http://tigercat1.me/tmpremote/api/' + url)
|
||||
timestamp = str(int(time.time()))
|
||||
signature = hashlib.sha256(timestamp + accountServerSecret + "h*^ahJGHA017JI&A&*uyhU07")
|
||||
request.add_header('User-Agent', 'TTS-CSM')
|
||||
request.add_header('X-CSM-Timestamp', timestamp)
|
||||
request.add_header('X-CSM-Signature', signature.hexdigest())
|
||||
for k, v in extras.items():
|
||||
request.add_header('X-CSM-' + k, v)
|
||||
_data = {}
|
||||
if len(extras.items()) != 0:
|
||||
for k, v in extras.items():
|
||||
_data[k] = v
|
||||
signature = hashlib.sha512(json.dumps(_data) + apiSecret).hexdigest()
|
||||
data = urllib.urlencode({'data': json.dumps(_data), 'hmac': signature})
|
||||
req = urllib2.Request('http://www.toontownstride.com/api/' + url, data)
|
||||
req.get_method = lambda: "POST"
|
||||
try:
|
||||
return urllib2.urlopen(request).read()
|
||||
return urllib2.urlopen(req).read()
|
||||
except:
|
||||
return None
|
||||
|
||||
|
@ -103,7 +106,8 @@ def executeHttpRequestAndLog(url, **extras):
|
|||
|
||||
return data
|
||||
|
||||
blacklist = executeHttpRequest('names/blacklist.json')
|
||||
#blacklist = executeHttpRequest('names/blacklist.json') # todo; create a better system for this
|
||||
blacklist = json.dumps(["none"])
|
||||
if blacklist:
|
||||
blacklist = json.loads(blacklist)
|
||||
|
||||
|
@ -139,7 +143,7 @@ class AccountDB:
|
|||
def addNameRequest(self, avId, name):
|
||||
return True
|
||||
|
||||
def getNameStatus(self, avId):
|
||||
def getNameStatus(self, avId, callback = None):
|
||||
return 'APPROVED'
|
||||
|
||||
def removeNameRequest(self, avId):
|
||||
|
@ -183,17 +187,36 @@ class RemoteAccountDB(AccountDB):
|
|||
# CURRENTLY IT MAKES n REQUESTS FOR EACH AVATAR
|
||||
# IN THE FUTURE, MAKE ONLY 1 REQUEST
|
||||
# WHICH RETURNS ALL PENDING AVS
|
||||
# ^ done, check before removing todo note
|
||||
notify = directNotify.newCategory('RemoteAccountDB')
|
||||
|
||||
def addNameRequest(self, avId, name):
|
||||
return executeHttpRequest('names/append', ID=str(avId), Name=name)
|
||||
|
||||
def getNameStatus(self, avId):
|
||||
#return executeHttpRequest('names/status/?Id=' + str(avId))
|
||||
return 'APPROVED' # Override temporarily.
|
||||
def addNameRequest(self, avId, name, accountID = None):
|
||||
username = avId
|
||||
if accountID is not None:
|
||||
username = accountID
|
||||
|
||||
res = executeHttpRequest('names', action='set', username=str(username),
|
||||
avId=str(avId), wantedName=name)
|
||||
if res is not None:
|
||||
return True
|
||||
return False
|
||||
|
||||
def getNameStatus(self, accountId, callback = None):
|
||||
r = executeHttpRequest('names', action='get', username=str(accountId))
|
||||
try:
|
||||
r = json.loads(r)
|
||||
if callback is not None:
|
||||
callback(r)
|
||||
return True
|
||||
except:
|
||||
return False
|
||||
|
||||
def removeNameRequest(self, avId):
|
||||
return executeHttpRequest('names/remove', ID=str(avId))
|
||||
r = executeHttpRequest('names', action='del', avId=str(avId))
|
||||
if r:
|
||||
return 'SUCCESS'
|
||||
return 'FAILURE'
|
||||
|
||||
def lookup(self, token, callback):
|
||||
'''
|
||||
|
@ -213,7 +236,6 @@ class RemoteAccountDB(AccountDB):
|
|||
try:
|
||||
token = token.decode('base64')
|
||||
hash, token = token[:hashSize], token[hashSize:]
|
||||
|
||||
correctHash = hashAlgo(token + accountServerSecret).digest()
|
||||
if len(hash) != len(correctHash):
|
||||
raise ValueError('Invalid hash.')
|
||||
|
@ -234,6 +256,7 @@ class RemoteAccountDB(AccountDB):
|
|||
|
||||
return AccountDB.lookup(self, token, callback)
|
||||
|
||||
|
||||
# --- FSMs ---
|
||||
class OperationFSM(FSM):
|
||||
TARGET_CONNECTION = False
|
||||
|
@ -457,6 +480,9 @@ class CreateAvatarFSM(OperationFSM):
|
|||
|
||||
self.account = fields
|
||||
|
||||
# For use in calling name requests:
|
||||
self.accountID = self.account['ACCOUNT_ID']
|
||||
|
||||
self.avList = self.account['ACCOUNT_AV_SET']
|
||||
# Sanitize:
|
||||
self.avList = self.avList[:6]
|
||||
|
@ -508,6 +534,8 @@ class CreateAvatarFSM(OperationFSM):
|
|||
{'ACCOUNT_AV_SET': self.account['ACCOUNT_AV_SET']},
|
||||
self.__handleStoreAvatar)
|
||||
|
||||
self.accountID = self.account['ACCOUNT_ID']
|
||||
|
||||
def __handleStoreAvatar(self, fields):
|
||||
if fields:
|
||||
self.demand('Kill', 'Database failed to associate the new avatar to your account!')
|
||||
|
@ -533,6 +561,9 @@ class AvatarOperationFSM(OperationFSM):
|
|||
|
||||
self.account = fields
|
||||
|
||||
# For use in calling name requests:
|
||||
self.accountID = self.account['ACCOUNT_ID']
|
||||
|
||||
self.avList = self.account['ACCOUNT_AV_SET']
|
||||
# Sanitize:
|
||||
self.avList = self.avList[:6]
|
||||
|
@ -546,6 +577,7 @@ class GetAvatarsFSM(AvatarOperationFSM):
|
|||
|
||||
def enterStart(self):
|
||||
self.demand('RetrieveAccount')
|
||||
self.nameStateData = None
|
||||
|
||||
def enterQueryAvatars(self):
|
||||
self.pendingAvatars = set()
|
||||
|
@ -585,7 +617,10 @@ class GetAvatarsFSM(AvatarOperationFSM):
|
|||
if wishNameState == 'OPEN':
|
||||
nameState = 1
|
||||
elif wishNameState == 'PENDING':
|
||||
actualNameState = self.csm.accountDB.getNameStatus(avId)
|
||||
if self.nameStateData is None:
|
||||
self.demand('QueryNameState')
|
||||
return
|
||||
actualNameState = self.nameStateData[str(avId)]
|
||||
self.csm.air.dbInterface.updateObject(
|
||||
self.csm.air.dbId,
|
||||
avId,
|
||||
|
@ -610,6 +645,16 @@ class GetAvatarsFSM(AvatarOperationFSM):
|
|||
self.csm.sendUpdateToAccountId(self.target, 'setAvatars', [potentialAvs])
|
||||
self.demand('Off')
|
||||
|
||||
def enterQueryNameState(self):
|
||||
def gotStates(data):
|
||||
self.nameStateData = data
|
||||
taskMgr.doMethodLater(0, GetAvatarsFSM.demand, 'demand-QueryAvatars',
|
||||
extraArgs=[self, 'QueryAvatars'])
|
||||
|
||||
self.csm.accountDB.getNameStatus(self.account['ACCOUNT_ID'], gotStates)
|
||||
# We should've called the taskMgr action by now.
|
||||
|
||||
|
||||
# This inherits from GetAvatarsFSM, because the delete operation ends in a
|
||||
# setAvatars message being sent to the client.
|
||||
class DeleteAvatarFSM(GetAvatarsFSM):
|
||||
|
@ -671,6 +716,7 @@ class SetNameTypedFSM(AvatarOperationFSM):
|
|||
def enterStart(self, avId, name):
|
||||
self.avId = avId
|
||||
self.name = name
|
||||
self.set_account_id = None
|
||||
|
||||
if self.avId:
|
||||
self.demand('RetrieveAccount')
|
||||
|
@ -680,6 +726,8 @@ class SetNameTypedFSM(AvatarOperationFSM):
|
|||
self.demand('JudgeName')
|
||||
|
||||
def enterRetrieveAvatar(self):
|
||||
if self.accountID:
|
||||
self.set_account_id = self.accountID
|
||||
if self.avId and self.avId not in self.avList:
|
||||
self.demand('Kill', 'Tried to name an avatar not in the account!')
|
||||
return
|
||||
|
@ -703,7 +751,7 @@ class SetNameTypedFSM(AvatarOperationFSM):
|
|||
status = judgeName(self.name)
|
||||
|
||||
if self.avId and status:
|
||||
if self.csm.accountDB.addNameRequest(self.avId, self.name):
|
||||
if self.csm.accountDB.addNameRequest(self.avId, self.name, accountID=self.set_account_id):
|
||||
self.csm.air.dbInterface.updateObject(
|
||||
self.csm.air.dbId,
|
||||
self.avId,
|
||||
|
|
Loading…
Reference in a new issue