Commit ffd7f092 authored by mamat-rahmat's avatar mamat-rahmat
Browse files

add server that use thread

parent 5a257e08
import socket
import json
import hashlib
import pymongo
import threading
from pymongo import MongoClient
# informasi port dan socket
hostTracker = "167.205.32.46"
portTracker = 8000
hostLaptop = ""
# config MongoDB
database = ""
playerCollection = ""
inventoriCollection = ""
offerCollection = ""
marketCollection = ""
# list server yang aktif
listActiveServer = []
# jenis item
items = ["honey", "herbs", "clay", "mineral", "potion", "incense", "gems", "elixir", "crystal", "stone"]
def createDatabase():
global database
database = client["quest"]
global playerCollection
playerCollection = database["player"]
global inventoriCollection
inventoriCollection = database["inventori"]
global offerCollection
offerCollection = database["offer"]
global marketCollection
marketCollection = database["market"]
def getIPAdress():
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.connect(("itb.ac.id",0))
global hostLaptop
hostLaptop = s.getsockname()[0]
s.close()
def getItemName(index):
return items[index]
def join(portLaptop):
print("join")
global listActiveServer
# inisialisasi socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((hostTracker,portTracker))
getIPAdress()
message = '{ "method" : "join", "ip" : "' + hostLaptop + '", "port" : ' + str(portLaptop) + ' }'
print(message)
s.send(str.encode(message))
tm = s.recv(4096)
tmString = tm.decode("utf-8")
tmJSON = json.JSONDecoder().decode(tmString)
# update list server aktif
listActiveServer = tmJSON["value"]
s.close()
# jalankan thread server utama
playserver(portLaptop)
#def accept(portLaptop, offer_token):
#print("accept_broadcast")
#s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# BROADCAST KE SEMUA SERVER UNTUK KONFIRMASI SERVER LAIN OFFER YANG SUDAH DITERIMA
#s.connect((,portTracker))
def playserver(portLaptop):
# config database mongodb
global client
client = MongoClient("localhost", 27107)
global database
database = client["quest"]
global playerCollection
playerCollection = database["player"]
global inventoriCollection
inventoriCollection = database["inventori"]
global offerCollection
offerCollection = database["offer"]
global marketCollection
marketCollection = database["market"]
# Mulai open socket server
print("playserver")
s = socket.socket()
s.bind((hostLaptop,portLaptop))
s.listen(5) # tunggu koneksi dari socket client
while True:
a, c = s.accept()
t = threading.Thread(target=handler, args = (a,c))
t.daemon = True
t.start()
s.close()
def handler(a, c):
# parsing bytes stream to json
data = a.recv(2048)
dataString = data.decode("utf-8")
dataJSON = json.JSONDecoder().decode(dataString)
# for debug
print("- " + str(dataJSON))
#process request
method = dataJSON['method']
response = "" # response from server to client
if (method == "signup"):
username = dataJSON["username"]
password = dataJSON["password"]
kriteriaObject = {"username" : username}
# user sudah terdaftar, keluarkan status gagal
if (database.playerCollection.find(kriteriaObject).count() != 0):
response = '{"status" : "fail", "description" : "username exists"}'
# user belum terdaftar, insert username dan password ke database
else:
# generate token player
objectToken = hashlib.md5(str.encode(username + password));
tokenuser = objectToken.hexdigest();
# insert player baru di playerCollection, insert inventori kosong
kriteria1Object = {"token" : tokenuser, "username" : username, "password" : password, "posisiX" : 0, "posisiY" : 0, "player_time" : 0}
kriteria2Object = {"token" : tokenuser, "honey" : 3, "herbs" : 3, "clay" : 3, "mineral" : 0, "potion" : 0, "incense" : 0, "gems" : 0, "elixir" : 0, "crystal" : 0, "stone" : 0}
database.playerCollection.insert(kriteria1Object)
database.inventoriCollection.insert(kriteria2Object)
# tulis response
response = '{"status" : "ok"}'
elif (method == "serverStatus"):
global listActiveServer
del listActiveServer[:] # hapus list
#update ulang list server aktif
listActiveServer = dataJSON["server"]
response = '{"status" : "ok"}'
print(listActiveServer)
elif (method == "login"):
username = dataJSON["username"]
password = dataJSON["password"]
kriteria1Object = {"username" : username, "password" : password}
# user sudah terdaftar, generate token user
if (database.playerCollection.find(kriteria1Object).count() != 0):
# mendapatkan posisi dan time player terakhir
user = database.playerCollection.find_one(kriteria1Object)
posisiX = user["posisiX"]
posisiY = user["posisiY"]
time = user["player_time"]
tokenuser = user["token"]
# tulis response
response = '{"status" : "ok", "token" : "' + tokenuser + '" , "x" : ' + str(posisiX) + ', "y" : ' + str(posisiY) + ', "time" : ' + str(time) + ' }'
# user belum terdaftar, keluarkan status gagal
else:
response = '{"status" : "fail", "description" : "username/password combination is not found"}'
elif (method == "inventory"):
token = dataJSON["token"]
kriteria1Object = { "token" : token }
row = database.inventoriCollection.find_one(kriteria1Object)
inventori = "["
for i in range(10):
inventori += str(row[getItemName(i)])
if (i != 9):
inventori += ", "
else:
inventori += "]"
response = '{ "status" : "ok", "inventory" : ' + inventori + '}'
elif (method == "mixitem"):
token = dataJSON["token"]
item1 = dataJSON["item1"]
item2 = dataJSON["item2"]
itemresult = -1
if ((item2 == item1 + 1) and ((item1 != 3) or (item1 != 6) or (item1 != 8) or (item1 != 9))):
name_item1 = getItemName(item1)
name_item2 = getItemName(item2)
kriteria1Object = { "token" : token }
n_item = database.inventoriCollection.find_one(kriteria1Object)
if ((n_item[name_item1] < 3) or (n_item[name_item2] < 3)):
itemresult = -1
else:
if ((item1 != 3) and (item1 != 6) and (item1 != 8) and (item1 != 9)):
if (item1 == 0):
itemresult = 4
elif (item1 == 1):
itemresult = 5
elif (item1 == 2):
itemresult = 6
elif (item1 == 4):
itemresult = 7
elif (item1 == 5):
itemresult = 8
elif (item1 == 7):
itemresult = 9
# kurangi jumlah item 1 dan 2 sebanyak 3 item
n_item1_baru = n_item[name_item1] - 3
n_item2_baru = n_item[name_item2] - 3
kriteriaItem1 = {"$set" : {name_item1:n_item1_baru}}
kriteriaItem2 = {"$set" : {name_item2:n_item2_baru}}
database.inventoriCollection.update(kriteria1Object,kriteriaItem1)
database.inventoriCollection.update(kriteria1Object,kriteriaItem2)
# tambah jumlah item campuran sebanyak 1 item
name_mixture = getItemName(itemresult)
n_item_mixture = n_item[getItemName(itemresult)] + 1
kriteriaItemMixture = {"$set" : {name_mixture:n_item_mixture}}
database.inventoriCollection.update(kriteria1Object,kriteriaItemMixture)
else:
itemresult = -1
else:
itemresult = -1
if (itemresult != -1):
response = '{ "status" : "ok", "item" : ' + str(itemresult) + '}'
else:
response = '{"status" : "fail", "description" : "wrong mixture" }'
elif (method == "fetchitem"):
token = dataJSON["token"]
offer_token = dataJSON["offer_token"]
kriteria1Object = {"offer_token" : offer_token}
if (database.offerCollection.find(kriteria1Object).count() != 0):
offer = database.offerCollection.find_one(kriteria1Object)
if (offer["availability"] == 0): # ready to fetch
# buat json object dari string kriteria update dan remove
kriteria2Object = {"token" : token}
# nama dan jumlah demand item yang baru setelah fetchitem
name_demand = getItemName(offer["demand_item"])
n_demand_old = database.inventoriCollection.find_one(kriteria2Object)
n_demand = offer["n_item2"] + n_demand_old[name_demand]
# buat json object dari string kriteria update dan remove
kriteria3Object = {"$set" : {name_demand : n_demand}}
# update data inventori dengan yang terbaru
database.inventoriCollection.update(kriteria2Object,kriteria3Object)
# hapus record offer tersebut
database.offerCollection.remove(kriteria1Object)
response = '{"status" : "ok"}'
else:
response = '{"status" : "fail", "description" : "still available"}'
else:
response = "{'status' : 'fail','description':'not exists'}"
#elif (method == "move"):
#elif (method == "field"):
elif (method == "map"):
response = '{"status" : "ok", "name" : "Bandar Behari", "width" : 5, "height" : 5}'
elif (method == "offer"):
token = dataJSON["token"]
offer_item = dataJSON["offer_item"]
n_item1 = dataJSON["n1"]
demand_item = dataJSON["demand_item"]
n_item2 = dataJSON["n2"]
kriteria1Object = {"token" : token}
if (database.playerCollection.find(kriteria1Object).count() != 0):
player = database.playerCollection.find_one(kriteria1Object)
inventory = database.inventoriCollection.find_one(kriteria1Object)
n_item1_inventory = inventory[getItemName(offer_item)]
if (n_item1_inventory >= n_item1):
objectOfferToken = hashlib.md5(str.encode(str(player['username']) + str(player['player_time'])))
offered_token = objectOfferToken.hexdigest();
#kurangi offer item di inventori
kriteria2Object = {"token" : token}
kriteria3Object = {"$set" : {getItemName(offer_item) : n_item1_inventory - n_item1}}
database.inventoriCollection.update(kriteria2Object,kriteria3Object)
kriteria2Object = {'offer_item' : offer_item, 'n_item1' : n_item1, 'demand_item' : demand_item, 'n_item2' : n_item2, 'availability' : 'true', 'offered_token' : offered_token, 'user_token' : token}
database.offerCollection.insert(kriteria2Object)
response = '{"status" : "ok"}'
else:
response = '{"status" : "fail", "description" : "items not enough"}'
else:
response = '{"status" : "fail", "description" : "wrong token"}'
elif (method == "tradebox"):
token = dataJSON["token"]
kriteria1Object = {"user_token" : token}
offer_self = []
for temp in database.offerCollection.find(kriteria1Object):
data = []
data.append( temp["offer_item"] )
data.append( temp["n_item1"] )
data.append( temp["demand_item"] )
data.append( temp["n_item2"] )
data.append( temp["availability"] )
data.append( temp["offered_token"] )
offer_self.append(data)
dictResponse = { "status" : "ok", "offers" : offer_self }
response = str(dictResponse)
elif (method == 'sendfind'):
token = dataJSON['token']
item = dataJSON['item']
kriteria1Object = {"offer_item" : item}
offer_all = []
for temp in database.marketCollection.find(kriteria1Object):
data = []
data.append( temp["offer_item"] )
data.append( temp["n_item1"] )
data.append( temp["demand_item"] )
data.append( temp["n_item2"] )
data.append( temp["availability"] )
data.append( temp["offered_token"] )
offer_self.append(data)
dictResponse = { "status" : "ok", "offers" : offer_self }
response = str(dictResponse)
elif (method == 'findoffer'):
# TODO : AMBIL DARI SEMUA SERVER
item = dataJSON['item']
kriteria1Object = {"offer_item" : item}
offer_all = []
for temp in offerCollection.find(kriteria1Object):
data = []
data.append( temp["offer_item"] )
data.append( temp["n_item1"] )
data.append( temp["demand_item"] )
data.append( temp["n_item2"] )
data.append( temp["availability"] )
data.append( temp["offered_token"] )
offer_self.append(data)
dictResponse = { "status" : "ok", "offers" : offer_self }
response = str(dictResponse)
elif (method == 'canceloffer'):
token = dataJSON['token']
offered_token = dataJSON['offered_token']
kriteria1Object = {"offered_token" : offered_token}
if (database.offerCollection.find(kriteria1Object).count() != 0):
offer = database.offerCollection.find_one(kriteria1Object)
if (offer['availability'] == 0): # already finished
response = "{'status':'fail','description':'already finished'}"
else:
# buat json object dari string kriteria update dan remove
kriteria2Object = {"token":token}
# nama dan jumlah offer item setelah canceloffer
name_offer = getItemName(offer['offer_item'])
n_offer_old = database.inventoriCollection.find_one(kriteria2Object)
n_offer = offer['n_item1'] + n_offer_old[name_offer]
# buat json object dari string kriteria update dan remove
kriteria3Object = {"$set": {name_offer : n_offer}}
# update data inventori dengan yang terbaru
database.inventoriCollection.update(kriteria2Object,kriteria3Object)
# hapus record offer tersebut
database.offerCollection.remove(kriteria1Object)
response = "{'status':'ok'}"
else:
response = "{'status':'fail','description':'not exists'}"
elif (method == 'sendaccept'):
# TODO : KIRIM PESAN ACCEPT KE SERVER LAIN
token = dataJSON['token']
offered_token = dataJSON['offered_token']
kriteria1Object = {"offered_token": offered_token}
if (database.marketCollection.find(kriteria1Object).count() != 0):
# Dapat jumlah item yang dioffer beserta nama itemnya
offer = database.marketCollection.find_one(kriteria1Object)
n_offer = offer['n_item1']
name_offer = getItemName(offer['offer_item'])
# Tambahkan jumlah item offer yang diterima dengan item lama
kriteria2Object = {"token" : token}
inventoriLama = database.inventoriCollection.find_one(kriteria2Object)
n_item_baru = n_offer + inventoriLama[name_offer]
# Set data offering jadi unavailable
database.marketCollection.update(kriteria1Object,{"$set" : {"availability":"false"}})
# Update inventori setelah accept offer
database.inventoriCollection.update(kriteria2Object,{"$set" : {name_offer:n_item_baru}})
response = "{'status' : 'ok'}"
else:
kriteria2Object = {"offered_token" : offered_token}
response = "{'status' : 'fail', 'description' : 'not exists'}"
elif (method == 'accept'):
offered_token = dataJSON['offered_token']
kriteria1Object = {"offered_token" : offered_token,"availability" : "false"}
if (database.marketCollection.find(kriteria1Object).count() != 0):
response = "{'status':'ok'}"
else:
response = "{'status' : 'fail', 'description' : 'offer is not available'}"
else:
response = "{'status' : 'error'}"
#for debug
print("+ " + response)
#kirim response ke client
a.sendall(str.encode(response))
#tutup koneksi socket client
a.close()
# main program
if __name__ == '__main__':
join(8500)
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