From 383985fb43f325636aca47a32807d27095f11f1f Mon Sep 17 00:00:00 2001 From: tuco Date: Fri, 23 Oct 2009 00:09:53 +0200 Subject: [PATCH] basic cleaning and prototype of game routine core.py moved to shakeTheFidget.py --- core.py | 117 ------------------------------- player.py | 11 +-- quest.py | 77 ++++++++++++++++++++- session.py | 201 +++++++++++++++++++++++++++++++++++++++--------------- shakeTheFidget.py | 44 ++++++++++++ 5 files changed, 267 insertions(+), 183 deletions(-) delete mode 100644 core.py create mode 100644 shakeTheFidget.py diff --git a/core.py b/core.py deleted file mode 100644 index af9bb06..0000000 --- a/core.py +++ /dev/null @@ -1,117 +0,0 @@ -#!/usr/bin/python -from sqlalchemy import create_engine -from sqlalchemy.orm import sessionmaker -from sqlalchemy.orm.exc import NoResultFound -from player import Player, metadata as playerMetadata -from session import Session -from time import time, sleep -from threading import Thread, Event, activeCount as activeThreads -import Queue - -engine = create_engine('sqlite:///test.db') -playerMetadata.create_all(engine) - -SQLSession = sessionmaker(bind=engine) -db = SQLSession() - -class QueryList(Thread): - def __init__(self, session, db): - self.session = session - self.db = db - self.eStop = Event() - Thread.__init__(self) - - def stop(self): - self.eStop.set() - - def run(self): - playerCount = self.session.request('007;%i' % (100000)).split('/')[-6] - i = 1 - while(not self.eStop.isSet()): - data = self.session.request('007;%i' % (i)) - result = data[0:3] - data = data[3:].split('/') - for j in range(15): - try: - p = self.db.query(Player).filter(Player.name == data[(j *5) +1]).one() - except NoResultFound, e: - p = Player(self.session) - p.name = data[(j *5) +1] - self.db.add(p) - p.honor = int(data[(j *5) +4]) - p.guild = data[(j *5) +2] - p.level = abs(int(data[(j *5) +3])) - print ('%s(%i) of %s - %i' % (p.name, p.level, p.guild, p.honor)).encode('unicode_escape', 'replace') - self.db.commit() - i += 15 - self.eStop.wait(5.0) - self.eStop.clear() - - def __del__(self): - self.stop() - -exit() -s = Session('Chr', 'trashor') -s.connect() -s.login() - -ql = QueryList(s, db) - - -def qArena(): - print 'Arena' - i = 0 - players = [] - while(True): - if(i >= len(players)): - players.extend(queryHoF(s, me.rank -50 +i)) - p = players[i] - if(me.level >= p.level -4): - p.query() - if(p.name != me.name and me.strikeDiff(p) > minStrikeDiff): - print('opponent found after: %i' % (i)) - p.fight() - break - i += 1 - q.put((time() +601, qArena)) - -def qWardCity(): - print 'WardCity' - me.wardCity(1) - q.put((time() +3601, qWardCity)) - -minStrikeDiff = 1 -me = Player(s, '') -me.query() - -s.close -#aralee = player.Player(a, 'Aralee') -#aralee.query() - -#test = [] -#for i in xrange(aralee.rank, aralee.rank +100, 15): -# test.extend(player.queryHoF(a, rank=i)) - -#for i in test: -# i.query() - -#while(True): -# a.fight(opponents[int(random.random()*len(opponents))]) - -#while True: -# qArena(); -# for i in range(12): -# qNoop() -# sleep(50) - -#s.close - - - - - - - - - - diff --git a/player.py b/player.py index 0fd881d..b6347eb 100644 --- a/player.py +++ b/player.py @@ -84,10 +84,8 @@ class Player(Base): self.intelligence = int(data[32])+int(data[37]) self.stamina = int(data[33])+int(data[38]) self.luck = int(data[34])+int(data[39]) - try: - self.guild = data[510].split(';')[2] - except e: - pass + try: self.guild = data[510].split(';')[2] + except: pass self.min_dmg = int(data[146]) self.max_dmg = int(data[147]) self.armor = int(data[448]) @@ -199,11 +197,6 @@ class Player(Base): self.name, ['', 'wari', 'mage', 'hunt'][self.type or 0]) - def wardCity(self, hours = 1): - if(hours < 1 or hours > 10): - raise - self.session.request('502%i' % (hours)) - sleep(hours *3600) diff --git a/quest.py b/quest.py index b945673..2d4468f 100644 --- a/quest.py +++ b/quest.py @@ -1,5 +1,53 @@ from time import sleep +class QuestList(): + def __init__(self, session): + self.session = session + self.quests = [] + + def __getattribute__(self, name): + if(name == 'minDuration'): + cur = self.quests[0] + for q in self.quests[1:]: + if(q.duration < cur.duration): + cur = q + return cur.duration + + def getBestByMoney(self, maxDuration = 1200): + cur = self.quests[0] + for q in self.quests[1:]: + if(q.silver/q.duration > cur.silver/cur.duration and q.duration <= maxDuration): + cur = q + if(q.duration <= maxDuration): + return cur + else: + return None + + def getBestByExperience(self, maxDuration = 1200): + cur = self.quests[0] + for q in self.quests[1:]: + if(q.experience/q.duration > cur.experience/cur.duration and q.duration <= maxDuration): + cur = q + if(q.duration <= maxDuration): + return cur + else: + return None + + def parse(self): + if(not result): + result = data[0:3] + data = data[3:] + + if(result == '010'): + for i in range(3): + quest = Quest( + self.session, + number = i+1, + duration = int(data[241 +i]), + silver = int(data[283 +i]), + experience = int(data[280 +i])) + self.quests.append(quest) + class Quest(): def __init__(self, session, number, duration = None, silver = None, experience = None): self.session = session @@ -8,10 +56,33 @@ class Quest(): self.silver = silver self.experience = experience + #TODO debug output def attend(self): - self.session.request('510%i' % (self.number)) - sleep(self.duration) - self.session.request('010') + try: + print 'do quest.attend quest' + r107 = self.session.request('510%i' % (self.number)) + #TODO parse + print 'done quest.attend quest' + + sleep(self.duration) + + print 'do quest.request fight' + r106 = self.session.request('010') + #TODO parse fight + print 'done quest.request fight' + + except KeyboardInterrupt: + print 'do quest.abort' + r108 = self.session.request('511') + #TODO parse + print 'done quest.abort' + + finally: + print 'do character.request' + r004 = self.session.request('004') + self.session.character.parse(r004) + print 'done character.request' + #self.session.character.silver def score(self): return float(self.experience) / float(self.duration) diff --git a/session.py b/session.py index 72d9ebc..5219a80 100644 --- a/session.py +++ b/session.py @@ -1,23 +1,17 @@ import socket from time import sleep from threading import Thread, Event, Lock + +# SQL stuff +from sqlalchemy import create_engine +from sqlalchemy.orm import sessionmaker +from palyer import metadata as metadataPlayer + +# classes from player import Player +from quest import QuestList + -class Noop(Thread): - def __init__(self, session): - self.session = session - self.stopThread = Event() - Thread.__init__(self, name='noop') - - def stop(self): - self.stopThread.set() - - def run(self): - while(not self.stopThread.isSet()): - self.session.send('999') - self.stopThread.wait(50.0) - self.stopThread.clear() - class Session(): def __init__(self, user, passwd, host = '213.165.80.92', port = 8005, version = 'v1.31'): self.user = user @@ -25,31 +19,60 @@ class Session(): self.host = host self.port = port self.version = version - self.noopThread = Noop(self) + + # s&f variables + self.character = Player(self, user) + + self.quests = QuestList() + self.questTime = 0 + + # interfaces + self.socket = None + self.db = None + self.dbEngine = None + self.dbSession = None + + # locks + self.lSocket = Lock() + + # threads + self.tNoop = Noop(self) + self.tQueryList = QueryList(self, self.db) + # database init and close + def dbInit(self, filename = 'sqlite:///%s.db' % (self.user)): + self.dbEngine = create_engine(filename) + + #create tables (if !exist) + metadataPlayer.create_all(self.dbEngine) + + #create session + self.dbSessionMaker = sessionmaker(bind=engine) + self.db = self.dbSessionMaker() + + def dbClose(self): + self.db.close() + + # server primitives: connect, send, request, disconnect def connect(self, host = None, port = None): if(host): self.host = host if(port): self.port = port self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.socket.connect((self.host, self.port)) - self.socketLock = Lock() - self.noopThread.start() + self.tNoop.start() + + def disconnect(self): + self.tNoop.stop() + self.tQueryList.stop() + self.socket.close() + self.socket = None def send(self, data): - with self.socketLock: + with self.lSocket: self.socket.send(data.encode('utf8')+chr(0)) - def recv(self, bufferlen = 1024): - with self.socketLock: - print 'warning: Session.recv() is deprecated. Use Session.request() instead!' - data = '' - while(True): - data += self.socket.recv(bufferlen) - if(data[-1:] == '\0'): break - return data[:-1].decode('utf8', 'replace') - def request(self, request, bufferlen = 1024): - with self.socketLock: + with self.lSocket: self.socket.send(request.encode('utf8')+chr(0)) data = '' while(True): @@ -57,36 +80,106 @@ class Session(): if(data[-1:] == chr(0)): break return data[:-1].decode('utf8', 'replace') - def login(self): + # s&f functions + def sfLogin(self): self.request('002%s;%s;%s' % (self.user, self.passwd, self.version)) - def close(self): - self.noopThread.stop() - self.socket.close() + def sfQueryTavern(self): + r010 = session.request('010') + code = data[0:3] + data = r010[3:].split('/') + + # questTime remaining + self.questTime = int(data[456]) + + # quests + self.quests.parse(r010) + + def wardCity(self, hours = 1): + if(hours < 1 or hours > 10): + raise ValueError + try: + self.request('502%i' % (int(hours))) + sleep(hours *3600) + except KeyboardInterrupt: + self.request('505') + finally: + self.sfQueryTavern() + + + # getattribute of dynamic values + def __getattribute__(self, name): + if(name == 'cooldownArena'): + r010 = self.request('010') + data = r010.split('/') + return int(data[460])-int(data[510]) + + # representation + def __repr__(self): + return '' % (self.name) + + # destructor + def __del__(self): + self.disconnect() + self.dbClose() + + + + +class MyThread(Thread): + def __init__(self, name = None): + self.name = name + self.eStop = Event() - def noop(self): - print 'warning: Session.noop() is deprecated.' - self.send('999') + def start(self): + Thread.__init__(self, name=self.name) + Thread.start(self) - def queryHoF(self, rank = -1, name = ''): - if(rank > -1): rank += 7 - data = self.request('007%s;%i' % (name, rank)) - result = data[0:3] - data = data[3:].split('/') - players = [] - for i in range(15): - p = Player(self) - p.rank = int(data[(i *5)]) - p.name = data[(i *5) +1] - p.guild = data[(i *5) +2] - p.level = int(data[(i *5) +3]) - p.honor = int(data[(i *5) +4]) - players.append(p) - return players + def stop(self): + if(self.isAlive()): + self.eStop.set() + self.join() def __del__(self): - self.close() + self.stop() + +class Noop(MyThread): + def __init__(self, session): + self.session = session + MyThread.__init__(self, name='Noop') - def __repr__(self): - return '' % (self.name) + def run(self): + while(not self.eStop.isSet()): + self.session.send('999') + self.eStop.wait(50.0) + self.eStop.clear() +class QueryList(MyThread): + def __init__(self, session, db): + self.session = session + self.db = db + + def run(self): + playerCount = self.session.request('007;%i' % (100000)).split('/')[-6] + i = 1 + while(not self.eStop.isSet()): + data = self.session.request('007;%i' % (i)) + result = data[0:3] + data = data[3:].split('/') + for j in range(15): + try: + #new = False + p = self.db.query(Player).filter(Player.name == data[(j *5) +1]).one() + except NoResultFound, e: + #new = True + p = Player(self.session) + p.name = data[(j *5) +1] + self.db.add(p) + p.honor = int(data[(j *5) +4]) + p.guild = data[(j *5) +2] + p.level = abs(int(data[(j *5) +3])) + #print ('%s%s(%i) of %s - %i' % (['~', '+'][new], p.name, p.level, p.guild, p.honor)).encode('unicode_escape', 'replace') + self.db.commit() + i += 15 + self.eStop.wait(5.0) + self.eStop.clear() diff --git a/shakeTheFidget.py b/shakeTheFidget.py new file mode 100644 index 0000000..733e7db --- /dev/null +++ b/shakeTheFidget.py @@ -0,0 +1,44 @@ +#!/usr/bin/python +from session import Session +from time import time, sleep +from sys import argv + + +# parse parameters +if(len(argv) < 3): + print """%s [options, ..] """ % (argv[0]) + exit() +user = argv[-2] +passwd = argv[-1] + +# setup session with connection and db +session = Session(user, passwd) +session.connect() +session.dbInit() + +# login to the server +session.sfLogin() + +# game routine +while(True): + session.sfQueryTavern() + if(session.questTime >= session.QuestList.minDuration): + quest = session.QuestList.getBestByExperience() + if(quest): + quest.attend() + + if(session.cooldownArena <= 0): + # find opponent and fight + else: + session.citywar + +# destruct session +del session + + + + + + + + -- 2.11.4.GIT