Guest User

Untitled

a guest
Jun 6th, 2018
196
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 65.44 KB | None | 0 0
  1. #
  2. # -*- py-indent-offset: 4; coding: iso-8859-1 -*-
  3. #
  4. # Copyright (C) 2006, 2007 Loic Dachary <loic@dachary.org>
  5. # Copyright (C) 2004, 2005, 2006 Mekensleep
  6. #
  7. # Mekensleep
  8. # 24 rue vieille du temple
  9. # 75004 Paris
  10. # licensing@mekensleep.com
  11. #
  12. # This program is free software; you can redistribute it and/or modify
  13. # it under the terms of the GNU General Public License as published by
  14. # the Free Software Foundation; either version 2 of the License, or
  15. # (at your option) any later version.
  16. #
  17. # This program is distributed in the hope that it will be useful,
  18. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  19. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  20. # GNU General Public License for more details.
  21. #
  22. # You should have received a copy of the GNU General Public License
  23. # along with this program; if not, write to the Free Software
  24. # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
  25. #
  26. # Authors:
  27. # Loic Dachary <loic@gnu.org>
  28. # Henry Precheur <henry@precheur.org> (2004)
  29. # Cedric Pinson <cpinson@freesheep.org>
  30.  
  31. from os.path import exists
  32. from types import *
  33. from string import split, join
  34. import time
  35. import os
  36. import operator
  37. import re
  38. from traceback import print_exc
  39.  
  40. from MySQLdb.cursors import DictCursor
  41. from MySQLdb.constants import ER
  42.  
  43. from OpenSSL import SSL
  44.  
  45. try:
  46. from OpenSSL import SSL
  47. HAS_OPENSSL=True
  48. except:
  49. print "openSSL not available."
  50. HAS_OPENSSL=False
  51.  
  52.  
  53. from twisted.application import service
  54. from twisted.internet import protocol, reactor, defer
  55. try:
  56. # twisted-2.0
  57. from zope.interface import Interface, implements
  58. except ImportError:
  59. # twisted-1.3 forwards compatibility
  60. def implements(interface):
  61. frame = sys._getframe(1)
  62. locals = frame.f_locals
  63.  
  64. # Try to make sure we were called from a class def
  65. if (locals is frame.f_globals) or ('__module__' not in locals):
  66. raise TypeError(" can be used only from a class definition.")
  67.  
  68. if '__implements__' in locals:
  69. raise TypeError(" can be used only once in a class definition.")
  70.  
  71. locals['__implements__'] = interface
  72.  
  73. from twisted.python.components import Interface
  74.  
  75. from twisted.python import components
  76.  
  77. from pokerengine.pokertournament import *
  78. from pokerengine.pokercards import PokerCards
  79.  
  80. from pokernetwork.server import PokerServerProtocol
  81. from pokernetwork.user import checkName, checkPassword
  82. from pokernetwork.pokerdatabase import PokerDatabase
  83. from pokernetwork.pokerpackets import *
  84. from pokernetwork.pokertable import PokerTable
  85. from pokernetwork import pokeravatar
  86. from pokernetwork.user import User
  87. from pokernetwork import pokercashier
  88.  
  89. UPDATE_TOURNEYS_SCHEDULE_DELAY = 10 * 60
  90. CHECK_TOURNEYS_SCHEDULE_DELAY = 60
  91. DELETE_OLD_TOURNEYS_DELAY = 15 * 60
  92.  
  93. class IPokerService(Interface):
  94.  
  95. def createAvatar(self):
  96. """ """
  97.  
  98. def destroyAvatar(self, avatar):
  99. """ """
  100.  
  101. class IPokerFactory(Interface):
  102.  
  103. def createAvatar(self):
  104. """ """
  105.  
  106. def destroyAvatar(self, avatar):
  107. """ """
  108.  
  109. def buildProtocol(self, addr):
  110. """ """
  111.  
  112. class PokerFactoryFromPokerService(protocol.ServerFactory):
  113.  
  114. implements(IPokerFactory)
  115.  
  116. protocol = PokerServerProtocol
  117.  
  118. def __init__(self, service):
  119. self.service = service
  120. self.verbose = service.verbose
  121.  
  122. def createAvatar(self):
  123. """ """
  124. return self.service.createAvatar()
  125.  
  126. def destroyAvatar(self, avatar):
  127. """ """
  128. return self.service.destroyAvatar(avatar)
  129.  
  130. components.registerAdapter(PokerFactoryFromPokerService,
  131. IPokerService,
  132. IPokerFactory)
  133.  
  134. class PokerService(service.Service):
  135.  
  136. implements(IPokerService)
  137.  
  138. def __init__(self, settings):
  139. self.settings = settings
  140. self.verbose = self.settings.headerGetInt("/server/@verbose")
  141. self.delays = settings.headerGetProperties("/server/delays")[0]
  142. self.db = None
  143. self.cashier = None
  144. self.poker_auth = None
  145. self.timer = {}
  146. self.down = True
  147. self.shutdown_deferred = None
  148.  
  149. def startService(self):
  150. self.db = PokerDatabase(self.settings)
  151. self.cleanupCrashedTables()
  152. self.cleanUp(temporary_users = self.settings.headerGet("/server/users/@temporary"))
  153. self.cashier = pokercashier.PokerCashier(self.settings)
  154. self.cashier.setDb(self.db)
  155. self.poker_auth = PokerAuth(self.db, self.settings)
  156. self.dirs = split(self.settings.headerGet("/server/path"))
  157. self.serial2client = {}
  158. self.avatars = []
  159. self.tables = []
  160. self.table_serial = 100
  161. self.shutting_down = False
  162. self.simultaneous = self.settings.headerGetInt("/server/@simultaneous")
  163. self._ping_delay = self.settings.headerGetInt("/server/@ping")
  164. self.chat = self.settings.headerGet("/server/@chat") == "yes"
  165. for description in self.settings.headerGetProperties("/server/table"):
  166. self.createTable(0, description)
  167. self.cleanupTourneys()
  168. self.updateTourneysSchedule()
  169. self.messageCheck()
  170. self.poker_auth.SetLevel(PACKET_POKER_SEAT, User.REGULAR)
  171. self.poker_auth.SetLevel(PACKET_POKER_GET_USER_INFO, User.REGULAR)
  172. self.poker_auth.SetLevel(PACKET_POKER_GET_PERSONAL_INFO, User.REGULAR)
  173. self.poker_auth.SetLevel(PACKET_POKER_PLAYER_INFO, User.REGULAR)
  174. self.poker_auth.SetLevel(PACKET_POKER_TOURNEY_REGISTER, User.REGULAR)
  175. self.poker_auth.SetLevel(PACKET_POKER_HAND_SELECT_ALL, User.ADMIN)
  176. service.Service.startService(self)
  177. self.down = False
  178.  
  179. def stopServiceFinish(self, x):
  180. if self.cashier: self.cashier.close()
  181. if self.db: self.db.close()
  182. if self.poker_auth: self.poker_auth.db = None
  183. service.Service.stopService(self)
  184.  
  185. def stopService(self):
  186. deferred = self.shutdown()
  187. deferred.addCallback(lambda x: reactor.disconnectAll())
  188. deferred.addCallback(self.stopServiceFinish)
  189. return deferred
  190.  
  191. def cancelTimer(self, key):
  192. if self.timer.has_key(key):
  193. if self.verbose > 3: print "cancelTimer " + key
  194. timer = self.timer[key]
  195. if timer.active():
  196. timer.cancel()
  197. del self.timer[key]
  198.  
  199. def shutdown(self):
  200. self.shutting_down = True
  201. self.cancelTimer('checkTourney')
  202. self.cancelTimer('updateTourney')
  203. self.cancelTimer('messages')
  204. self.shutdown_deferred = defer.Deferred()
  205. reactor.callLater(0.01, self.shutdownCheck)
  206. return self.shutdown_deferred
  207.  
  208. def shutdownCheck(self):
  209. if self.down:
  210. if self.shutdown_deferred:
  211. self.shutdown_deferred.callback(True)
  212. return
  213.  
  214. playing = 0
  215. for table in self.tables:
  216. if not table.game.isEndOrNull():
  217. playing += 1
  218. if self.verbose and playing > 0:
  219. print "Shutting down, waiting for %d games to finish" % playing
  220. if playing <= 0:
  221. if self.verbose:
  222. print "Shutdown immediately"
  223. self.down = True
  224. self.shutdown_deferred.callback(True)
  225. self.shutdown_deferred = False
  226. else:
  227. reactor.callLater(10, self.shutdownCheck)
  228.  
  229. def isShuttingDown(self):
  230. return self.shutting_down
  231.  
  232. def stopFactory(self):
  233. pass
  234.  
  235. def createAvatar(self):
  236. avatar = pokeravatar.PokerAvatar(self)
  237. self.avatars.append(avatar)
  238. return avatar
  239.  
  240. def destroyAvatar(self, avatar):
  241. if avatar in self.avatars:
  242. self.avatars.remove(avatar)
  243. else:
  244. print "*ERROR* PokerService: avatar %s is not in the list of known avatars" % str(avatar)
  245. avatar.connectionLost("Disconnected")
  246.  
  247. def sessionStart(self, serial, ip):
  248. if self.verbose > 2: print "PokerService::sessionStart(%d, %s): " % ( serial, ip )
  249. cursor = self.db.cursor()
  250. sql = "insert into session ( user_serial, started, ip ) values ( %d, %d, '%s')" % ( serial, time.time(), ip )
  251. cursor.execute(sql)
  252. if cursor.rowcount != 1: print " *ERROR* modified %d rows (expected 1): %s" % ( cursor.rowcount, sql )
  253. cursor.close()
  254. return True
  255.  
  256. def sessionEnd(self, serial):
  257. if self.verbose > 2: print "PokerService::sessionEnd(%d): " % ( serial )
  258. cursor = self.db.cursor()
  259. sql = "insert into session_history ( user_serial, started, ended, ip ) select user_serial, started, %d, ip from session where user_serial = %d" % ( time.time(), serial )
  260. cursor.execute(sql)
  261. if cursor.rowcount != 1: print " *ERROR* a) modified %d rows (expected 1): %s" % ( cursor.rowcount, sql )
  262. sql = "delete from session where user_serial = %d" % serial
  263. cursor.execute(sql)
  264. if cursor.rowcount != 1: print " *ERROR* b) modified %d rows (expected 1): %s" % ( cursor.rowcount, sql )
  265. cursor.close()
  266. return True
  267.  
  268. def auth(self, name, password, roles):
  269. for (serial, client) in self.serial2client.iteritems():
  270. if client.getName() == name and roles.intersection(client.roles):
  271. if self.verbose: print "PokerService::auth: %s attempt to login more than once with similar roles %s" % ( name, roles.intersection(client.roles) )
  272. return ( False, "Already logged in from somewhere else" )
  273. return self.poker_auth.auth(name, password)
  274.  
  275. def updateTourneysSchedule(self):
  276. if self.verbose > 3: print "updateTourneysSchedule"
  277. cursor = self.db.cursor(DictCursor)
  278.  
  279. sql = ( " SELECT * FROM tourneys_schedule WHERE " +
  280. " active = 'y' AND " +
  281. " ( respawn = 'y' OR " +
  282. " register_time < UNIX_TIMESTAMP(NOW()) )" )
  283. cursor.execute(sql)
  284. result = cursor.fetchall()
  285. self.tourneys_schedule = dict(zip(map(lambda schedule: schedule['serial'], result), result))
  286. cursor.close()
  287. self.checkTourneysSchedule()
  288. self.cancelTimer('updateTourney')
  289. self.timer['updateTourney'] = reactor.callLater(UPDATE_TOURNEYS_SCHEDULE_DELAY, self.updateTourneysSchedule)
  290.  
  291. def checkTourneysSchedule(self):
  292. if self.verbose > 3: print "checkTourneysSchedule"
  293. #
  294. # Respawning tournaments
  295. #
  296. for schedule in filter(lambda schedule: schedule['respawn'] == 'y', self.tourneys_schedule.values()):
  297. schedule_serial = schedule['serial']
  298. if ( not self.schedule2tourneys.has_key(schedule_serial) or
  299. not filter(lambda tourney: tourney.state == TOURNAMENT_STATE_REGISTERING, self.schedule2tourneys[schedule_serial]) ):
  300. self.spawnTourney(schedule)
  301. #
  302. # One time tournaments
  303. #
  304. now = time.time()
  305. one_time = []
  306. for serial in self.tourneys_schedule.keys():
  307. schedule = self.tourneys_schedule[serial]
  308. if ( schedule['respawn'] == 'n' and
  309. int(schedule['register_time']) < now ):
  310. one_time.append(schedule)
  311. del self.tourneys_schedule[serial]
  312. for schedule in one_time:
  313. self.spawnTourney(schedule)
  314.  
  315. #
  316. # Update tournaments with time clock
  317. #
  318. for tourney in filter(lambda tourney: tourney.sit_n_go == 'n', self.tourneys.values()):
  319. tourney.updateRunning()
  320. #
  321. # Forget about old tournaments
  322. #
  323. for tourney in filter(lambda tourney: tourney.state in ( TOURNAMENT_STATE_COMPLETE, TOURNAMENT_STATE_CANCELED), self.tourneys.values()):
  324. if now - tourney.finish_time > DELETE_OLD_TOURNEYS_DELAY:
  325. self.deleteTourney(tourney)
  326.  
  327. self.cancelTimer('checkTourney')
  328. self.timer['checkTourney'] = reactor.callLater(CHECK_TOURNEYS_SCHEDULE_DELAY, self.checkTourneysSchedule)
  329.  
  330. def spawnTourney(self, schedule):
  331. cursor = self.db.cursor()
  332. cursor.execute("INSERT INTO tourneys "
  333. " (schedule_serial, name, description_short, description_long, players_quota, players_min, variant, betting_structure, seats_per_game, player_timeout, currency_serial, prize_min, bailor_serial, buy_in, rake, sit_n_go, breaks_interval, rebuy_delay, add_on, add_on_delay, start_time)"
  334. " VALUES "
  335. " (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s )",
  336. ( schedule['serial'],
  337. schedule['name'],
  338. schedule['description_short'],
  339. schedule['description_long'],
  340. schedule['players_quota'],
  341. schedule['players_min'],
  342. schedule['variant'],
  343. schedule['betting_structure'],
  344. schedule['seats_per_game'],
  345. schedule['player_timeout'],
  346. schedule['currency_serial'],
  347. schedule['prize_min'],
  348. schedule['bailor_serial'],
  349. schedule['buy_in'],
  350. schedule['rake'],
  351. schedule['sit_n_go'],
  352. schedule['breaks_interval'],
  353. schedule['rebuy_delay'],
  354. schedule['add_on'],
  355. schedule['add_on_delay'],
  356. schedule['start_time'] ) )
  357. if self.verbose > 2: print "spawnTourney: " + str(schedule)
  358. #
  359. # Accomodate with MySQLdb versions < 1.1
  360. #
  361. if hasattr(cursor, "lastrowid"):
  362. tourney_serial = cursor.lastrowid
  363. else:
  364. tourney_serial = cursor.insert_id()
  365. if schedule['respawn'] == 'n':
  366. cursor.execute("UPDATE tourneys_schedule SET active = 'n' WHERE serial = %s" % schedule['serial'])
  367. cursor.close()
  368. self.spawnTourneyInCore(schedule, tourney_serial, schedule['serial'])
  369.  
  370. def spawnTourneyInCore(self, tourney_map, tourney_serial, schedule_serial):
  371. tourney_map['start_time'] = int(tourney_map['start_time'])
  372. tourney_map['register_time'] = int(tourney_map.get('register_time', 0))
  373. tourney = PokerTournament(dirs = self.dirs, **tourney_map)
  374. tourney.serial = tourney_serial
  375. tourney.verbose = self.verbose
  376. tourney.schedule_serial = schedule_serial
  377. tourney.currency_serial = tourney_map['currency_serial']
  378. tourney.bailor_serial = tourney_map['bailor_serial']
  379. tourney.player_timeout = int(tourney_map['player_timeout'])
  380. tourney.callback_new_state = self.tourneyNewState
  381. tourney.callback_create_game = self.tourneyCreateTable
  382. tourney.callback_game_filled = self.tourneyGameFilled
  383. tourney.callback_destroy_game = self.tourneyDestroyGame
  384. tourney.callback_move_player = self.tourneyMovePlayer
  385. tourney.callback_remove_player = self.tourneyRemovePlayer
  386. tourney.callback_cancel = self.tourneyCancel
  387. if not self.schedule2tourneys.has_key(schedule_serial):
  388. self.schedule2tourneys[schedule_serial] = []
  389. self.schedule2tourneys[schedule_serial].append(tourney)
  390. self.tourneys[tourney.serial] = tourney
  391. return tourney
  392.  
  393. def deleteTourney(self, tourney):
  394. if self.verbose > 2: print "deleteTourney: %d" % tourney.serial
  395. self.schedule2tourneys[tourney.schedule_serial].remove(tourney)
  396. if len(self.schedule2tourneys[tourney.schedule_serial]) <= 0:
  397. del self.schedule2tourneys[tourney.schedule_serial]
  398. del self.tourneys[tourney.serial]
  399.  
  400. def tourneyNewState(self, tourney):
  401. cursor = self.db.cursor()
  402. updates = [ "state = '" + tourney.state + "'" ]
  403. if tourney.state == TOURNAMENT_STATE_RUNNING:
  404. updates.append("start_time = %d" % tourney.start_time)
  405. sql = "update tourneys set " + ", ".join(updates) + " where serial = " + str(tourney.serial)
  406. if self.verbose > 4: print "tourneyNewState: " + sql
  407. cursor.execute(sql)
  408. if cursor.rowcount != 1: print " *ERROR* modified %d rows (expected 1): %s " % ( cursor.rowcount, sql )
  409. cursor.close()
  410.  
  411. def tourneyEndTurn(self, tourney, game_id):
  412. if not tourney.endTurn(game_id):
  413. self.tourneyFinished(tourney)
  414.  
  415. def tourneyFinished(self, tourney):
  416. prizes = tourney.prizes()
  417. winners = tourney.winners[:len(prizes)]
  418. cursor = self.db.cursor()
  419. #
  420. # Guaranteed prize pool is withdrawn from a given account if and only if
  421. # the buy in of the players is not enough.
  422. #
  423. bail = tourney.prize_min - ( tourney.buy_in * tourney.registered )
  424. if bail > 0:
  425. sql = ( "UPDATE user2money SET amount = amount - " + str(bail) + " WHERE " +
  426. " user_serial = " + str(tourney.bailor_serial) + " AND " +
  427. " currency_serial = " + str(tourney.currency_serial) + " AND " +
  428. " amount >= " + str(bail) )
  429. if self.verbose > 2: print "tourneyFinished: bailor pays " + sql
  430. cursor.execute(sql)
  431. if cursor.rowcount != 1:
  432. print " *ERROR* tourneyFinished: bailor failed to provide requested money modified %d rows (expected 1): %s " % ( cursor.rowcount, sql )
  433. cursor.close()
  434. return
  435.  
  436. while prizes:
  437. prize = prizes.pop(0)
  438. serial = winners.pop(0)
  439. if prize <= 0:
  440. continue
  441. sql = "UPDATE user2money SET amount = amount + " + str(prize) + " WHERE user_serial = " + str(serial) + " AND currency_serial = " + str(tourney.currency_serial)
  442. if self.verbose > 2: print "tourneyFinished: " + sql
  443. cursor.execute(sql)
  444. if cursor.rowcount == 0:
  445. sql = ( "INSERT INTO user2money (user_serial, currency_serial, amount) VALUES (%d, %d, %d)" %
  446. ( serial, tourney.currency_serial, prize ) )
  447. if self.verbose > 2: print "tourneyFinished: " + sql
  448. cursor.execute(sql)
  449.  
  450. if cursor.rowcount != 1:
  451. print " *ERROR* tourneyFinished: affected %d rows (expected 1): %s " % ( cursor.rowcount, sql )
  452.  
  453. cursor.close()
  454.  
  455. def tourneyGameFilled(self, tourney, game):
  456. table = self.getTable(game.id)
  457. cursor = self.db.cursor()
  458. for player in game.playersAll():
  459. serial = player.serial
  460. player.setUserData(pokeravatar.DEFAULT_PLAYER_USER_DATA.copy())
  461. client = self.serial2client.get(serial, None)
  462. if client:
  463. if self.verbose > 2: print "tourneyGameFilled: player %d connected" % serial
  464. table.serial2client[serial] = client
  465. else:
  466. if self.verbose > 2: print "tourneyGameFilled: player %d disconnected" % serial
  467. self.seatPlayer(serial, game.id, game.buyIn())
  468.  
  469. if client:
  470. client.join(table)
  471. sql = "update user2tourney set table_serial = %d where user_serial = %d and tourney_serial = %d" % ( game.id, serial, tourney.serial )
  472. if self.verbose > 4: print "tourneyGameFilled: " + sql
  473. cursor.execute(sql)
  474. if cursor.rowcount != 1: print " *ERROR* modified %d rows (expected 1): %s " % ( cursor.rowcount, sql )
  475. cursor.close()
  476. table.update()
  477.  
  478. def tourneyCreateTable(self, tourney):
  479. table = self.createTable(0, { 'name': tourney.name + str(self.table_serial),
  480. 'variant': tourney.variant,
  481. 'betting_structure': tourney.betting_structure,
  482. 'seats': tourney.seats_per_game,
  483. 'currency_serial': 0,
  484. 'player_timeout': tourney.player_timeout,
  485. 'transient': True,
  486. 'tourney': tourney,
  487. })
  488. table.timeout_policy = "fold"
  489. self.table_serial += 1
  490. return table.game
  491.  
  492. def tourneyDestroyGame(self, tourney, game):
  493. table = self.getTable(game.id)
  494. table.destroy()
  495.  
  496. def tourneyMovePlayer(self, tourney, from_game_id, to_game_id, serial):
  497. from_table = self.getTable(from_game_id)
  498. from_table.movePlayer(from_table.serial2client.get(serial, None), serial, to_game_id)
  499. cursor = self.db.cursor()
  500. sql = "update user2tourney set table_serial = %d where user_serial = %d and tourney_serial = %d" % ( to_game_id, serial, tourney.serial )
  501. if self.verbose > 4: print "tourneyMovePlayer: " + sql
  502. cursor.execute(sql)
  503. if cursor.rowcount != 1: print " *ERROR* modified %d rows (expected 1): %s " % ( cursor.rowcount, sql )
  504. cursor.close()
  505.  
  506. def tourneyRemovePlayer(self, tourney, game_id, serial):
  507. #
  508. # Inform the player about its position and prize
  509. #
  510. prizes = tourney.prizes()
  511. rank = tourney.getRank(serial)
  512. money = 0
  513. players = len(tourney.players)
  514. if rank-1 < len(prizes):
  515. money = prizes[rank-1]
  516.  
  517. client = self.serial2client.get(serial, None)
  518. if client:
  519. packet = PacketPokerTourneyRank(serial = tourney.serial,
  520. game_id = game_id,
  521. players = players,
  522. rank = rank,
  523. money = money)
  524. client.sendPacketVerbose(packet)
  525. table = self.getTable(game_id)
  526. table.kickPlayer(serial)
  527. cursor = self.db.cursor()
  528. sql = "update user2tourney set rank = %d, table_serial = -1 where user_serial = %d and tourney_serial = %d" % ( tourney.getRank(serial), serial, tourney.serial )
  529. if self.verbose > 4: print "tourneyRemovePlayer: " + sql
  530. cursor.execute(sql)
  531. if cursor.rowcount != 1: print " *ERROR* modified %d rows (expected 1): %s " % ( cursor.rowcount, sql )
  532. cursor.close()
  533.  
  534. def tourneyPlayersList(self, tourney_serial):
  535. if not self.tourneys.has_key(tourney_serial):
  536. return PacketError(other_type = PACKET_POKER_TOURNEY_REGISTER,
  537. code = PacketPokerTourneyRegister.DOES_NOT_EXIST,
  538. message = "Tournament %d does not exist" % tourney_serial)
  539. tourney = self.tourneys[tourney_serial]
  540. players = map(lambda serial: ( self.getName(serial), -1, 0 ), tourney.players)
  541. return PacketPokerTourneyPlayersList(serial = tourney_serial,
  542. players = players)
  543.  
  544. def tourneyStats(self):
  545. players = reduce(operator.add, map(lambda tourney: tourney.registered, self.tourneys.values()))
  546. scheduled = filter(lambda schedule: schedule['respawn'] == 'n', self.tourneys_schedule.values())
  547. return ( players, len(self.tourneys) + len(scheduled) )
  548.  
  549. def tourneySelect(self, string):
  550. tourneys = filter(lambda schedule: schedule['respawn'] == 'n', self.tourneys_schedule.values()) + map(lambda tourney: tourney.__dict__, self.tourneys.values() )
  551. criterion = split(string, "\t")
  552. if string == '':
  553. return tourneys
  554. elif len(criterion) > 1:
  555. ( currency_serial, type ) = criterion
  556. sit_n_go = type == 'sit_n_go' and 'y' or 'n'
  557. if currency_serial:
  558. currency_serial = int(currency_serial)
  559. return filter(lambda tourney: tourney['currency_serial'] == currency_serial and tourney['sit_n_go'] == sit_n_go, tourneys)
  560. else:
  561. return filter(lambda tourney: tourney['sit_n_go'] == sit_n_go, tourneys)
  562. else:
  563. return filter(lambda tourney: tourney['name'] == string, tourneys)
  564.  
  565. def tourneyRegister(self, packet):
  566. serial = packet.serial
  567. tourney_serial = packet.game_id
  568. client = self.serial2client.get(serial, None)
  569.  
  570. if not self.tourneys.has_key(tourney_serial):
  571. error = PacketError(other_type = PACKET_POKER_TOURNEY_REGISTER,
  572. code = PacketPokerTourneyRegister.DOES_NOT_EXIST,
  573. message = "Tournament %d does not exist" % tourney_serial)
  574. print error
  575. if client: client.sendPacketVerbose(error)
  576. return False
  577. tourney = self.tourneys[tourney_serial]
  578.  
  579. if tourney.isRegistered(serial):
  580. error = PacketError(other_type = PACKET_POKER_TOURNEY_REGISTER,
  581. code = PacketPokerTourneyRegister.ALREADY_REGISTERED,
  582. message = "Player %d already registered in tournament %d " % ( serial, tourney_serial ) )
  583. print error
  584. if client: client.sendPacketVerbose(error)
  585. return False
  586.  
  587. if not tourney.canRegister(serial):
  588. error = PacketError(other_type = PACKET_POKER_TOURNEY_REGISTER,
  589. code = PacketPokerTourneyRegister.REGISTRATION_REFUSED,
  590. message = "Registration refused in tournament %d " % tourney_serial)
  591. print error
  592. if client: client.sendPacketVerbose(error)
  593. return False
  594.  
  595. cursor = self.db.cursor()
  596. #
  597. # Buy in
  598. #
  599. currency_serial = tourney.currency_serial
  600. withdraw = tourney.buy_in + tourney.rake
  601. if withdraw > 0:
  602. sql = ( "UPDATE user2money SET amount = amount - " + str(withdraw) +
  603. " WHERE user_serial = " + str(serial) + " AND " +
  604. " currency_serial = " + str(currency_serial) + " AND " +
  605. " amount >= " + str(withdraw)
  606. )
  607. if self.verbose > 1:
  608. print "tourneyRegister: %s" % sql
  609. cursor.execute(sql)
  610. if cursor.rowcount == 0:
  611. error = PacketError(other_type = PACKET_POKER_TOURNEY_REGISTER,
  612. code = PacketPokerTourneyRegister.NOT_ENOUGH_MONEY,
  613. message = "Not enough money to enter the tournament %d" % tourney_serial)
  614. if client: client.sendPacketVerbose(error)
  615. print error
  616. return False
  617. if cursor.rowcount != 1:
  618. print " *ERROR* modified %d rows (expected 1): %s " % ( cursor.rowcount, sql )
  619. if client:
  620. client.sendPacketVerbose(PacketError(other_type = PACKET_POKER_TOURNEY_REGISTER,
  621. code = PacketPokerTourneyRegister.SERVER_ERROR,
  622. message = "Server error"))
  623. return False
  624. #
  625. # Register
  626. #
  627. sql = "INSERT INTO user2tourney (user_serial, tourney_serial) VALUES (%d, %d)" % ( serial, tourney_serial )
  628. if self.verbose > 4: print "tourneyRegister: " + sql
  629. cursor.execute(sql)
  630. if cursor.rowcount != 1:
  631. print " *ERROR* insert %d rows (expected 1): %s " % ( cursor.rowcount, sql )
  632. cursor.close()
  633. if client:
  634. client.sendPacketVerbose(PacketError(other_type = PACKET_POKER_TOURNEY_REGISTER,
  635. code = PacketPokerTourneyRegister.SERVER_ERROR,
  636. message = "Server error"))
  637. return False
  638. cursor.close()
  639.  
  640. # notify success
  641. if client: client.sendPacketVerbose(packet)
  642. tourney.register(serial)
  643. return True
  644.  
  645. def tourneyUnregister(self, packet):
  646. serial = packet.serial
  647. tourney_serial = packet.game_id
  648. if not self.tourneys.has_key(tourney_serial):
  649. return PacketError(other_type = PACKET_POKER_TOURNEY_UNREGISTER,
  650. code = PacketPokerTourneyUnregister.DOES_NOT_EXIST,
  651. message = "Tournament %d does not exist" % tourney_serial)
  652. tourney = self.tourneys[tourney_serial]
  653.  
  654. if not tourney.isRegistered(serial):
  655. return PacketError(other_type = PACKET_POKER_TOURNEY_UNREGISTER,
  656. code = PacketPokerTourneyUnregister.NOT_REGISTERED,
  657. message = "Player %d is not registered in tournament %d " % ( serial, tourney_serial ) )
  658.  
  659. if not tourney.canUnregister(serial):
  660. return PacketError(other_type = PACKET_POKER_TOURNEY_UNREGISTER,
  661. code = PacketPokerTourneyUnregister.TOO_LATE,
  662. message = "It is too late to unregister player %d from tournament %d " % ( serial, tourney_serial ) )
  663.  
  664. cursor = self.db.cursor()
  665. #
  666. # Refund buy in
  667. #
  668. currency_serial = tourney.currency_serial
  669. withdraw = tourney.buy_in + tourney.rake
  670. if withdraw > 0:
  671. sql = ( "UPDATE user2money SET amount = amount + " + str(withdraw) +
  672. " WHERE user_serial = " + str(serial) + " AND " +
  673. " currency_serial = " + str(currency_serial) )
  674. if self.verbose > 1:
  675. print "tourneyUnregister: %s" % sql
  676. cursor.execute(sql)
  677. if cursor.rowcount != 1:
  678. print " *ERROR* modified %d rows (expected 1): %s " % ( cursor.rowcount, sql )
  679. return PacketError(other_type = PACKET_POKER_TOURNEY_UNREGISTER,
  680. code = PacketPokerTourneyUnregister.SERVER_ERROR,
  681. message = "Server error")
  682. #
  683. # Unregister
  684. #
  685. sql = "delete from user2tourney where user_serial = %d and tourney_serial = %d" % ( serial, tourney_serial )
  686. if self.verbose > 4: print "tourneyUnregister: " + sql
  687. cursor.execute(sql)
  688. if cursor.rowcount != 1:
  689. print " *ERROR* insert %d rows (expected 1): %s " % ( cursor.rowcount, sql )
  690. cursor.close()
  691. return PacketError(other_type = PACKET_POKER_TOURNEY_UNREGISTER,
  692. code = PacketPokerTourneyUnregister.SERVER_ERROR,
  693. message = "Server error")
  694. cursor.close()
  695.  
  696. tourney.unregister(serial)
  697.  
  698. return packet
  699.  
  700. def tourneyCancel(self, tourney):
  701. if self.verbose > 1: print "tourneyCancel " + str(tourney.players)
  702. for serial in tourney.players:
  703. packet = self.tourneyUnregister(PacketPokerTourneyUnregister(game_id = tourney.serial,
  704. serial = serial))
  705. if packet.type == PACKET_ERROR:
  706. print "*ERROR* tourneyCancel: " + str(packet)
  707.  
  708. def getHandSerial(self):
  709. cursor = self.db.cursor()
  710. cursor.execute("insert into hands (description) values ('[]')")
  711. #
  712. # Accomodate with MySQLdb versions < 1.1
  713. #
  714. if hasattr(cursor, "lastrowid"):
  715. serial = cursor.lastrowid
  716. else:
  717. serial = cursor.insert_id()
  718. cursor.close()
  719. return int(serial)
  720.  
  721. def getHandHistory(self, hand_serial, serial):
  722. history = self.loadHand(hand_serial)
  723.  
  724. if not history:
  725. return PacketPokerError(game_id = hand_serial,
  726. serial = serial,
  727. other_type = PACKET_POKER_HAND_HISTORY,
  728. code = PacketPokerHandHistory.NOT_FOUND,
  729. message = "Hand %d was not found in history of player %d" % ( hand_serial, serial ) )
  730.  
  731. (type, level, hand_serial, hands_count, time, variant, betting_structure, player_list, dealer, serial2chips) = history[0]
  732.  
  733. if serial not in player_list:
  734. return PacketPokerError(game_id = hand_serial,
  735. serial = serial,
  736. other_type = PACKET_POKER_HAND_HISTORY,
  737. code = PacketPokerHandHistory.FORBIDDEN,
  738. message = "Player %d did not participate in hand %d" % ( serial, hand_serial ) )
  739.  
  740. serial2name = {}
  741. for player_serial in player_list:
  742. serial2name[player_serial] = self.getName(player_serial)
  743. #
  744. # Filter out the pocket cards that do not belong to player "serial"
  745. #
  746. for event in history:
  747. if event[0] == "round":
  748. (type, name, board, pockets) = event
  749. if pockets:
  750. for (player_serial, pocket) in pockets.iteritems():
  751. if player_serial != serial:
  752. pocket.loseNotVisible()
  753. elif event[0] == "showdown":
  754. (type, board, pockets) = event
  755. if pockets:
  756. for (player_serial, pocket) in pockets.iteritems():
  757. if player_serial != serial:
  758. pocket.loseNotVisible()
  759.  
  760. return PacketPokerHandHistory(game_id = hand_serial,
  761. serial = serial,
  762. history = str(history),
  763. serial2name = str(serial2name))
  764.  
  765. def loadHand(self, hand_serial):
  766. cursor = self.db.cursor()
  767. sql = ( "select description from hands where serial = " + str(hand_serial) )
  768. cursor.execute(sql)
  769. if cursor.rowcount != 1:
  770. print " *ERROR* loadHand(%d) expected one row got %d" % ( hand_serial, cursor.rowcount )
  771. cursor.close()
  772. return None
  773. (description,) = cursor.fetchone()
  774. cursor.close()
  775. try:
  776. history = eval(description.replace("\r",""))
  777. return history
  778. except:
  779. print " *ERROR* loadHand(%d) eval failed for %s" % ( hand_serial, description )
  780. print_exc()
  781. return None
  782.  
  783. def saveHand(self, description, hand_serial):
  784. (type, level, hand_serial, hands_count, time, variant, betting_structure, player_list, dealer, serial2chips) = description[0]
  785. cursor = self.db.cursor()
  786.  
  787. sql = ( "update hands set " +
  788. " description = %s "
  789. " where serial = " + str(hand_serial) )
  790. if self.verbose > 1:
  791. print "saveHand: %s" % ( sql % description )
  792. cursor.execute(sql, str(description))
  793. if cursor.rowcount != 1 and cursor.rowcount != 0:
  794. print " *ERROR* modified %d rows (expected 1 or 0): %s " % ( cursor.rowcount, sql )
  795. cursor.close()
  796. return
  797.  
  798. sql = "insert into user2hand values "
  799. sql += ", ".join(map(lambda player_serial: "(%d, %d)" % ( player_serial, hand_serial ), player_list))
  800. if self.verbose > 1:
  801. print "saveHand: %s" % sql
  802. cursor.execute(sql)
  803. if cursor.rowcount != len(player_list):
  804. print " *ERROR* inserted %d rows (expected exactly %d): %s " % ( cursor.rowcount, len(player_list), sql )
  805.  
  806.  
  807. cursor.close()
  808.  
  809. def listHands(self, sql_list, sql_total):
  810. cursor = self.db.cursor()
  811. if self.verbose > 1:
  812. print "listHands: " + sql_list + " " + sql_total
  813. cursor.execute(sql_list)
  814. hands = cursor.fetchall()
  815. cursor.execute(sql_total)
  816. total = cursor.fetchone()[0]
  817. cursor.close()
  818. return (total, map(lambda x: x[0], hands))
  819.  
  820. def statsTables(self):
  821. players = reduce(operator.add, map(lambda table: table.game.allCount(), self.tables))
  822. return ( players, len(self.tables) )
  823.  
  824. def listTables(self, string, serial):
  825. criterion = split(string, "\t")
  826. if string == '' or string == 'all':
  827. return self.tables
  828. elif string == 'my':
  829. return filter(lambda table: serial in table.game.serialsAll(), self.tables)
  830. elif re.match("^[0-9]+$", string):
  831. return filter(lambda table: table.currency_serial == int(string), self.tables)
  832. elif len(criterion) > 1:
  833. ( currency_serial, variant ) = criterion
  834. if currency_serial:
  835. currency_serial = int(currency_serial)
  836. return filter(lambda table: table.game.variant == variant and table.currency_serial == currency_serial, self.tables)
  837. else:
  838. return filter(lambda table: table.game.variant == variant, self.tables)
  839. else:
  840. return filter(lambda table: table.game.name == string, self.tables)
  841.  
  842. def cleanUp(self, temporary_users = ''):
  843. cursor = self.db.cursor()
  844.  
  845. if len(temporary_users) > 2:
  846. sql = "delete session_history from session_history, users where session_history.user_serial = users.serial and users.name like '" + temporary_users + "%'"
  847. cursor.execute(sql)
  848. sql = "delete session from session, users where session.user_serial = users.serial and users.name like '" + temporary_users + "%'"
  849. cursor.execute(sql)
  850. sql = "delete from users where name like '" + temporary_users + "%'"
  851. cursor.execute(sql)
  852.  
  853. sql = "insert into session_history ( user_serial, started, ended, ip ) select user_serial, started, %d, ip from session" % time.time()
  854. cursor.execute(sql)
  855. sql = "delete from session"
  856. cursor.execute(sql)
  857.  
  858. cursor.close()
  859.  
  860. def cleanupTourneys(self):
  861. self.tourneys = {}
  862. self.schedule2tourneys = {}
  863. self.tourneys_schedule = {}
  864.  
  865. cursor = self.db.cursor(DictCursor)
  866. sql = "SELECT * FROM tourneys WHERE state = 'registering' AND start_time > (%d + 60)" % time.time()
  867. if self.verbose > 2: print "cleanupTourneys: " + sql
  868. cursor.execute(sql)
  869. for x in xrange(cursor.rowcount):
  870. row = cursor.fetchone()
  871. if self.verbose >= 0: message = "cleanupTourneys: restoring %s(%s) with players" % ( row['name'], row['serial'], )
  872. tourney = self.spawnTourneyInCore(row, row['serial'], row['schedule_serial'])
  873. cursor1 = self.db.cursor()
  874. sql = "SELECT user_serial FROM user2tourney WHERE tourney_serial = " + str(row['serial'])
  875. if self.verbose > 2: print "cleanupTourneys: " + sql
  876. cursor1.execute(sql)
  877. for y in xrange(cursor1.rowcount):
  878. (serial,) = cursor1.fetchone()
  879. if self.verbose >= 0: message += " " + str(serial)
  880. tourney.register(serial)
  881.  
  882. cursor1.execute(sql)
  883. cursor1.close()
  884. if self.verbose >= 0: print message
  885. cursor.close()
  886.  
  887. def getMoney(self, serial, currency_serial):
  888. cursor = self.db.cursor()
  889. sql = ( "SELECT amount FROM user2money " +
  890. " WHERE user_serial = " + str(serial) + " AND " +
  891. " currency_serial = " + str(currency_serial) )
  892. if self.verbose: print sql
  893. cursor.execute(sql)
  894. if cursor.rowcount > 1:
  895. print " *ERROR* getMoney(%d) expected one row got %d" % ( serial, cursor.rowcount )
  896. cursor.close()
  897. return 0
  898. elif cursor.rowcount == 1:
  899. (money,) = cursor.fetchone()
  900. else:
  901. money = 0
  902. cursor.close()
  903. return money
  904.  
  905. def cashIn(self, packet):
  906. return self.cashier.cashIn(packet)
  907.  
  908. def cashOut(self, packet):
  909. return self.cashier.cashOut(packet)
  910.  
  911. def cashQuery(self, packet):
  912. return self.cashier.cashQuery(packet)
  913.  
  914. def cashOutCommit(self, packet):
  915. count = self.cashier.cashOutCommit(packet)
  916. if count in (0, 1):
  917. return PacketAck()
  918. else:
  919. return PacketError(code = PacketPokerCashOutCommit.INVALID_TRANSACTION,
  920. message = "transaction " + packet.transaction_id + " affected " + str(count) + " rows instead of zero or one",
  921. other_type = PACKET_POKER_CASH_OUT_COMMIT)
  922.  
  923. def getPlayerInfo(self, serial):
  924. placeholder = PacketPokerPlayerInfo(serial = serial,
  925. name = "anonymous",
  926. url= "random",
  927. outfit = "random")
  928. if serial == 0:
  929. return placeholder
  930.  
  931. cursor = self.db.cursor()
  932. sql = ( "select name,skin_url,skin_outfit from users where serial = " + str(serial) )
  933. cursor.execute(sql)
  934. if cursor.rowcount != 1:
  935. print " *ERROR* getPlayerInfo(%d) expected one row got %d" % ( serial, cursor.rowcount )
  936. return placeholder
  937. (name,skin_url,skin_outfit) = cursor.fetchone()
  938. if skin_outfit == None:
  939. skin_outfit = "random"
  940. cursor.close()
  941. return PacketPokerPlayerInfo(serial = serial,
  942. name = name,
  943. url = skin_url,
  944. outfit = skin_outfit)
  945.  
  946. def getUserInfo(self, serial):
  947. cursor = self.db.cursor(DictCursor)
  948.  
  949. sql = ( "SELECT rating,affiliate,email,name FROM users WHERE serial = " + str(serial) )
  950. cursor.execute(sql)
  951. if cursor.rowcount != 1:
  952. print " *ERROR* getUserInfo(%d) expected one row got %d" % ( serial, cursor.rowcount )
  953. return PacketPokerUserInfo(serial = serial)
  954. row = cursor.fetchone()
  955. if row['email'] == None: row['email'] = ""
  956.  
  957. packet = PacketPokerUserInfo(serial = serial,
  958. name = row['name'],
  959. email = row['email'],
  960. rating = row['rating'],
  961. affiliate = row['affiliate'])
  962. sql = ( " SELECT user2money.currency_serial,user2money.amount,user2money.points,CAST(SUM(user2table.bet) + SUM(user2table.money) AS UNSIGNED) AS in_game "
  963. " FROM user2money LEFT JOIN (pokertables,user2table) "
  964. " ON (user2table.user_serial = user2money.user_serial AND "
  965. " user2table.table_serial = pokertables.serial AND "
  966. " user2money.currency_serial = pokertables.currency_serial) "
  967. " WHERE user2money.user_serial = " + str(serial) + " GROUP BY user2money.currency_serial " )
  968. if self.verbose: print sql
  969. cursor.execute(sql)
  970. for row in cursor:
  971. if not row['in_game']: row['in_game'] = 0
  972. if not row['points']: row['points'] = 0
  973. packet.money[row['currency_serial']] = ( row['amount'], row['in_game'], row['points'] )
  974. if self.verbose > 2: print "getUserInfo: " + str(packet)
  975. return packet
  976.  
  977. def getPersonalInfo(self, serial):
  978. user_info = self.getUserInfo(serial)
  979. print "getPersonalInfo %s" % str(user_info)
  980. packet = PacketPokerPersonalInfo(serial = user_info.serial,
  981. name = user_info.name,
  982. email = user_info.email,
  983. rating = user_info.rating,
  984. affiliate = user_info.affiliate,
  985. money = user_info.money)
  986. cursor = self.db.cursor()
  987. sql = ( "SELECT firstname,lastname,addr_street,addr_street2,addr_zip,addr_town,addr_state,addr_country,phone,gender,birthdate FROM users_private WHERE serial = " + str(serial) )
  988. cursor.execute(sql)
  989. if cursor.rowcount != 1:
  990. print " *ERROR* getPersonalInfo(%d) expected one row got %d" % ( serial, cursor.rowcount )
  991. return PacketPokerPersonalInfo(serial = serial)
  992. (packet.firstname, packet.lastname, packet.addr_street, packet.addr_street2, packet.addr_zip, packet.addr_town, packet.addr_state, packet.addr_country, packet.phone, packet.gender, packet.birthdate) = cursor.fetchone()
  993. cursor.close()
  994. if not packet.gender: packet.gender = ''
  995. if not packet.birthdate: packet.birthdate = ''
  996. return packet
  997.  
  998. def setPersonalInfo(self, personal_info):
  999. cursor = self.db.cursor()
  1000. sql = ( "UPDATE users_private SET "
  1001. " firstname = '" + personal_info.firstname + "', "
  1002. " lastname = '" + personal_info.lastname + "', "
  1003. " addr_street = '" + personal_info.addr_street + "', "
  1004. " addr_street2 = '" + personal_info.addr_street2 + "', "
  1005. " addr_zip = '" + personal_info.addr_zip + "', "
  1006. " addr_town = '" + personal_info.addr_town + "', "
  1007. " addr_state = '" + personal_info.addr_state + "', "
  1008. " addr_country = '" + personal_info.addr_country + "', "
  1009. " phone = '" + personal_info.phone + "', "
  1010. " gender = '" + personal_info.gender + "', "
  1011. " birthdate = '" + personal_info.birthdate + "' "
  1012. " WHERE serial = " + str(personal_info.serial) )
  1013. if self.verbose > 1:
  1014. print "setPersonalInfo: %s" % sql
  1015. cursor.execute(sql)
  1016. if cursor.rowcount != 1 and cursor.rowcount != 0:
  1017. print " *ERROR* setPersonalInfo: modified %d rows (expected 1 or 0): %s " % ( cursor.rowcount, sql )
  1018. return False
  1019. else:
  1020. return True
  1021.  
  1022. def setAccount(self, packet):
  1023. #
  1024. # name constraints check
  1025. #
  1026. status = checkName(packet.name)
  1027. if not status[0]:
  1028. return PacketError(code = status[1],
  1029. message = status[2],
  1030. other_type = packet.type)
  1031. #
  1032. # Look for user
  1033. #
  1034. cursor = self.db.cursor()
  1035. cursor.execute("select serial from users where name = '%s'" % packet.name)
  1036. numrows = int(cursor.rowcount)
  1037. #
  1038. # password constraints check
  1039. #
  1040. if ( numrows == 0 or ( numrows > 0 and packet.password != "" )):
  1041. status = checkPassword(packet.password)
  1042. if not status[0]:
  1043. return PacketError(code = status[1],
  1044. message = status[2],
  1045. other_type = packet.type)
  1046. #
  1047. # email constraints check
  1048. #
  1049. email_regexp = ".*.@.*\..*$"
  1050. if not re.match(email_regexp, packet.email):
  1051. return PacketError(code = PacketPokerSetAccount.INVALID_EMAIL,
  1052. message = "email %s does not match %s " % ( packet.email, email_regexp ),
  1053. other_type = packet.type)
  1054. if numrows == 0:
  1055. cursor.execute("select serial from users where email = '%s' " % packet.email)
  1056. numrows = int(cursor.rowcount)
  1057. if numrows > 0:
  1058. return PacketError(code = PacketPokerSetAccount.EMAIL_ALREADY_EXISTS,
  1059. message = "there already is another account with the email %s" % packet.email,
  1060. other_type = packet.type)
  1061. #
  1062. # User does not exists, create it
  1063. #
  1064. sql = "INSERT INTO users (created, name, password, email, affiliate) values (%d, '%s', '%s', '%s', '%d')" % (time.time(), packet.name, packet.password, packet.email, packet.affiliate)
  1065. cursor.execute(sql)
  1066. if cursor.rowcount != 1:
  1067. print " *ERROR* setAccount: insert %d rows (expected 1): %s " % ( cursor.rowcount, sql )
  1068. return PacketError(code = PacketPokerSetAccount.SERVER_ERROR,
  1069. message = "inserted %d rows (expected 1)" % cursor.rowcount,
  1070. other_type = packet.type)
  1071. #
  1072. # Accomodate for MySQLdb versions < 1.1
  1073. #
  1074. if hasattr(cursor, "lastrowid"):
  1075. packet.serial = cursor.lastrowid
  1076. else:
  1077. packet.serial = cursor.insert_id()
  1078. cursor.execute("insert into users_private (serial) values ('%d')" % packet.serial)
  1079. if int(cursor.rowcount) == 0:
  1080. print " *ERROR* setAccount: unable to create user_private entry for serial %d" % packet.serial
  1081. return PacketError(code = PacketPokerSetAccount.SERVER_ERROR,
  1082. message = "unable to create user_private entry for serial %d" % packet.serial,
  1083. other_type = packet.type)
  1084. else:
  1085. #
  1086. # User exists, update name, password and email
  1087. #
  1088. (serial,) = cursor.fetchone()
  1089. if serial != packet.serial:
  1090. return PacketError(code = PacketPokerSetAccount.NAME_ALREADY_EXISTS,
  1091. message = "user name %s already exists" % packet.name,
  1092. other_type = packet.type)
  1093. cursor.execute("select serial from users where email = '%s' and serial != %d" % ( packet.email, serial ))
  1094. numrows = int(cursor.rowcount)
  1095. if numrows > 0:
  1096. return PacketError(code = PacketPokerSetAccount.EMAIL_ALREADY_EXISTS,
  1097. message = "there already is another account with the email %s" % packet.email,
  1098. other_type = packet.type)
  1099. set_password = packet.password and ", password = '" + packet.password + "' " or ""
  1100. sql = ( "update users set "
  1101. " name = '" + packet.name + "', "
  1102. " email = '" + packet.email + "' " +
  1103. set_password +
  1104. " where serial = " + str(packet.serial) )
  1105. if self.verbose > 1:
  1106. print "setAccount: %s" % sql
  1107. cursor.execute(sql)
  1108. if cursor.rowcount != 1 and cursor.rowcount != 0:
  1109. print " *ERROR* setAccount: modified %d rows (expected 1 or 0): %s " % ( cursor.rowcount, sql )
  1110. return PacketError(code = PacketPokerSetAccount.SERVER_ERROR,
  1111. message = "modified %d rows (expected 1 or 0)" % cursor.rowcount,
  1112. other_type = packet.type)
  1113. #
  1114. # Set personal information
  1115. #
  1116. if not self.setPersonalInfo(packet):
  1117. return PacketError(code = PacketPokerSetAccount.SERVER_ERROR,
  1118. message = "unable to set personal information",
  1119. other_type = packet.type)
  1120. return self.getPersonalInfo(packet.serial)
  1121.  
  1122. def setPlayerInfo(self, player_info):
  1123. cursor = self.db.cursor()
  1124. sql = ( "update users set "
  1125. " name = '" + player_info.name + "', "
  1126. " skin_url = '" + player_info.url + "', "
  1127. " skin_outfit = '" + player_info.outfit + "' "
  1128. " where serial = " + str(player_info.serial) )
  1129. if self.verbose > 1:
  1130. print "setPlayerInfo: %s" % sql
  1131. cursor.execute(sql)
  1132. if cursor.rowcount != 1 and cursor.rowcount != 0:
  1133. print " *ERROR* setPlayerInfo: modified %d rows (expected 1 or 0): %s " % ( cursor.rowcount, sql )
  1134. return False
  1135. return True
  1136.  
  1137.  
  1138. def getPlayerImage(self, serial):
  1139. placeholder = PacketPokerPlayerImage(serial = serial)
  1140.  
  1141. if serial == 0:
  1142. return placeholder
  1143.  
  1144. cursor = self.db.cursor()
  1145. sql = ( "select skin_image,skin_image_type from users where serial = " + str(serial) )
  1146. cursor.execute(sql)
  1147. if cursor.rowcount != 1:
  1148. print " *ERROR* getPlayerImage(%d) expected one row got %d" % ( serial, cursor.rowcount )
  1149. return placeholder
  1150. (skin_image, skin_image_type) = cursor.fetchone()
  1151. if skin_image == None:
  1152. skin_image = ""
  1153. cursor.close()
  1154. return PacketPokerPlayerImage(serial = serial,
  1155. image = skin_image,
  1156. image_type = skin_image_type)
  1157.  
  1158. def setPlayerImage(self, player_image):
  1159. cursor = self.db.cursor()
  1160. sql = ( "update users set "
  1161. " skin_image = '" + player_image.image + "', "
  1162. " skin_image_type = '" + player_image.image_type + "' "
  1163. " where serial = " + str(player_image.serial) )
  1164. if self.verbose > 1:
  1165. print "setPlayerInfo: %s" % sql
  1166. cursor.execute(sql)
  1167. if cursor.rowcount != 1 and cursor.rowcount != 0:
  1168. print " *ERROR* setPlayerImage: modified %d rows (expected 1 or 0): %s " % ( cursor.rowcount, sql )
  1169. return False
  1170. return True
  1171.  
  1172. def getName(self, serial):
  1173. if serial == 0:
  1174. return "anonymous"
  1175.  
  1176. cursor = self.db.cursor()
  1177. sql = ( "select name from users where serial = " + str(serial) )
  1178. cursor.execute(sql)
  1179. if cursor.rowcount != 1:
  1180. print " *ERROR* getName(%d) expected one row got %d" % ( serial, cursor.rowcount )
  1181. return "UNKNOWN"
  1182. (name,) = cursor.fetchone()
  1183. cursor.close()
  1184. return name
  1185.  
  1186. def buyInPlayer(self, serial, table_id, currency_serial, amount):
  1187. # unaccounted money is delivered regardless
  1188. if not currency_serial: return amount
  1189.  
  1190. withdraw = min(self.getMoney(serial, currency_serial), amount)
  1191. cursor = self.db.cursor()
  1192. sql = ( "UPDATE user2money,user2table SET "
  1193. " user2table.money = user2table.money + " + str(withdraw) + ", "
  1194. " user2money.amount = user2money.amount - " + str(withdraw) + " "
  1195. " WHERE user2money.user_serial = " + str(serial) + " AND "
  1196. " user2money.currency_serial = " + str(currency_serial) + " AND "
  1197. " user2table.user_serial = " + str(serial) + " AND "
  1198. " user2table.table_serial = " + str(table_id) )
  1199. if self.verbose > 1:
  1200. print "buyInPlayer: %s" % sql
  1201. cursor.execute(sql)
  1202. if cursor.rowcount != 0 and cursor.rowcount != 2:
  1203. print " *ERROR* modified %d rows (expected 0 or 2): %s " % ( cursor.rowcount, sql )
  1204. return withdraw
  1205.  
  1206. def seatPlayer(self, serial, table_id, amount):
  1207. status = True
  1208. cursor = self.db.cursor()
  1209. sql = ( "INSERT user2table ( user_serial, table_serial, money) VALUES "
  1210. " ( " + str(serial) + ", " + str(table_id) + ", " + str(amount) + " )" )
  1211. if self.verbose > 1:
  1212. print "seatPlayer: %s" % sql
  1213. cursor.execute(sql)
  1214. if cursor.rowcount != 1:
  1215. print " *ERROR* inserted %d rows (expected 1): %s " % ( cursor.rowcount, sql )
  1216. status = False
  1217. cursor.close()
  1218. return status
  1219.  
  1220. def movePlayer(self, serial, from_table_id, to_table_id):
  1221. money = -1
  1222. cursor = self.db.cursor()
  1223. sql = ( "SELECT money FROM user2table "
  1224. " WHERE user_serial = " + str(serial) + " AND "
  1225. " table_serial = " + str(from_table_id) )
  1226. cursor.execute(sql)
  1227. if cursor.rowcount != 1:
  1228. print " *ERROR* movePlayer(%d) expected one row got %d" % ( serial, cursor.rowcount )
  1229. (money,) = cursor.fetchone()
  1230. cursor.close()
  1231.  
  1232. if money > 0:
  1233. cursor = self.db.cursor()
  1234. sql = ( "update user2table "
  1235. " set table_serial = " + str(to_table_id) +
  1236. " where user_serial = " + str(serial) + " and"
  1237. " table_serial = " + str(from_table_id) )
  1238. if self.verbose > 1:
  1239. print "movePlayer: %s" % sql
  1240. cursor.execute(sql)
  1241. if cursor.rowcount != 1:
  1242. print " *ERROR* modified %d rows (expected 1): %s " % ( cursor.rowcount, sql )
  1243. money = -1
  1244. cursor.close()
  1245.  
  1246. # HACK CHECK
  1247. # cursor = self.db.cursor()
  1248. # sql = ( "select sum(money), sum(bet) from user2table" )
  1249. # cursor.execute(sql)
  1250. # (total_money,bet) = cursor.fetchone()
  1251. # if total_money + bet != 120000:
  1252. # print "BUG(6) %d" % (total_money + bet)
  1253. # os.abort()
  1254. # cursor.close()
  1255. # END HACK CHECK
  1256.  
  1257. return money
  1258.  
  1259. def leavePlayer(self, serial, table_id, currency_serial):
  1260. status = True
  1261. cursor = self.db.cursor()
  1262. if currency_serial != '':
  1263. sql = ( "UPDATE user2money,user2table,pokertables SET " +
  1264. " user2money.amount = user2money.amount + user2table.money + user2table.bet " +
  1265. " WHERE user2money.user_serial = user2table.user_serial AND " +
  1266. " user2money.currency_serial = pokertables.currency_serial AND " +
  1267. " pokertables.serial = " + str(table_id) + " AND " +
  1268. " user2table.table_serial = " + str(table_id) + " AND " +
  1269. " user2table.user_serial = " + str(serial) )
  1270. if self.verbose > 1:
  1271. print "leavePlayer %s" % sql
  1272. cursor.execute(sql)
  1273. if cursor.rowcount > 1:
  1274. print " *ERROR* modified %d rows (expected 0 or 1): %s " % ( cursor.rowcount, sql )
  1275. status = False
  1276. sql = ( "delete from user2table "
  1277. " where user_serial = " + str(serial) + " and "
  1278. " table_serial = " + str(table_id) )
  1279. if self.verbose > 1:
  1280. print "leavePlayer %s" % sql
  1281. cursor.execute(sql)
  1282. if cursor.rowcount != 1:
  1283. print " *ERROR* modified %d rows (expected 1): %s " % ( cursor.rowcount, sql )
  1284. status = False
  1285. cursor.close()
  1286. return status
  1287.  
  1288. def updatePlayerRake(self, currency_serial, serial, amount):
  1289. if amount == 0:
  1290. return True
  1291. status = True
  1292. cursor = self.db.cursor()
  1293. sql = ( "UPDATE user2money SET "
  1294. " rake = rake + " + str(amount) + ", "
  1295. " points = points + " + str(amount) + " "
  1296. " WHERE user_serial = " + str(serial) + " AND "
  1297. " currency_serial = " + str(currency_serial) )
  1298. if self.verbose > 1:
  1299. print "updatePlayerRake: %s" % sql
  1300. cursor.execute(sql)
  1301. if cursor.rowcount != 1:
  1302. print " *ERROR* modified %d rows (expected 1): %s " % ( cursor.rowcount, sql )
  1303. status = False
  1304. cursor.close()
  1305.  
  1306. def updatePlayerMoney(self, serial, table_id, amount):
  1307. if amount == 0:
  1308. return True
  1309. status = True
  1310. cursor = self.db.cursor()
  1311. sql = ( "UPDATE user2table SET "
  1312. " money = money + " + str(amount) + ", "
  1313. " bet = bet - " + str(amount) +
  1314. " WHERE user_serial = " + str(serial) + " AND "
  1315. " table_serial = " + str(table_id) )
  1316. if self.verbose > 1:
  1317. print "updatePlayerMoney: %s" % sql
  1318. cursor.execute(sql)
  1319. if cursor.rowcount != 1:
  1320. print " *ERROR* modified %d rows (expected 1): %s " % ( cursor.rowcount, sql )
  1321. status = False
  1322. cursor.close()
  1323.  
  1324. # # HACK CHECK
  1325. # cursor = self.db.cursor()
  1326. # sql = ( "select sum(money), sum(bet) from user2table" )
  1327. # cursor.execute(sql)
  1328. # (money,bet) = cursor.fetchone()
  1329. # if money + bet != 120000:
  1330. # print "BUG(4) %d" % (money + bet)
  1331. # os.abort()
  1332. # cursor.close()
  1333.  
  1334. # cursor = self.db.cursor()
  1335. # sql = ( "select user_serial,table_serial,money from user2table where money < 0" )
  1336. # cursor.execute(sql)
  1337. # if cursor.rowcount >= 1:
  1338. # (user_serial, table_serial, money) = cursor.fetchone()
  1339. # print "BUG(11) %d/%d/%d" % (user_serial, table_serial, money)
  1340. # os.abort()
  1341. # cursor.close()
  1342. # # END HACK CHECK
  1343.  
  1344. return status
  1345.  
  1346. def tableMoneyAndBet(self, table_id):
  1347. cursor = self.db.cursor()
  1348. sql = ( "SELECT sum(money), sum(bet) FROM user2table WHERE table_serial = " + str(table_id) )
  1349. cursor.execute(sql)
  1350. (money, bet) = cursor.fetchone()
  1351. cursor.close()
  1352. if not money: money = 0
  1353. elif type(money) == StringType: money = int(money)
  1354. if not bet: bet = 0
  1355. elif type(bet) == StringType: bet = int(bet)
  1356. return (money, bet)
  1357.  
  1358. def destroyTable(self, table_id):
  1359.  
  1360. # # HACK CHECK
  1361. # cursor = self.db.cursor()
  1362. # sql = ( "select * from user2table where money != 0 and bet != 0 and table_serial = " + str(table_id) )
  1363. # cursor.execute(sql)
  1364. # if cursor.rowcount != 0:
  1365. # print "BUG(10)"
  1366. # os.abort()
  1367. # cursor.close()
  1368. # # END HACK CHECK
  1369.  
  1370. cursor = self.db.cursor()
  1371. sql = ( "delete from user2table "
  1372. " where table_serial = " + str(table_id) )
  1373. if self.verbose > 1:
  1374. print "destroy: %s" % sql
  1375. cursor.execute(sql)
  1376.  
  1377. # def setRating(self, winners, serials):
  1378. # url = self.settings.headerGet("/server/@rating")
  1379. # if url == "":
  1380. # return
  1381.  
  1382. # params = []
  1383. # for first in range(0, len(serials) - 1):
  1384. # for second in range(first + 1, len(serials)):
  1385. # first_wins = serials[first] in winners
  1386. # second_wins = serials[second] in winners
  1387. # if first_wins or second_wins:
  1388. # param = "a=%d&b=%d&c=" % ( serials[first], serials[second] )
  1389. # if first_wins and second_wins:
  1390. # param += "2"
  1391. # elif first_wins:
  1392. # param += "0"
  1393. # else:
  1394. # param += "1"
  1395. # params.append(param)
  1396.  
  1397. # params = join(params, '&')
  1398. # if self.verbose > 2:
  1399. # print "setRating: url = %s" % url + params
  1400. # content = loadURL(url + params)
  1401. # if self.verbose > 2:
  1402. # print "setRating: %s" % content
  1403.  
  1404. def resetBet(self, table_id):
  1405. status = True
  1406. cursor = self.db.cursor()
  1407. sql = ( "update user2table set bet = 0 "
  1408. " where table_serial = " + str(table_id) )
  1409. if self.verbose > 1:
  1410. print "resetBet: %s" % sql
  1411. cursor.execute(sql)
  1412. cursor.close()
  1413.  
  1414. # # HACK CHECK
  1415. # cursor = self.db.cursor()
  1416. # sql = ( "select sum(money), sum(bet) from user2table" )
  1417. # cursor.execute(sql)
  1418. # (money,bet) = cursor.fetchone()
  1419. # if money + bet != 120000:
  1420. # print "BUG(2) %d" % (money + bet)
  1421. # os.abort()
  1422. # cursor.close()
  1423. # # END HACK CHECK
  1424.  
  1425. return status
  1426.  
  1427. def getTable(self, game_id):
  1428. for table in self.tables:
  1429. if game_id == table.game.id:
  1430. game = table.game
  1431. return table
  1432. return False
  1433.  
  1434. def createTable(self, owner, description):
  1435. #
  1436. # Do not create two tables by the same name
  1437. #
  1438. if filter(lambda table: table.game.name == description["name"], self.tables):
  1439. print "*ERROR* will not create two tables by the same name %s" % description["name"]
  1440. return False
  1441.  
  1442. id = self.table_serial
  1443. table = PokerTable(self, id, description)
  1444. table.owner = owner
  1445.  
  1446. cursor = self.db.cursor()
  1447. sql = ( "INSERT pokertables ( serial, name, currency_serial ) VALUES "
  1448. " ( " + str(id) + ", \"" + description["name"] + "\", " + str(description["currency_serial"]) + " ) " )
  1449. if self.verbose > 1:
  1450. print "createTable: %s" % sql
  1451. cursor.execute(sql)
  1452. if cursor.rowcount != 1:
  1453. print " *ERROR* inserted %d rows (expected 1): %s " % ( cursor.rowcount, sql )
  1454. cursor.close()
  1455.  
  1456. self.tables.append(table)
  1457. self.table_serial += 1
  1458.  
  1459. if self.verbose:
  1460. print "table created : %s" % table.game.name
  1461.  
  1462. return table
  1463.  
  1464. def cleanupCrashedTables(self):
  1465. cursor = self.db.cursor()
  1466.  
  1467. sql = ( "select user_serial,table_serial,currency_serial from pokertables,user2table where user2table.table_serial = pokertables.serial " )
  1468. cursor.execute(sql)
  1469. if cursor.rowcount > 0 and self.verbose > 1:
  1470. print "cleanupCrashedTables found %d players" % cursor.rowcount
  1471. for i in xrange(cursor.rowcount):
  1472. (user_serial, table_serial, currency_serial) = cursor.fetchone()
  1473. self.leavePlayer(user_serial, table_serial, currenc
Add Comment
Please, Sign In to add comment