def sendFindOffer(self, address, item, timeout): ''' The method to be called for each thread. Finds the offer with itemId(item) of an address. @address (ip: string, port: int) @item: int @timeout float: timeout in seconds ''' # structure data toSend = {'method': 'findoffer', 'item': item} # setup connection mJSON = helpers.sendJSON(address, toSend, timeout) offers = mJSON['offers'] # convert back to our offer representation and update offers ref = self.offers[(address) + (item,)] = {} ref['lastUpdate'] = helpers.getCurrentTime() ref0 = ref['offers'] = {} for offer in offers: ref0[offer[-1]] = offer[:-1]
def move(self, userToken, x, y): """ Move a user. :param userToken: string :param x: int :param y: int :return: int, completion time in unix time :exception: TokenException, MoveException """ username = self.getNameByToken(userToken) if x < 0 or x >= self.gameMap.get('width') or y < 0 or y >= self.gameMap.get('height'): raise sisterexceptions.ActionException('position out of bounds') record = self.getRecordByName(username) prevX = record.get('x') prevY = record.get('y') if prevX == x and prevY == y: raise sisterexceptions.ActionException('invalid move') currTime = helpers.getCurrentTime() if record.get('actionTime') > currTime: raise sisterexceptions.ActionException('you are still moving') # time in seconds eachStep = 10 timeNeeded = (abs(prevX - x) + abs(prevY - y)) * eachStep unixTime = currTime + timeNeeded self.updateRecord(username, {'x': x, 'y': y, 'actionTime': unixTime}) return unixTime
def field(self, userToken): """ Collect item from current position. :param userToken: string :return: int, itemID of fetched item :exception: TokenException """ username = self.getNameByToken(userToken) mRecord = self.getRecordByName(username) if mRecord.get('actionTime') > helpers.getCurrentTime(): raise sisterexceptions.ActionException('you are still moving') curX = mRecord.get('x') curY = mRecord.get('y') pos = mRecord.get('lastField') width = self.gameMap.get('width') if pos: x = pos % width y = pos / width if x == curX and y == curY: raise sisterexceptions.ActionException('you already took that item') nameItem = self.gameMap.get('map')[curX][curY] index = helpers.mappingNameItemToIndex(nameItem) inventory = mRecord.get('inventory') inventory[index] += 1 self.updateRecord(username, {'inventory': inventory, 'lastField': curY * width + curX}) return index
def putOffer(self, token, offeredItem, n1, demandedItem, n2): username = self.getNameByToken(token) mRecord = self.getRecordByName(username) numItem = mRecord['inventory'][offeredItem] if numItem < n1: raise sisterexceptions.OfferException( 'insufficient number of offered item') # userOffers = self.registeredUser[username].get('offers') # if not userOffers: # userOffers = {} # generate offer unixTime = helpers.getCurrentTime() lOfferToken = [token, str(unixTime)] lOfferToken += [ self.salt, str(random.randint(-2147483648, 2147483647)) ] lOfferToken += [chr(ord('A') + offeredItem), str(n1)] lOfferToken += [chr(ord('A') + demandedItem), str(n2)] offerToken = hashlib.md5(''.join(lOfferToken)).hexdigest() # jadi di dalam add offer, otomatis uda dikurangi demanded item nya self.addOffer(username, offerToken, offeredItem, n1, demandedItem, n2, True)
def move(self, userToken, x, y): """ Move a user. :param userToken: string :param x: int :param y: int :return: int, completion time in unix time :exception: TokenException, MoveException """ username = self.getNameByToken(userToken) if x < 0 or x >= self.gameMap.get( 'width') or y < 0 or y >= self.gameMap.get('height'): raise sisterexceptions.ActionException('position out of bounds') record = self.getRecordByName(username) prevX = record.get('x') prevY = record.get('y') if prevX == x and prevY == y: raise sisterexceptions.ActionException('invalid move') currTime = helpers.getCurrentTime() if record.get('actionTime') > currTime: raise sisterexceptions.ActionException('you are still moving') # time in seconds eachStep = 10 timeNeeded = (abs(prevX - x) + abs(prevY - y)) * eachStep unixTime = currTime + timeNeeded self.updateRecord(username, {'x': x, 'y': y, 'actionTime': unixTime}) return unixTime
def login(self, name, password): """ Login a user. Return on success. :param name: string :param password: string :return: (token, x, y, time) :exception: UsernameException """ if name == '' or '{' in name or '}' in name: raise sisterexceptions.UsernameException( 'please use a good username') mRecord = self.getRecordByName(name) if mRecord.get('password') != hashlib.md5(password).hexdigest(): raise sisterexceptions.UsernameException( 'username/password combination is not found') actionTime = mRecord.get('actionTime') serverTime = helpers.getCurrentTime() token = hashlib.md5(name).hexdigest() self.setLogin(token, name) return token, mRecord.get('x'), mRecord.get( 'y'), actionTime, serverTime
def findOffers(self, item): """ Find Offers from foreign servers. :return: list of (offerid, n1, demandid, n2, availability, offerToken) """ # list of servers need to be searched for offers toSend = [] # result variable to return res = [] for address in self.servers: addressItem = (address.get('ip'), address.get('port'), item) if addressItem[:2] == self.myAddress: continue record = self.foreignOffers.get(addressItem) hit = False if record: # hit, check validity with timestamp unixTime = helpers.getCurrentTime() if unixTime < record.get('lastUpdate') + self.cacheTimeout: # hit! res += [ tuple(val) + (key, ) for key, val in record.get('offers').items() ] hit = True if not hit: # not hit, delete record and find on that server if record: self.foreignOffers.pop(addressItem) toSend.append(addressItem[:2]) oFinder = OffersFinder(toSend, item, 3) uncached, deadServers = oFinder.find() self.foreignOffers.update(uncached) for server in deadServers: self.removeServer(server) for key1, val1 in uncached.items(): res += [ tuple(val0) + (key0, ) for key0, val0 in val1.get('offers').items() ] return res
def findOffers(self, item): """ Find Offers from foreign servers. :return: list of (offerid, n1, demandid, n2, availability, offerToken) """ # list of servers need to be searched for offers toSend = [] # result variable to return res = [] for address in self.servers: addressItem = (address.get('ip'), address.get('port'), item) if addressItem[:2] == self.myAddress: continue record = self.foreignOffers.get(addressItem) hit = False if record: # hit, check validity with timestamp unixTime = helpers.getCurrentTime() if unixTime < record.get('lastUpdate') + self.cacheTimeout: # hit! res += [tuple(val) + (key,) for key, val in record.get('offers').items()] hit = True if not hit: # not hit, delete record and find on that server if record: self.foreignOffers.pop(addressItem) toSend.append(addressItem[:2]) oFinder = OffersFinder(toSend, item, 3) uncached, deadServers = oFinder.find() self.foreignOffers.update(uncached) for server in deadServers: self.removeServer(server) for key1, val1 in uncached.items(): res += [tuple(val0) + (key0,) for key0, val0 in val1.get('offers').items()] return res
def putOffer(self, token, offeredItem, n1, demandedItem, n2): username = self.getNameByToken(token) mRecord = self.getRecordByName(username) numItem = mRecord['inventory'][offeredItem] if numItem < n1: raise sisterexceptions.OfferException('insufficient number of offered item') # userOffers = self.registeredUser[username].get('offers') # if not userOffers: # userOffers = {} # generate offer unixTime = helpers.getCurrentTime() lOfferToken = [token, str(unixTime)] lOfferToken += [self.salt, str(random.randint(-2147483648, 2147483647))] lOfferToken += [chr(ord('A') + offeredItem), str(n1)] lOfferToken += [chr(ord('A') + demandedItem), str(n2)] offerToken = hashlib.md5(''.join(lOfferToken)).hexdigest() # jadi di dalam add offer, otomatis uda dikurangi demanded item nya self.addOffer(username, offerToken, offeredItem, n1, demandedItem, n2, True)
def field(self, userToken): """ Collect item from current position. :param userToken: string :return: int, itemID of fetched item :exception: TokenException """ username = self.getNameByToken(userToken) mRecord = self.getRecordByName(username) if mRecord.get('actionTime') > helpers.getCurrentTime(): raise sisterexceptions.ActionException('you are still moving') curX = mRecord.get('x') curY = mRecord.get('y') pos = mRecord.get('lastField') width = self.gameMap.get('width') if pos: x = pos % width y = pos / width if x == curX and y == curY: raise sisterexceptions.ActionException( 'you already took that item') nameItem = self.gameMap.get('map')[curX][curY] index = helpers.mappingNameItemToIndex(nameItem) inventory = mRecord.get('inventory') inventory[index] += 1 self.updateRecord(username, { 'inventory': inventory, 'lastField': curY * width + curX }) return index
def login(self, name, password): """ Login a user. Return on success. :param name: string :param password: string :return: (token, x, y, time) :exception: UsernameException """ if name == '' or '{' in name or '}' in name: raise sisterexceptions.UsernameException('please use a good username') mRecord = self.getRecordByName(name) if mRecord.get('password') != hashlib.md5(password).hexdigest(): raise sisterexceptions.UsernameException('username/password combination is not found') actionTime = mRecord.get('actionTime') serverTime = helpers.getCurrentTime() token = hashlib.md5(name).hexdigest() self.setLogin(token, name) return token, mRecord.get('x'), mRecord.get('y'), actionTime, serverTime
def sendFindOffer(self, address, item, timeout): ''' The method to be called for each thread. Finds the offer with itemId(item) of an address. @address (ip: string, port: int) @item: int @timeout float: timeout in seconds ''' # structure data toSend = {'method': 'findoffer', 'item': item} # setup connection mJSON = helpers.sendJSON(address, toSend, timeout) offers = mJSON['offers'] # convert back to our offer representation and update offers ref = self.offers[(address) + (item, )] = {} ref['lastUpdate'] = helpers.getCurrentTime() ref0 = ref['offers'] = {} for offer in offers: ref0[offer[-1]] = offer[:-1]