basic cleaning and prototype of game routine
[shakeTheFidget.git] / session.py
blob5219a80ebc8af2159ec2862ea259cfc8387c5f50
1 import socket
2 from time import sleep
3 from threading import Thread, Event, Lock
5 # SQL stuff
6 from sqlalchemy import create_engine
7 from sqlalchemy.orm import sessionmaker
8 from palyer import metadata as metadataPlayer
10 # classes
11 from player import Player
12 from quest import QuestList
15 class Session():
16 def __init__(self, user, passwd, host = '213.165.80.92', port = 8005, version = 'v1.31'):
17 self.user = user
18 self.passwd = passwd
19 self.host = host
20 self.port = port
21 self.version = version
23 # s&f variables
24 self.character = Player(self, user)
26 self.quests = QuestList()
27 self.questTime = 0
29 # interfaces
30 self.socket = None
31 self.db = None
32 self.dbEngine = None
33 self.dbSession = None
35 # locks
36 self.lSocket = Lock()
38 # threads
39 self.tNoop = Noop(self)
40 self.tQueryList = QueryList(self, self.db)
42 # database init and close
43 def dbInit(self, filename = 'sqlite:///%s.db' % (self.user)):
44 self.dbEngine = create_engine(filename)
46 #create tables (if !exist)
47 metadataPlayer.create_all(self.dbEngine)
49 #create session
50 self.dbSessionMaker = sessionmaker(bind=engine)
51 self.db = self.dbSessionMaker()
53 def dbClose(self):
54 self.db.close()
56 # server primitives: connect, send, request, disconnect
57 def connect(self, host = None, port = None):
58 if(host): self.host = host
59 if(port): self.port = port
60 self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
61 self.socket.connect((self.host, self.port))
62 self.tNoop.start()
64 def disconnect(self):
65 self.tNoop.stop()
66 self.tQueryList.stop()
67 self.socket.close()
68 self.socket = None
70 def send(self, data):
71 with self.lSocket:
72 self.socket.send(data.encode('utf8')+chr(0))
74 def request(self, request, bufferlen = 1024):
75 with self.lSocket:
76 self.socket.send(request.encode('utf8')+chr(0))
77 data = ''
78 while(True):
79 data += self.socket.recv(bufferlen)
80 if(data[-1:] == chr(0)): break
81 return data[:-1].decode('utf8', 'replace')
83 # s&f functions
84 def sfLogin(self):
85 self.request('002%s;%s;%s' % (self.user, self.passwd, self.version))
87 def sfQueryTavern(self):
88 r010 = session.request('010')
89 code = data[0:3]
90 data = r010[3:].split('/')
92 # questTime remaining
93 self.questTime = int(data[456])
95 # quests
96 self.quests.parse(r010)
98 def wardCity(self, hours = 1):
99 if(hours < 1 or hours > 10):
100 raise ValueError
101 try:
102 self.request('502%i' % (int(hours)))
103 sleep(hours *3600)
104 except KeyboardInterrupt:
105 self.request('505')
106 finally:
107 self.sfQueryTavern()
110 # getattribute of dynamic values
111 def __getattribute__(self, name):
112 if(name == 'cooldownArena'):
113 r010 = self.request('010')
114 data = r010.split('/')
115 return int(data[460])-int(data[510])
117 # representation
118 def __repr__(self):
119 return '<Session \'%s\'>' % (self.name)
121 # destructor
122 def __del__(self):
123 self.disconnect()
124 self.dbClose()
129 class MyThread(Thread):
130 def __init__(self, name = None):
131 self.name = name
132 self.eStop = Event()
134 def start(self):
135 Thread.__init__(self, name=self.name)
136 Thread.start(self)
138 def stop(self):
139 if(self.isAlive()):
140 self.eStop.set()
141 self.join()
143 def __del__(self):
144 self.stop()
146 class Noop(MyThread):
147 def __init__(self, session):
148 self.session = session
149 MyThread.__init__(self, name='Noop')
151 def run(self):
152 while(not self.eStop.isSet()):
153 self.session.send('999')
154 self.eStop.wait(50.0)
155 self.eStop.clear()
157 class QueryList(MyThread):
158 def __init__(self, session, db):
159 self.session = session
160 self.db = db
162 def run(self):
163 playerCount = self.session.request('007;%i' % (100000)).split('/')[-6]
164 i = 1
165 while(not self.eStop.isSet()):
166 data = self.session.request('007;%i' % (i))
167 result = data[0:3]
168 data = data[3:].split('/')
169 for j in range(15):
170 try:
171 #new = False
172 p = self.db.query(Player).filter(Player.name == data[(j *5) +1]).one()
173 except NoResultFound, e:
174 #new = True
175 p = Player(self.session)
176 p.name = data[(j *5) +1]
177 self.db.add(p)
178 p.honor = int(data[(j *5) +4])
179 p.guild = data[(j *5) +2]
180 p.level = abs(int(data[(j *5) +3]))
181 #print ('%s%s(%i) of %s - %i' % (['~', '+'][new], p.name, p.level, p.guild, p.honor)).encode('unicode_escape', 'replace')
182 self.db.commit()
183 i += 15
184 self.eStop.wait(5.0)
185 self.eStop.clear()