Skip to content
Snippets Groups Projects
Commit ed944f14 authored by Alvin Natawiguna's avatar Alvin Natawiguna
Browse files

More functions implemented. Not tested though... :v

parent 669c2ee8
Branches
No related merge requests found
from abc import abstractmethod, ABCMeta
import json
import socket
from game.game import Game, GameMap
from game.player import Player
from game.map import Map
from game.item import Item
class Command(object):
......@@ -11,6 +13,7 @@ class Command(object):
Abstract base class for commands
"""
METHOD_JOIN = "join"
METHOD_SERVERSTATUS = "serverStatus"
METHOD_SIGNUP = "signup"
METHOD_LOGIN = "login"
......@@ -30,6 +33,7 @@ class Command(object):
def __init__(self):
super().__init__()
self.__error = None
"""
......@@ -37,9 +41,18 @@ class Command(object):
"""
@abstractmethod
def execute(self):
pass
raise NotImplementedError("You need to implement the method for your Command class")
def getStatus(self):
"""
Gets the status of the command's execution
Any error should be assigned to the self.__error variable.
If the self.__error object is a str, fail status will be returned
else, error status will be returned
returns dict object
"""
if not self.__error:
return {'status': 'ok'}
else:
......@@ -49,98 +62,185 @@ class Command(object):
return {'status': 'error'}
class CommandFactory(object):
def __init__(self, jsonObject):
def __init__(self, **jsonObject):
super().__init__()
self.__json = jsonObject
self.game = Game.getInstance()
def getCommand(self):
method = self.__json["method"]
if method == Command.METHOD_SERVERSTATUS:
if method == Command.METHOD_JOIN:
if 'ip' in self.__json and 'port' in self.__json:
return JoinCommand(self.__json['ip'], self.__json['port'])
else:
return JoinCommand()
elif method == Command.METHOD_SERVERSTATUS:
return ServerStatusCommand(self.__json['server'])
elif method == Command.METHOD_SIGNUP:
return SignupCommand(self.__json["username"], self.__json["password"])
return SignupCommand(self.game, self.__json["username"], self.__json["password"])
elif method == Command.METHOD_LOGIN:
return LoginCommand(self.__json["username"], self.__json["password"])
return LoginCommand(self.game, self.__json["username"], self.__json["password"])
elif method == Command.METHOD_INVENTORY:
return InventoryQueryCommand(self.__json["token"])
return InventoryQueryCommand(self.game, self.__json["token"])
elif method == Command.METHOD_MIXITEM:
return MixItemCommand(self.__json["token"], self.__json["item1"], self.__json["item2"])
return MixItemCommand(self.game, self.__json["token"], self.__json["item1"], self.__json["item2"])
elif method == Command.METHOD_MAP:
return MapQueryCommand(self.__json["token"])
return MapQueryCommand(self.game, self.__json["token"])
elif method == Command.METHOD_MOVE:
return MoveCommand(self.__json["token"], self.__json["x"], self.__json["y"])
return MoveCommand(self.game, self.__json["token"], self.__json["x"], self.__json["y"])
elif method == Command.METHOD_FIELD:
return GetItemFromFieldCommand(self.__json["token"])
return GetItemFromFieldCommand(self.game, self.__json["token"])
elif method == Command.METHOD_OFFER:
return MakeItemOfferCommand(self.__json["token"],
return MakeItemOfferCommand(self.game,
self.__json["token"],
self.__json["offered_item"],
self.__json["n1"],
self.__json["demanded_item"],
self.__json["n2"])
elif method == Command.METHOD_TRADEBOX:
return TradeboxQueryCommand(self.__json["token"])
return TradeboxQueryCommand(self.game, self.__json["token"])
elif method == Command.METHOD_SENDFIND:
return SendFindCommand(self.__json["token"], self.__json["item"])
return SendFindCommand(self.game, self.__json["token"], self.__json["item"])
elif method == Command.METHOD_FINDOFFER:
return FindOfferCommand(self.__json["item"])
return FindOfferCommand(self.__json["item"], self.__json["ip"], self.__json["port"])
elif method == Command.METHOD_SENDACCEPT:
return SendAcceptCommand(self.__json["token"], self.__json["offer_token"])
return SendAcceptCommand(self.game, self.__json["token"], self.__json["offer_token"])
elif method == Command.METHOD_ACCEPT:
return AcceptItemOfferCommand(self.__json["offer_token"])
return AcceptItemOfferCommand(self.__json["offer_token"], self.__json["ip"], self.__json["port"])
elif method == Command.METHOD_FETCHITEM:
return FetchOfferedItemCommand(self.__json["token"], self.__json["offer_token"])
return FetchOfferedItemCommand(self.game, self.__json["token"], self.__json["offer_token"])
elif method == Command.METHOD_CANCELOFFER:
return CancelItemOfferCommand(self.__json["token"], self.__json["offer_token"])
return CancelItemOfferCommand(self.game, self.__json["token"], self.__json["offer_token"])
else:
raise ValueError("Unknown method: {}".format(method))
# SERVER COMMANDS #
class JoinCommand(Command):
DEFAULT_TRACKER_IP, DEFAULT_TRACKER_PORT = '167.205.32.46', 8000
def __init__(self, ip = JoinCommand.DEFAULT_TRACKER_IP, port = JoinCommand.DEFAULT_TRACKER_PORT):
super().__init__()
self.ip = ip
self.port = port
self.result = None
def execute(self):
sock = socket.socket()
try:
sock.connect((self.ip, self.port))
sock.sendall(json.dumps({
'method': Command.METHOD_JOIN,
'ip': self.ip,
'port': self.port
}))
"""
This assumes that the server is going to send some small data.
Maybe in the future this needs to be revised, to handle arbitary-sized data.
"""
data = sock.recv(4096, 'utf-8')
if data:
self.result = json.loads(data)
else:
self.__error = True
except Exception, e:
self.__error = str(e)
finally:
sock.close()
def getStatus(self):
if self.result:
return self.result
else:
if not self.__error:
self.__error = True
super().getStatus()
class ServerStatusCommand(Command):
DB_COLLECTION_SERVER = 'activeServers'
def __init__(self, serverList):
super().__init__()
self.__servers = serverList
self.servers = serverList
def execute(self):
try:
for server in servers:
# TODO: put the data into the db
print ("{}{}".format(server['ip'], server['port']))
with pymongo.MongoClient().get_database(Game.DB_NAME) as db:
collection = db.get_collection(ServerStatusCommand.DB_COLLECTION_SERVER)
for server in enumerate(self.servers):
collection.update_one({'ip': server['ip']}, {'$set': {'port': server['port']} })
except Exception:
self.__error = True
class SignupCommand(Command):
def __init__(self, username, password):
def __init__(self, game, username, password):
super().__init__()
self.game = game
self.username = username
self.password = password
def execute(self):
pass
try:
game.playerSignup(self.username, self.password)
with pymongo.MongoClient().get_database(Game.DB_NAME) as db:
db.users.insert({
Player.KEY_USERNAME: self.username,
Player.KEY_PASSWORD: bcrypt.hashpw(self.password, bcrypt.gensalt()),
Player.KEY_ITEMS: [],
Player.KEY_CURRENTLOCATION: {
'x': 0,
'y': 0
},
Player.KEY_OFFERS: []
})
except Exception, e:
self.__error = str(e)
class LoginCommand(Command):
def __init__(self, username, password):
def __init__(self, game, username, password):
super().__init__()
self.game = game
self.username = username
self.password = password
self.player = None
self.token = None
def execute(self):
# TODO: find the player in the Game object, and generate the apropriate token
pass
try:
self.token = game.playerLogin(self.username, self.password)
# should not fail. Not yet tested though .__.
self.player = game.getPlayer(token = self.token)
if not self.player:
self.__error = True
except Exception, e:
self.__error = str(e)
def getStatus(self):
if not self.error and self.player:
if not self.error and self.token:
return {
'status': 'ok',
'token': self.__player.__id,
'x': self.__player.currentLocation.x,
'y': self.__player.currentLocation.y,
'token': self.token,
'x': self.player.currentLocation.x,
'y': self.player.currentLocation.y,
'time': int(time.time())
}
else:
......@@ -154,14 +254,20 @@ class InventoryQueryCommand(Command):
docstring for InventoryQueryCommand
"""
def __init__(self, token):
def __init__(self, game, token):
super().__init__()
self.game = game
self.token = token
self.inventory = []
def execute(self):
# TODO: get the inventory from the game class
pass
player = game.getPlayer(token = self.token)
if not player:
self.__error = True
else:
self.inventory = player.getInventory()
def getStatus(self):
if not self.error and self.inventory:
......@@ -177,9 +283,10 @@ class InventoryQueryCommand(Command):
class MixItemCommand(Command):
def __init__(self, token, item1_id, item2_id):
def __init__(self, game, token, item1_id, item2_id):
super().__init__()
self.game = game
self.token = token
self.item1 = item1_id
self.item2 = item2_id
......@@ -187,8 +294,12 @@ class MixItemCommand(Command):
self.result = None
def execute(self):
# TODO: mix the items
pass
player = game.getPlayer(token = self.token)
if player:
else:
self.__error = True
def getStatus(self):
if self.result:
......@@ -204,15 +315,18 @@ class MixItemCommand(Command):
class MapQueryCommand(Command):
def __init__(self, token):
def __init__(self, game, token):
super().__init__()
self.game = game
self.token = token
self.map = None
def execute(self):
# TODO: get the map info
pass
if player.getPlayer(token = self.token):
self.map = game.map
else:
self.__error = True
def getStatus(self):
if self.map:
......@@ -230,16 +344,25 @@ class MapQueryCommand(Command):
class MoveCommand(Command):
def __init__(self, token, x, y):
def __init__(self, game, token, x, y):
super().__init__()
self.game = game
self.token = token
self.x = x
self.y = y
def execute(self):
# TODO: move the player
pass
player = self.game.getPlayer(token = self.token)
if not player:
self.__error = True
else:
try:
player.moveTo(x = x, y = y)
# TODO: update the player's position in the db
except Exception, e:
self.__error = str(e)
def getStatus(self):
if not self.__error:
......@@ -253,15 +376,25 @@ class MoveCommand(Command):
# alias: Field
class GetItemFromFieldCommand(Command):
def __init__(self, token):
def __init__(self, game, token):
super().__init__()
self.game = game
self.token = token
self.item = None
def execute(self):
# TODO: get the item from the player's current position
pass
player = self.game.getPlayer(token = self.token)
if not player:
self.__error = True
else:
try:
self.item = player.takeItem(location = player.currentLocation)
# TODO: update the player's inventory in the db
except Exception, e:
self.__error = str(e)
def getStatus(self):
if not self.__error and self.result:
......@@ -277,29 +410,47 @@ class GetItemFromFieldCommand(Command):
class MakeItemOfferCommand(Command):
def __init__(self, token, offer_item, offer_itemCount, demand_item, demand_itemCount):
def __init__(self, game, token, offer_item, offer_itemCount, demand_item, demand_itemCount):
super().__init__()
self.token = token
self.game = game
self.token = token
self.offer_item = Item(id=offer_item, count=offer_itemCount)
self.demand_item = Item(id=demand_item, count=demand_itemCount)
def execute(self):
# TODO: make the offer
pass
try:
player = self.game.getPlayer(self.token)
if player:
player.makeOffer(self.offer_item, self.demand_item)
# TODO: add the offer to the global offer table, and update the player's offer table
else:
self.__error = True
except Exception, e:
self.__error = e
class TradeboxQueryCommand(Command):
def __init__(self, token):
def __init__(self, game, token):
super().__init__()
self.game = game
self.token = token
self.result = None
self.result = []
def execute(self):
# TODO: get the tradebox of the player
pass
try:
player = self.game.getPlayer(self.token)
if player:
for offer in enumerate(player.getTradebox()):
self.result.append(offer.asList())
else:
self.__error = True
except Exception, e:
self.__error = e
def getStatus(self):
if not self.__error and self.result:
......@@ -315,9 +466,10 @@ class TradeboxQueryCommand(Command):
class SendFindCommand(Command):
def __init__(self, token, itemId):
def __init__(self, game, token, itemId):
super().__init__()
self.game = game
self.token = token
self.item = itemId
......@@ -352,15 +504,30 @@ class FindOfferCommand(Command):
self.result = None
def execute(self):
# TODO: create a connection to such server, and send the query
pass
sock = socket.socket()
try:
sock.connect((self.ip, self.port))
sock.sendAll(json.dumps({
'method': Command.METHOD_FINDOFFER,
'item': self.item
}))
"""
This assumes that the server is going to send small-sized data.
Maybe in the future this needs to be revised, to handle arbitary-sized data.
"""
data = sock.recv(4096, 'utf-8')
self.result = json.loads(data)
except Exception, e:
self.__error = str(e)
finally:
sock.close()
def getStatus(self):
if not self.__error and self.result:
return {
'status': 'ok',
'offers': self.result
}
return self.result
else:
if not self.__error:
self.__error = True
......@@ -369,9 +536,10 @@ class FindOfferCommand(Command):
class SendItemAcceptOfferCommand(Command):
def __init__(self, token, offer_token):
def __init__(self, game, token, offer_token):
super().__init__()
self.game = game
self.token = token
self.offer_token = offer_token
......@@ -382,20 +550,26 @@ class SendItemAcceptOfferCommand(Command):
# NOTE: this is something that is sent by the server, not received by the server
class AcceptItemOfferCommand(Command):
def __init__(self, offer_token):
def __init__(self, offer_token, ip, port):
super().__init__()
self.token = token
self.offer_token = offer_token
self.ip = ip
self.port = port
self.result = None
def execute(self):
# TODO: accept the player's offer from other server
# Question: do we need to duplicate?
pass
class FetchOfferedItemCommand(Command):
def __init__(self, token, offer_token):
def __init__(self, game, token, offer_token):
super().__init__()
self.game = game
self.token = token
self.offer_token = offer_token
......@@ -404,9 +578,10 @@ class FetchOfferedItemCommand(Command):
pass
class CancelItemOfferCommand(Command):
def __init__(self, token, offer_token):
def __init__(self, game, token, offer_token):
super().__init__()
self.game = game
self.token = token
self.offer_token = offer_token
......
import pymongo
class Game(object):
DEFAULT_ID = 0
def __init__(self, id=Game.DEFAULT_ID):
super().__init__()
__loadGameData()
def __loadGameData(self):
pass
\ No newline at end of file
import pymongo
import json
import bcrypt
class Location(object):
def __init__(self, x, y):
super().__init__()
self.x = int(x)
self.y = int(y)
class GameMap(object):
def __init__(self, name, width, height, locations = None):
assert width > 0 and height > 0
super().__init__()
self.name = name
self.width = int(width)
self.height = int(height)
if not locations:
self.locations = [[None] * height] * width
else:
assert len(locations) == width and len(locations[0]) == height
self.locations = []
for elem in locations:
self.locations.append(elem)
class Game(object):
FILE_MAP = 'map.json'
DB_NAME = 'if3230-sister'
DB_COLLECTION_USERS = 'users'
__instance = None
def __init__(self, mapFile = FILE_MAP):
super().__init__()
# the attributes
self.players = []
self.map = None
with open(mapFile) as map_file:
self.__loadMap(json.load(mapFile))
self.__loadPlayers()
@classmethod
def getInstance(self):
if not Game.__instance:
Game.__instance = Game()
return Game.__instance
def __loadMap(self, json):
assert isinstance(json, dict)
self.map = GameMap(json['name'], json['width'], json['height'], json['map'])
def __loadPlayers(self):
self.players = []
with pymongo.MongoClient().get_database(Game.DB_NAME) as db:
# load the players from the db
cursor = db.get_collection(Game.DB_COLLECTION_USERS)
for player in cursor.find():
location = Location(player['location']['x'], player['location']['y'])
players.append(Player(self, player['username'], player['password'], location))
"""
Do a player login
Attributes:
username -- the Player's username
password -- the Player's password in plaintext
Returns the authentication token
"""
def playerLogin(self, username, password):
for player in enumerate(self.players):
if player.username == username:
break
else:
raise LookupError('user not found: {}'.format(username))
if isinstnace(password, str):
password = password.encode()
assert isinstance(password, bytes)
if bcrypt.hashpw(password, player.password) != player.password:
raise ValueError('invalid password')
token = Player.__generateToken(username, password)
player.token = token
return token
"""
Signup a new user
Attributes:
username -- the Player's username
password -- the Player's password in plaintext
"""
def playerSignup(self, username, password):
for player in enumerate(self.players):
if player.username == username:
raise ValueError('Username already exists')
else:
if isinstance(password, str):
password = password.encode()
hashed_pass = bcrypt.hashpw(password, bcrypt.gensalt())
self.players.append(Player(username, hashed_pass))
"""
Get a player object
Attributes:
token: the login token
username: the Player's username
"""
def getPlayer(self, token = None, username = None):
if token or username:
for player in enumerate(self.players):
assert isinstance(player.username, str)
if player.username == username or (token and player.token == token):
return player
else:
return None
else:
raise TypeError('No search argument (token or username) defined')
\ No newline at end of file
from game_object import GameObject
from enum import Enum
from player import Player
class ItemId(Enum):
HONEY = (0, 'R11')
......@@ -82,38 +83,53 @@ class Item(GameObject):
if not isinstance(item2, Item):
raise TypeError('item2 is not an Item')
if item1.__count >= __MIX_USAGE and item2.__count >= __MIX_USAGE:
if item1.__count >= Item.__MIX_USAGE and item2.__count >= Item.__MIX_USAGE:
# define the recipe here
result = None
# Level 1 mix
if Item.isEqual(item1, ItemId.HONEY) and Item.isEqual(item2, ItemId.HERBS):
if ((Item.isEqual(item1, ItemId.HONEY) and Item.isEqual(item2, ItemId.HERBS)) or
(Item.isEqual(item1, ItemId.HERBS) and Item.isEqual(item2, ItemId.HONEY))):
result = Item(itemId=ItemId.POTION)
elif Item.isEqual(item1, ItemId.HERBS) and Item.isEqual(item2, ItemId.CLAY):
elif ((Item.isEqual(item1, ItemId.HERBS) and Item.isEqual(item2, ItemId.CLAY)) or
(Item.isEqual(item1, ItemId.CLAY) and Item.isEqual(item2, ItemId.HERBS))):
result = Item(itemId=ItemId.INCENSE)
elif Item.isEqual(item1, ItemId.CLAY) and Item.isEqual(item2, ItemId.MINERAL):
elif ((Item.isEqual(item1, ItemId.CLAY) and Item.isEqual(item2, ItemId.MINERAL)) or
(Item.isEqual(item1, ItemId.MINERAL) and Item.isEqual(item2, ItemId.CLAY))):
result = Item(itemId=ItemId.GEMS)
# Level 2 mix
elif Item.isEqual(item1, ItemId.POTION) and Item.isEqual(item2, ItemId.INCENSE):
elif ((Item.isEqual(item1, ItemId.POTION) and Item.isEqual(item2, ItemId.INCENSE)) or
(Item.isEqual(item1, ItemId.INCENSE) and Item.isEqual(item2, ItemId.POTION))):
result = Item(itemId=ItemId.LIFE_ELIXIR)
elif Item.isEqual(item1, ItemId.INCENSE) and Item.isEqual(item2, ItemId.GEMS):
elif ((Item.isEqual(item1, ItemId.INCENSE) and Item.isEqual(item2, ItemId.GEMS)) or
(Item.isEqual(item1, ItemId.GEMS) and Item.isEqual(item2, ItemId.INCENSE))):
result = Item(itemId=ItemId.MANA_CRYSTAL)
# Level 3 mix
elif Item.isEqual(item1, ItemId.LIFE_ELIXIR) and Item.isEqual(item2, ItemId.MANA_CRYSTAL):
elif ((Item.isEqual(item1, ItemId.LIFE_ELIXIR) and Item.isEqual(item2, ItemId.MANA_CRYSTAL)) or
(Item.isEqual(item1, ItemId.MANA_CRYSTAL) and Item.isEqual(item2, ItemId.LIFE_ELIXIR))):
result = Item(itemId=ItemId.PHILOSOPHER_STONE)
else:
raise ValueError('Unknown recipe for item {} and {}'.format(item1.id, item2.id))
# reduce
item1.__count -= __MIX_USAGE
item2.__count -= __MIX_USAGE
item1.__count -= Item.__MIX_USAGE
item2.__count -= Item.__MIX_USAGE
return result
else:
if item1.__count < __MIX_USAGE:
if item1.__count < Item.__MIX_USAGE:
raise ValueError('not enough items for item1')
else:
raise ValueError('not enough items for item2')
......@@ -123,4 +139,36 @@ class Item(GameObject):
if isinstance(item, Item) and isinstance(itemId, ItemId):
return item.__id == itemId.index || item.__id == itemId.id
else:
raise TypeError('Invalid parameter(s)')
\ No newline at end of file
raise TypeError('Invalid parameter(s)')
class ItemOffer(GameObject):
"""docstring for ItemOffer"""
def __init__(self, player: Player, offer: Item, demand: Item):
super().__init__(ItemOffer.generateId())
self.offerer_id = player.id
self.offer = offer
self.demand = demand
# Available means that this offer is available to be get
self.available = True
@classmethod
def generateId(self):
import hashlib
import random
import string
result = str(int(time.time()))
# generate a random string with length of 6
result += (''.join(random.SystemRandom().choice(string.ascii_uppercase + string.digits) for _ in range(6)))
md5hash = hashlib.md5()
md5hash.update(result)
return str(md5hash.hexdigest())
def asList(self):
return [self.offer.__id, self.offer.count, self.demand.__id, self.demand.__count, self.avaliable, self.__id]
from game_object import GameObject
from ... import Game
from location import Location
from game import Game, Location
import json
import time
import pymongo
class Player(GameObject):
DEFAULT_NAME = "Player"
COUNT = 0
KEY_USERNAME = 'username'
KEY_PASSWORD = 'password'
KEY_CURRENTLOCATION = 'location'
KEY_ITEMS = 'items'
KEY_OFFERS = 'offers'
"""Creates a Player object, for logging in purposes
Attributes:
game -- the Game object related to the player
username -- the Player's username, for identification purposes
password -- the Player's password
currentLocation -- the
location -- the Player's avatar's current position in the map
"""
def __init__(self,
token : str = None
game : Game
username : str,
password : str = None,
location : Location = None,
sprite = None):
assert isinstance(token, str) or isinstance(password, str)
if token:
super().__init__(token)
else:
super().__init__(__generateToken(username, password))
password : str,
location : Location = None
):
super().__init__(Player.generateId())
self.game = game
self.username = username
self.password = password
self.currentLocation = location
self.sprite = sprite
# some protos
self.token = None
self.items = []
self.offers = []
if not location:
# new user implied
self.currentLocation = Location(0, 0)
else:
# user already exists in db
self.currentLocation = location
self.__loadProperties()
def __loadProperties(self):
with pymongo.MongoClient().get_database(Game.DB_NAME) as db:
cursor = db.get_collection(Game.DB_COLLECTION_USERS).find({'username': self.username})
if cursor.count() == 1:
userDict = cursor.next()
__loadItems(db, userDict)
__loadOffers(db, userDict)
else:
if cursor.count() == 0:
raise LookupError('player not found: {}'.format(self.username))
else: # some error: multiple users found
raise LookupError('multiple players found for {}:{}'.format(self.username, cursor.count()))
def __loadItems(self, db, userDict):
if 'items' in userDict:
for item in enumerate(userDict['items']):
self.items.append(Item(id = item['id'], count = item['count']))
else:
# initialize empty inventory
db.get_collection(Game.DB_COLLECTION_USERS).update(
{
'_id': obj['_id']
},
{
'$set': {
'items': []
}
}
)
def __loadOffers(self, db, userDict):
if 'offers' in userDict:
for offer in enumerate(userDict['offers']):
self.offers.append()
else:
# initialize empty inventory
db.get_collection(Game.DB_COLLECTION_USERS).update(
{
'_id': obj['_id']
},
{
'$set': {
'offers': []
}
}
)
def getInventory(self):
inventory = []
for item in enumerate(self.items):
for count in range(item.count):
inventory.append(item.id)
return inventory
def moveTo(self,
x : int = None,
y : int = None,
location : Location = None):
if x is int and y is int:
self.location.x = x
self.location.y = y
if x in range(0, self.game.map.width) and y in range(0, self.game.map.height):
self.currentLocation.x = x
self.currentLocation.y = y
else: raise ValueError('Position out of bounds: ({},{})'.format(x, y))
elif location is Location:
self.location = location
if location.x in range(0, self.game.map.width) and y in range(0, self.game.map.height):
self.currentLocation = location
else:
raise ValueError('Position out of bounds: ({},{})'.format(location.x, location.y))
else:
raise ValueError('Invalid parameter')
def takeItem(self,
x : int = None,
y : int = None,
location : Location = None,
offerId : str = None):
if x is int and y is int:
# do some item getting here
pass
elif location is Location:
# do some item gathering here
pass
if (x and y) or location:
# take item at position x, y
if not (x and y):
x = location.x
y = location.y
return self.game.map.locations[x][y]
elif offerId is str:
# do lookup
pass
......@@ -65,15 +144,18 @@ class Player(GameObject):
def addItem(self,
item: Item = None,
id: string = None,
itemId: string = None,
count: int = 1):
if isinstance(item, Item):
pass
self.items.append(item)
elif isinstance(id, str) and isinstance(count, int):
pass
self.items.append(Item(id = itemId, count = count))
else:
raise TypeError('Invalid parameter')
def getTradebox(self):
return self.offers
def mixItems(self,
item1: Item,
item2: Item):
......@@ -92,8 +174,8 @@ class Player(GameObject):
@classmethod
def generateId(self):
# not used; token is used instead, generated from time and password, hashed together
raise NotImplementedError('use __generateId(password) instead of this')
Player.COUNT += 1
return "P-{:03d}".format(Player.COUNT)
@classmethod
def __generateToken(self, username, password):
......
......@@ -3,6 +3,8 @@ import threading
import socketserver
import json
import time
import sys
import sched
from command import CommandFactory, Command
......@@ -27,8 +29,9 @@ class RequestHandler(socketserver.BaseRequestHandler):
command.execute()
response = command.getStatus()
assert(isinstance(response, dict))
self.request.sendall(json.dumps(response))
except ValueError, e:
except Exception, e:
pass # TODO: log the error
def getData(self, timeout = 3):
......@@ -47,7 +50,7 @@ class RequestHandler(socketserver.BaseRequestHandler):
end = True
else:
try:
data = self.request.recv(RequestHandler.BUFSIZE, 'ascii')
data = self.request.recv(RequestHandler.BUFSIZE, 'utf-8')
if not data:
time.sleep(0.1)
else:
......@@ -64,5 +67,31 @@ class RequestHandler(socketserver.BaseRequestHandler):
class ThreadedTcpServer(socketserver.ThreadingMixIn, socketserver.TCPServer):
pass
def connectTracker():
factory = CommandFactory({
'method': Command.METHOD_JOIN
})
command = factory.getCommand()
command.execute()
# TODO: get the status, then add the servers to the activeServers list
def findItem(server, ip, port):
pass
if __name__ == '__main__':
pass
\ No newline at end of file
HOST, PORT = 'localhost', sys.argv[1]
server = ThreadedTcpServer((HOST, PORT), RequestHandler)
# start a server thread
server_thread = threading.Thread(target=server.serve_forever)
# exit the server thread when the main thread ends
server_thread.daemon = True
server_thread.start()
print("Server running on thread: ", server_thread.name)
server_thread.stop()
\ No newline at end of file
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