Commit 82e9584b authored by Alvin Natawiguna's avatar Alvin Natawiguna

More bugfixes

parent 01bccbea
......@@ -75,6 +75,7 @@ class Command(object):
return self.__error
class CommandFactory(object):
DB_CLIENT = game.game_class.Game.DB_CLIENT
def __init__(self, jsonObject):
super().__init__()
......@@ -199,7 +200,7 @@ class ServerStatusCommand(Command):
def execute(self):
try:
with pymongo.MongoClient() as client:
with CommandFactory.DB_CLIENT as client:
db = client.get_database(game.game_class.Game.DB_NAME)
assert db.authenticate(game.game_class.Game.DB_USERNAME, game.game_class.Game.DB_PASSWORD)
......@@ -234,7 +235,7 @@ class SignupCommand(Command):
try:
hashed_pw = self.game.playerSignup(self.username, self.password)
with pymongo.MongoClient() as client:
with CommandFactory.DB_CLIENT as client:
db = client.get_database(game.game_class.Game.DB_NAME)
assert db.authenticate(game.game_class.Game.DB_USERNAME, game.game_class.Game.DB_PASSWORD)
......@@ -316,8 +317,6 @@ class InventoryQueryCommand(Command):
super().setError(True)
else:
self.inventory = player.getInventory()
print (self.inventory)
except Exception as e:
super().setError(True)
traceback.print_exc()
......@@ -357,13 +356,10 @@ class MixItemCommand(Command):
newItem, new = player.mixItems(item1, item2)
# update the inventory in the db
with pymongo.MongoClient() as client:
with CommandFactory.DB_CLIENT as client:
db = client.get_database(game.game_class.Game.DB_NAME)
assert db.authenticate(game.game_class.Game.DB_USERNAME, game.game_class.Game.DB_PASSWORD)
print(item1)
print(item2)
request = [
pymongo.UpdateOne({
'username': player.username,
......@@ -478,7 +474,7 @@ class MoveCommand(Command):
self.time = player.moveTo(x = self.x, y = self.y)
# TODO: update the player's position in the db
with pymongo.MongoClient() as client:
with CommandFactory.DB_CLIENT as client:
db = client.get_database(game.game_class.Game.DB_NAME)
assert db.authenticate(game.game_class.Game.DB_USERNAME, game.game_class.Game.DB_PASSWORD)
......@@ -532,7 +528,7 @@ class GetItemFromFieldCommand(Command):
try:
self.item, newItem = player.takeItem(location = player.location)
with pymongo.MongoClient() as client:
with CommandFactory.DB_CLIENT as client:
db = client.get_database(game.game_class.Game.DB_NAME)
assert db.authenticate(game.game_class.Game.DB_USERNAME, game.game_class.Game.DB_PASSWORD)
......@@ -659,7 +655,7 @@ class SendFindCommand(Command):
if not player:
super().setError(True)
else:
with pymongo.MongoClient() as client:
with CommandFactory.DB_CLIENT as client:
db = client.get_database(game.game_class.Game.DB_NAME)
assert db.authenticate(game.game_class.Game.DB_USERNAME, game.game_class.Game.DB_PASSWORD)
......@@ -679,6 +675,8 @@ class SendFindCommand(Command):
if currTime - self.UPDATE_TIMES[self.item] > self.CACHE_MAX_DELAY:
self.UPDATE_TIMES[self.item] = currTime
self.fetchOffers()
else:
self.UPDATE_TIMES[self.item] += int(CACHE_MAX_DELAY / 2)
# fetch the cached results
cached = db.cachedOffers.find({'offer.id': self.item})
......@@ -709,7 +707,7 @@ class SendFindCommand(Command):
def fetchOffers(self):
servers = []
with pymongo.MongoClient() as client:
with CommandFactory.DB_CLIENT as client:
db = client.get_database(game.game_class.Game.DB_NAME)
assert db.authenticate(game.game_class.Game.DB_USERNAME, game.game_class.Game.DB_PASSWORD)
......@@ -784,7 +782,7 @@ class RecvFindOfferCommand(Command):
def execute(self):
try:
with pymongo.MongoClient() as client:
with CommandFactory.DB_CLIENT as client:
db = client.get_database(game.game_class.Game.DB_NAME)
assert db.authenticate(game.game_class.Game.DB_USERNAME, game.game_class.Game.DB_PASSWORD)
......@@ -825,14 +823,17 @@ class SendItemAcceptOfferCommand(Command):
try:
player = self.game.getPlayer(self.token)
if player:
with pymongo.MongoClient() as client:
with CommandFactory.DB_CLIENT as client:
db = client.get_database(game.game_class.Game.DB_NAME)
assert db.authenticate(game.game_class.Game.DB_USERNAME, game.game_class.Game.DB_PASSWORD)
offer = db.offers.find_one({'id': self.offer_token})
if offer:
if offer['available']:
# the item demanded from the player: going to be deducted from the inventory
demandedItem = game.item.Item(id=offer['demand']['id'], count=offer['demand']['count'])
# the item demanded by the player: going to be added into the inventory
offeredItem = game.item.Item(id=offer['offer']['id'], count=offer['offer']['count'])
try:
if player.checkAcceptOfferedItem(demandedItem):
# accept the local offer
......@@ -846,6 +847,7 @@ class SendItemAcceptOfferCommand(Command):
assert result.modified_count == 1
player.acceptOffer(demandedItem)
player.fetchOffer(offeredItem)
else:
super().setError("Insufficient items")
except Exception as e:
......@@ -859,7 +861,10 @@ class SendItemAcceptOfferCommand(Command):
offer = db.cachedOffers.find_one({'id': self.offer_token})
if offer:
demandedItem = game.item.Item(id = offer['demand']['id'], count=offer['demand']['count'])
# the item demanded from the player: going to be deducted from the inventory
demandedItem = game.item.Item(id=offer['demand']['id'], count=offer['demand']['count'])
# the item demanded by the player: going to be added into the inventory
offeredItem = game.item.Item(id=offer['offer']['id'], count=offer['offer']['count'])
if player.checkAcceptOfferedItem(demandedItem):
# accept the cached offer
command = AcceptItemOfferCommand(offer['id'], offer['ip'], offer['port'])
......@@ -873,6 +878,30 @@ class SendItemAcceptOfferCommand(Command):
offer['id'])
player.acceptOffer(demandedItem)
if not player.fetchOffer(offeredItem):
result = db.users.update_one({
'username': player.username,
'items.id': offeredItem.getId()
}, {
'$inc': {
'items.$.count': offeredItem.count()
}
})
assert result.modified_count == 1
else: # new item
result = db.users.update_one({
'username': player.username
}, {
'$addToSet': {
'items': {
'id': offeredItem.getId(),
'count': offeredItem.count()
}
}
})
assert result.modified_count == 1
else:
if result['status'] == Command.RESULT_FAIL:
super().setError(result['description'])
......@@ -905,7 +934,7 @@ class AcceptItemOfferCommand(Command):
def execute(self):
sock = socket.socket()
try:
sock.settimeout(3)
sock.settimeout(10)
sock.connect((self.ip, self.port))
sock.sendall(json.dumps({
......@@ -944,7 +973,7 @@ class RecvAcceptItemOfferCommand(Command):
def execute(self):
try:
with pymongo.MongoClient() as client:
with CommandFactory.DB_CLIENT as client:
db = client.get_database(game.game_class.Game.DB_NAME)
assert db.authenticate(game.game_class.Game.DB_USERNAME, game.game_class.Game.DB_PASSWORD)
......@@ -981,22 +1010,22 @@ class FetchOfferedItemCommand(Command):
try:
player = self.game.getPlayer(self.token)
if player:
with pymongo.MongoClient() as client:
with CommandFactory.DB_CLIENT as client:
db = client.get_database(game.game_class.Game.DB_NAME)
assert db.authenticate(game.game_class.Game.DB_USERNAME, game.game_class.Game.DB_PASSWORD)
offer = db.offers.find_one({'id': self.offer_token})
if offer: # offer is in DB
if not item['available']:
offeredItem = game.item.Item(id = offer['offer']['id'], count = offer['offer']['count'])
if not player.fetchOffer(offeredItem):
if not offer['available']:
demandedItem = game.item.Item(id = offer['demand']['id'], count = offer['demand']['count'])
if not player.fetchOffer(demandedItem):
result = db.users.update_one({
'username': player.username,
'items.id': offeredItem.getId()
'items.id': demandedItem.getId()
}, {
'$inc': {
'items.$.count': offeredItem.count()
'items.$.count': demandedItem.count()
}
})
assert result.modified_count == 1
......@@ -1007,8 +1036,8 @@ class FetchOfferedItemCommand(Command):
}, {
'$addToSet': {
'items': {
'id': offeredItem.getId(),
'count': offeredItem.count()
'id': demandedItem.getId(),
'count': demandedItem.count()
}
}
})
......@@ -1039,7 +1068,7 @@ class CancelItemOfferCommand(Command):
try:
player = self.game.getPlayer(self.token)
if player:
with pymongo.MongoClient() as client:
with CommandFactory.DB_CLIENT as client:
db = client.get_database(game.game_class.Game.DB_NAME)
assert db.authenticate(game.game_class.Game.DB_USERNAME, game.game_class.Game.DB_PASSWORD)
......@@ -1095,7 +1124,7 @@ def findOffers(ip, port, item):
if result['status'] == Command.RESULT_OK:
#count = 0
with pymongo.MongoClient() as client:
with CommandFactory.DB_CLIENT as client:
db = client.get_database(game.game_class.Game.DB_NAME)
assert db.authenticate(game.game_class.Game.DB_USERNAME, game.game_class.Game.DB_PASSWORD)
......@@ -1127,7 +1156,7 @@ def findOffers(ip, port, item):
raise IOError("Cannot fetch item offers from ({}, {}): Unknown error".format(ip, port))
def clearCache():
with pymongo.MongoClient() as client:
with CommandFactory.DB_CLIENT as client:
db = client.get_database(game.game_class.Game.DB_NAME)
assert db.authenticate(game.game_class.Game.DB_USERNAME, game.game_class.Game.DB_PASSWORD)
......
......@@ -48,6 +48,7 @@ class GameMap(object):
class Game(object):
FILE_MAP = 'map.json'
DB_CLIENT = pymongo.MongoClient()
DB_NAME = 'if3230-sister'
DB_USERNAME = "sister"
......@@ -87,16 +88,17 @@ class Game(object):
from .player import Player
self.players = []
with pymongo.MongoClient() as client:
db = client.get_database(Game.DB_NAME)
assert db.authenticate(Game.DB_USERNAME, Game.DB_PASSWORD)
# load the players from the db
cursor = db.get_collection(Game.DB_COLLECTION_USERS).find()
client = Game.DB_CLIENT
db = client.get_database(Game.DB_NAME)
assert db.authenticate(Game.DB_USERNAME, Game.DB_PASSWORD)
for user in cursor:
location = Location(user[Player.KEY_CURRENTLOCATION]['x'], user[Player.KEY_CURRENTLOCATION]['y'])
self.players.append(Player(self, user[Player.KEY_USERNAME], user[Player.KEY_PASSWORD].encode(), location))
# load the players from the db
cursor = db.get_collection(Game.DB_COLLECTION_USERS).find()
for user in cursor:
location = Location(user[Player.KEY_CURRENTLOCATION]['x'], user[Player.KEY_CURRENTLOCATION]['y'])
self.players.append(Player(self, user[Player.KEY_USERNAME], user[Player.KEY_PASSWORD].encode(), location))
def __loadOffers(self):
pass
......@@ -230,39 +232,39 @@ class Game(object):
from .item import ItemOffer
with pymongo.MongoClient() as client:
db = client.get_database(Game.DB_NAME)
assert db.authenticate(Game.DB_USERNAME, Game.DB_PASSWORD)
result = db.offers.insert_one({
'id': offerId,
'available': False,
'username': 'DUPLICATE_EXTERNAL',
'demand': {
'id': demandedItem.getId(),
'count': demandedItem.count()
},
'offer': {
'id': offeredItem.getId(),
'count': offeredItem.count()
}
})
client = Game.DB_CLIENT
db = client.get_database(Game.DB_NAME)
assert db.authenticate(Game.DB_USERNAME, Game.DB_PASSWORD)
result = db.offers.insert_one({
'id': offerId,
'available': False,
'username': 'DUPLICATE_EXTERNAL',
'demand': {
'id': demandedItem.getId(),
'count': demandedItem.count()
},
'offer': {
'id': offeredItem.getId(),
'count': offeredItem.count()
}
})
assert result.inserted_count == 1
assert result.inserted_count == 1
# insert the similar value to the offers
self.offers.append(ItemOffer('DUPLICATE_EXTERNAL', demandedItem, offeredItem, offerId, False))
def deleteCachedOffer(self, offerId):
with pymongo.MongoClient() as client:
db = client.get_database(Game.DB_NAME)
assert db.authenticate(Game.DB_USERNAME, Game.DB_PASSWORD)
client = Game.DB_CLIENT
db = client.get_database(Game.DB_NAME)
assert db.authenticate(Game.DB_USERNAME, Game.DB_PASSWORD)
result = db.cachedOffers.delete_one({
'id': offerId
})
result = db.cachedOffers.delete_one({
'id': offerId
})
assert result.deleted_count == 1
assert result.deleted_count == 1
def generateToken(self, username, password):
assert isinstance(password, str) and isinstance(username, str)
......
......@@ -127,7 +127,8 @@ class Player(GameObject):
username = offer['username'],
demand = Item(id=offer['demand']['id'], count=offer['demand']['count']),
offer = Item(id=offer['offer']['id'], count=offer['offer']['count']),
id = offer['id']
id = offer['id'],
available = offer['available']
))
return myOffers
......
......@@ -42,6 +42,12 @@ class RequestHandler(socketserver.BaseRequestHandler):
self.request.sendall(json.dumps(response).encode())
except Exception as e:
traceback.print_exc()
try:
self.request.sendall(json.dumps({
'status': 'error'
}).encode())
except Exception as e:
traceback.print_exc()
def getData(self, timeout = 3):
total_data = []
......@@ -176,7 +182,8 @@ def scheduleBatchFindOffer(scheduler, externalAddr):
'ip': server[0],
'port': server[1]
})
servers[:] = [tup for tup in servers if tup == server]
servers[:] = [tup for tup in servers if tup != server]
continue
except Exception as e:
traceback.print_exc()
else:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment