Commit 0ca43047 authored by Alvin Natawiguna's avatar Alvin Natawiguna
Browse files

Somewhat running server, cleanups, and readme

parent f9207ab2
# Server Side
By:
By: Alvin Natawiguna (13512030)
## Development Environment
Python
## Requirements
-
- Python 3.4.x
- pymongo (install with pip)
- bcrypt (install with pip)
## How to Run
-
- Run ``` python server.py [port] ```
## Additional Information
-
Last Updated:
Last Updated: 23 April 2015
from abc import abstractmethod, ABCMeta
import abc
import json
import socket
from game.game import Game, GameMap
from game.player import Player
from game.item import Item
import game
class Command(object):
__metaclass__ = ABCMeta
__metaclass__ = abc.ABCMeta
"""
Abstract base class for commands
......@@ -39,7 +36,7 @@ class Command(object):
"""
Executes the command
"""
@abstractmethod
@abc.abstractmethod
def execute(self):
raise NotImplementedError("You need to implement the method for your Command class")
......@@ -49,7 +46,7 @@ class Command(object):
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
else as error status will be returned
returns dict object
"""
......@@ -66,7 +63,7 @@ class CommandFactory(object):
super().__init__()
self.__json = jsonObject
self.game = Game.getInstance()
self.game = game.Game.getInstance()
def getCommand(self):
method = self.__json["method"]
......@@ -120,7 +117,7 @@ class CommandFactory(object):
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):
def __init__(self, ip = DEFAULT_TRACKER_IP, port = DEFAULT_TRACKER_PORT):
super().__init__()
self.ip = ip
......@@ -150,7 +147,7 @@ class JoinCommand(Command):
self.result = json.loads(data)
else:
self.__error = True
except Exception, e:
except Exception as e:
self.__error = str(e)
finally:
sock.close()
......@@ -173,7 +170,7 @@ class ServerStatusCommand(Command):
def execute(self):
try:
with pymongo.MongoClient().get_database(Game.DB_NAME) as db:
with pymongo.MongoClient().get_database(game.Game.DB_NAME) as db:
collection = db.get_collection(ServerStatusCommand.DB_COLLECTION_SERVER)
for server in enumerate(self.servers):
......@@ -195,21 +192,21 @@ class SignupCommand(Command):
try:
game.playerSignup(self.username, self.password)
with pymongo.MongoClient().get_database(Game.DB_NAME) as db:
with pymongo.MongoClient().get_database(game.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: [],
game.Player.KEY_USERNAME: self.username,
game.Player.KEY_PASSWORD: bcrypt.hashpw(self.password, bcrypt.gensalt()),
game.Player.KEY_ITEMS: [],
Player.KEY_CURRENTLOCATION: {
game.Player.KEY_CURRENTLOCATION: {
'x': 0,
'y': 0
},
Player.KEY_OFFERS: []
game.Player.KEY_OFFERS: []
})
except Exception, e:
except Exception as e:
self.__error = str(e)
class LoginCommand(Command):
......@@ -231,7 +228,7 @@ class LoginCommand(Command):
self.player = game.getPlayer(token = self.token)
if not self.player:
self.__error = True
except Exception, e:
except Exception as e:
self.__error = str(e)
def getStatus(self):
......@@ -297,7 +294,7 @@ class MixItemCommand(Command):
player = game.getPlayer(token = self.token)
if player:
pass
else:
self.__error = True
......@@ -361,7 +358,7 @@ class MoveCommand(Command):
player.moveTo(x = x, y = y)
# TODO: update the player's position in the db
except Exception, e:
except Exception as e:
self.__error = str(e)
def getStatus(self):
......@@ -393,7 +390,7 @@ class GetItemFromFieldCommand(Command):
self.item = player.takeItem(location = player.currentLocation)
# TODO: update the player's inventory in the db
except Exception, e:
except Exception as e:
self.__error = str(e)
def getStatus(self):
......@@ -415,8 +412,8 @@ class MakeItemOfferCommand(Command):
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)
self.offer_item = game.Item(id=offer_item, count=offer_itemCount)
self.demand_item = game.Item(id=demand_item, count=demand_itemCount)
def execute(self):
try:
......@@ -428,7 +425,7 @@ class MakeItemOfferCommand(Command):
else:
self.__error = True
except Exception, e:
except Exception as e:
self.__error = e
class TradeboxQueryCommand(Command):
......@@ -449,7 +446,7 @@ class TradeboxQueryCommand(Command):
self.result.append(offer.asList())
else:
self.__error = True
except Exception, e:
except Exception as e:
self.__error = e
def getStatus(self):
......@@ -520,7 +517,7 @@ class FindOfferCommand(Command):
data = sock.recv(4096, 'utf-8')
self.result = json.loads(data)
except Exception, e:
except Exception as e:
self.__error = str(e)
finally:
sock.close()
......
from game_object import GameObject
from enum import Enum
from player import Player
import game
class ItemId(Enum):
HONEY = (0, 'R11')
......@@ -17,16 +17,16 @@ class ItemId(Enum):
def __init__(self, index: int, idStr: str):
assert isinstance(index, int) and isinstance(idStr, str)
this.index = index
this.id = idStr
self.index = index
self.id = idStr
class Item(GameObject):
class Item(game.GameObject):
"""docstring for Item"""
def __init__(self,
id: int = None,
itemId: ItemId = None,
item: Item = None,
item = None,
count: int = None):
if isinstance(item, Item):
super().__init__(item.id)
......@@ -41,7 +41,7 @@ class Item(GameObject):
else:
self.__selfInit(1)
elif GameObject.isValidId(id):
elif game.GameObject.isValidId(id):
super().__init__(id)
if isinstance(count, int):
......@@ -58,7 +58,7 @@ class Item(GameObject):
else:
self.__count = 1
def __copyInit(self, item: Item):
def __copyInit(self, item):
self.__count = item.__count
def count(self, newVal: int = None):
......@@ -76,7 +76,7 @@ class Item(GameObject):
__MIX_USAGE = 3
@classmethod
def mixItems(self, item1: Item, item2: Item) -> Item:
def mixItems(self, item1, item2):
if not isinstance(item1, Item):
raise TypeError('item1 is not an Item')
......@@ -135,13 +135,14 @@ class Item(GameObject):
raise ValueError('not enough items for item2')
@classmethod
def isEqual(self, item: Item, itemId: ItemId) -> boolean:
def isEqual(self, item, itemId: ItemId):
if isinstance(item, Item) and isinstance(itemId, ItemId):
return item.__id == itemId.index || item.__id == itemId.id
return item.__id == itemId.index or item.__id == itemId.id
else:
raise TypeError('Invalid parameter(s)')
class ItemOffer(GameObject):
class ItemOffer(game.GameObject):
from game.player import Player
"""docstring for ItemOffer"""
def __init__(self, player: Player, offer: Item, demand: Item):
......
from game_object import GameObject
from game import Game, Location
import game
import json
import time
import pymongo
class Player(GameObject):
class Player(game.GameObject):
COUNT = 0
KEY_USERNAME = 'username'
......@@ -17,16 +15,16 @@ class Player(GameObject):
"""Creates a Player object, for logging in purposes
Attributes:
game -- the Game object related to the player
game -- the game.Game object related to the player
username -- the Player's username, for identification purposes
password -- the Player's password
location -- the Player's avatar's current position in the map
"""
def __init__(self,
game : Game
game : game.game.Game,
username : str,
password : str,
location : Location = None
location : game.Location = None
):
super().__init__(Player.generateId())
......@@ -41,15 +39,15 @@ class Player(GameObject):
if not location:
# new user implied
self.currentLocation = Location(0, 0)
self.currentgame.Location = game.Location(0, 0)
else:
# user already exists in db
self.currentLocation = location
self.currentgame.Location = 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})
with pymongo.MongoClient().get_database(game.Game.DB_NAME) as db:
cursor = db.get_collection(game.Game.DB_COLLECTION_USERS).find({'username': self.username})
if cursor.count() == 1:
userDict = cursor.next()
......@@ -65,10 +63,10 @@ class Player(GameObject):
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']))
self.items.append(game.Item(id = item['id'], count = item['count']))
else:
# initialize empty inventory
db.get_collection(Game.DB_COLLECTION_USERS).update(
db.get_collection(game.Game.DB_COLLECTION_USERS).update(
{
'_id': obj['_id']
},
......@@ -85,7 +83,7 @@ class Player(GameObject):
self.offers.append()
else:
# initialize empty inventory
db.get_collection(Game.DB_COLLECTION_USERS).update(
db.get_collection(game.Game.DB_COLLECTION_USERS).update(
{
'_id': obj['_id']
},
......@@ -108,16 +106,16 @@ class Player(GameObject):
def moveTo(self,
x : int = None,
y : int = None,
location : Location = None):
location : game.Location = None):
if x is int and y is int:
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
self.currentgame.Location.x = x
self.currentgame.Location.y = y
else: raise ValueError('Position out of bounds: ({},{})'.format(x, y))
elif location is Location:
elif location is game.Location:
if location.x in range(0, self.game.map.width) and y in range(0, self.game.map.height):
self.currentLocation = location
self.currentgame.Location = location
else:
raise ValueError('Position out of bounds: ({},{})'.format(location.x, location.y))
else:
......@@ -126,7 +124,7 @@ class Player(GameObject):
def takeItem(self,
x : int = None,
y : int = None,
location : Location = None,
location : game.Location = None,
offerId : str = None):
if (x and y) or location:
# take item at position x, y
......@@ -143,13 +141,13 @@ class Player(GameObject):
raise TypeError('Invalid parameter')
def addItem(self,
item: Item = None,
item: game.Item = None,
itemId: string = None,
count: int = 1):
if isinstance(item, Item):
if isinstance(item, game.Item):
self.items.append(item)
elif isinstance(id, str) and isinstance(count, int):
self.items.append(Item(id = itemId, count = count))
self.items.append(game.Item(id = itemId, count = count))
else:
raise TypeError('Invalid parameter')
......@@ -157,13 +155,13 @@ class Player(GameObject):
return self.offers
def mixItems(self,
item1: Item,
item2: Item):
item1: game.Item,
item2: game.Item):
pass
def makeOffer(self,
offer: Item,
demand: Item):
offer: game.Item,
demand: game.Item):
pass
def cancelOffer(self, offerId: str):
......
......@@ -6,7 +6,7 @@ import time
import sys
import sched
from command import CommandFactory, Command
import command
class RequestHandler(socketserver.BaseRequestHandler):
BUFSIZE = 4096
......@@ -23,7 +23,7 @@ class RequestHandler(socketserver.BaseRequestHandler):
jsonObject = json.loads(data)
# throw it into the command processor
factory = CommandFactory(jsonObject)
factory = command.CommandFactory(jsonObject)
command = factory.getCommand()
command.execute()
......@@ -31,7 +31,7 @@ class RequestHandler(socketserver.BaseRequestHandler):
assert(isinstance(response, dict))
self.request.sendall(json.dumps(response))
except Exception, e:
except Exception as e:
pass # TODO: log the error
def getData(self, timeout = 3):
......@@ -57,7 +57,7 @@ class RequestHandler(socketserver.BaseRequestHandler):
total_data.append(data)
begin = time.time()
except Exception, e:
except Exception as e:
# TODO: log the error
end = True
......@@ -68,8 +68,8 @@ class ThreadedTcpServer(socketserver.ThreadingMixIn, socketserver.TCPServer):
pass
def connectTracker():
factory = CommandFactory({
'method': Command.METHOD_JOIN
factory = command.CommandFactory({
'method': command.Command.METHOD_JOIN
})
command = factory.getCommand()
......@@ -81,7 +81,7 @@ def findItem(server, ip, port):
pass
if __name__ == '__main__':
HOST, PORT = 'localhost', sys.argv[1]
HOST, PORT = 'localhost', int(sys.argv[1])
server = ThreadedTcpServer((HOST, PORT), RequestHandler)
......@@ -94,4 +94,5 @@ if __name__ == '__main__':
print("Server running on thread: ", server_thread.name)
server_thread.stop()
\ No newline at end of file
while True:
pass
\ No newline at end of file
Supports Markdown
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