model.py 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286
  1. import re
  2. import sqlite3 as db
  3. import sys
  4. import uuid
  5. import db_setup
  6. from game import CURRENCY_NAME
  7. from util import debug
  8. connection = None
  9. cursor = None
  10. db_name = None
  11. def query_save_name():
  12. global db_name
  13. if debug:
  14. db_name = 'test.db'
  15. return
  16. while True:
  17. save_name = input('Name of the savegame: ')
  18. if re.match(r"[A-Za-z0-9.-]{0,50}", save_name):
  19. db_name = save_name + '.db'
  20. return
  21. else:
  22. print('Must match "[A-Za-z0-9.-]{0,50}"')
  23. def connect(reconnect=False):
  24. global connection
  25. global cursor
  26. global db_name
  27. if reconnect:
  28. connection.commit()
  29. connection.close()
  30. cursor = None
  31. connection = None
  32. db_name = None
  33. if connection is None or cursor is None:
  34. query_save_name()
  35. try:
  36. connection = db.connect(db_name)
  37. cursor = connection.cursor()
  38. except db.Error as e:
  39. print("Database error %s:" % e.args[0])
  40. sys.exit(1)
  41. # finally:
  42. # if con is not None:
  43. # con.close()
  44. def setup():
  45. connect()
  46. db_setup.setup(cursor)
  47. connection.commit()
  48. def login(username, password):
  49. connect()
  50. # do not allow login as bank
  51. if password == '':
  52. return None
  53. cursor.execute('''
  54. SELECT rowid
  55. FROM users
  56. WHERE username = ?
  57. AND password = ?
  58. ''', (username, password))
  59. user_id = cursor.fetchone()
  60. if user_id:
  61. return new_session(user_id)
  62. else:
  63. return None
  64. def register(username, password, game_key):
  65. connect()
  66. if username == '':
  67. return False
  68. if password == '':
  69. return False
  70. cursor.execute('''
  71. INSERT INTO users
  72. (username, password)
  73. VALUES (? , ?)
  74. ''', (username, password))
  75. own(username, CURRENCY_NAME)
  76. if game_key != '':
  77. if valid_key(game_key):
  78. activate_key(game_key, get_user_id_by_name(username))
  79. return True
  80. def own(username, ownable_name):
  81. cursor.execute('''
  82. INSERT INTO ownership
  83. (user_id, ownable_id)
  84. VALUES ((SELECT rowid FROM users WHERE username = ?),
  85. (SELECT rowid FROM ownables WHERE name = ?))
  86. ''', (username, ownable_name))
  87. def send_ownable(from_user_id, to_user_id, ownable_name, amount):
  88. connect()
  89. if amount < 0:
  90. return False
  91. if from_user_id != bank_id():
  92. cursor.execute('''
  93. UPDATE ownership
  94. SET amount = amount - ?
  95. WHERE user_id = ?
  96. AND ownable_id = (SELECT rowid FROM ownables WHERE name = ?)
  97. ''', (amount, from_user_id, ownable_name,))
  98. if not cursor.fetchone():
  99. return False
  100. cursor.execute('''
  101. UPDATE ownership
  102. SET amount = amount + ?
  103. WHERE user_id = ?
  104. AND ownable_id = (SELECT rowid FROM ownables WHERE name = ?)
  105. ''', (amount, to_user_id, ownable_name))
  106. if cursor.rowcount == 0:
  107. return False
  108. return True
  109. def valid_key(key): # TODO possible performance increase when database gets larger by using sql directly
  110. return key in unused_keys()
  111. def new_session(user_id):
  112. connect()
  113. session_id = str(uuid.uuid4())
  114. cursor.execute('''
  115. INSERT INTO SESSIONS
  116. (user_id, session_id)
  117. VALUES (? , ?)
  118. ''', (user_id[0], session_id))
  119. return session_id
  120. def save_key(key):
  121. connect()
  122. cursor.execute('''
  123. INSERT INTO keys
  124. (key)
  125. VALUES (?)
  126. ''', (key,))
  127. def drop_old_sessions():
  128. connect()
  129. # TODO: test
  130. cursor.execute('''
  131. DELETE FROM sessions s1
  132. WHERE
  133. (SELECT COUNT(*) as newer
  134. FROM sessions s2
  135. WHERE s1.user_id = s2.user_id
  136. AND s1.rowid < s2.rowid) >= 10
  137. ''')
  138. def user_exists(username):
  139. connect()
  140. cursor.execute('''
  141. SELECT rowid
  142. FROM users
  143. WHERE username = ?
  144. ''', (username,))
  145. if cursor.fetchone():
  146. return True
  147. else:
  148. return False
  149. def unused_keys():
  150. connect()
  151. cursor.execute('''
  152. SELECT key
  153. FROM keys
  154. WHERE used_by_user_id IS NULL
  155. ''')
  156. return [str(key[0]).strip().upper() for key in cursor.fetchall()]
  157. def get_user_id_by_session_id(session_id):
  158. connect()
  159. cursor.execute('''
  160. SELECT users.rowid
  161. FROM sessions, users
  162. WHERE sessions.session_id = ?
  163. AND users.rowid = sessions.user_id
  164. ''', (session_id,))
  165. ids = cursor.fetchone()
  166. if ids is None:
  167. return False
  168. return ids[0]
  169. def get_user_id_by_name(username):
  170. connect()
  171. cursor.execute('''
  172. SELECT users.rowid
  173. FROM users
  174. WHERE username = ?
  175. ''', (username,))
  176. return cursor.fetchone()[0]
  177. def get_user_ownership(user_id):
  178. connect()
  179. cursor.execute('''
  180. SELECT ownables.name, ownership.amount
  181. FROM ownership, ownables
  182. WHERE user_id = ?
  183. AND ownership.ownable_id = ownables.rowid
  184. ''', (user_id,))
  185. return cursor.fetchall()
  186. def activate_key(key, user_id):
  187. connect()
  188. cursor.execute('''
  189. UPDATE keys
  190. SET used_by_user_id = ?
  191. WHERE used_by_user_id IS NULL
  192. AND key = ?
  193. ''', (user_id, key,))
  194. if cursor.rowcount == 0:
  195. raise AssertionError
  196. send_ownable(bank_id(), user_id, CURRENCY_NAME, 1000)
  197. def bank_id():
  198. connect()
  199. cursor.execute('''
  200. SELECT users.rowid
  201. FROM users
  202. WHERE username = 'bank'
  203. ''')
  204. return cursor.fetchone()[0]
  205. def valid_session_id(session_id):
  206. connect()
  207. cursor.execute('''
  208. SELECT rowid
  209. FROM sessions
  210. WHERE session_id = ?
  211. ''', (session_id,))
  212. if cursor.fetchone():
  213. return True
  214. else:
  215. return False