Restore original CFBank API
Moving accounts to player files added unnecessary complexity. Restore original API and add code to migrate accounts back from player files. While here, wrap CFBank with a context manager so it can be used with the Python 'with' statement. git-svn-id: svn://svn.code.sf.net/p/crossfire/code/maps/trunk@20449 282e977c-c81d-0410-88c4-b93c2d0d6712master
parent
45f873736b
commit
739ca3508b
|
@ -1,12 +1,7 @@
|
|||
"""
|
||||
Created by: Joris Bontje <jbontje@suespammers.org>
|
||||
|
||||
This module stores bank account information. Player accounts are stored in
|
||||
the player file using the 'balance' key. Other accounts (for guilds) are
|
||||
stored in the original bank file using the 'shelve' library.
|
||||
|
||||
Since the original implementation stored player accounts using the 'shelve'
|
||||
library as well, this module also converts old bank accounts to new ones.
|
||||
This module stores bank account information.
|
||||
"""
|
||||
|
||||
import os.path
|
||||
|
@ -16,10 +11,15 @@ import Crossfire
|
|||
|
||||
class CFBank:
|
||||
def __init__(self, bankfile):
|
||||
self.bankdb_file = os.path.join(Crossfire.LocalDirectory(),
|
||||
bankfile)
|
||||
self.bankdb_file = os.path.join(Crossfire.LocalDirectory(), bankfile)
|
||||
self.bankdb = shelve.open(self.bankdb_file)
|
||||
|
||||
def __enter__(self):
|
||||
return self
|
||||
|
||||
def __exit__(self, exc_type, exc_value, traceback):
|
||||
self.close()
|
||||
|
||||
def deposit(self, user, amount):
|
||||
if not user in self.bankdb:
|
||||
self.bankdb[user] = amount
|
||||
|
@ -29,13 +29,14 @@ class CFBank:
|
|||
|
||||
def withdraw(self, user, amount):
|
||||
if user in self.bankdb:
|
||||
if self.bankdb[user] >= amount:
|
||||
balance = self.bankdb[user]
|
||||
balance = self.getbalance(user)
|
||||
if balance >= amount:
|
||||
self.bankdb[user] = balance - amount
|
||||
return 1
|
||||
return 0
|
||||
|
||||
def getbalance(self, user):
|
||||
self._convert(user)
|
||||
if user in self.bankdb:
|
||||
return self.bankdb[user]
|
||||
else:
|
||||
|
@ -53,43 +54,26 @@ class CFBank:
|
|||
def close(self):
|
||||
self.bankdb.close()
|
||||
|
||||
def _convert(self, name):
|
||||
"""Move a player's balance from the player file to the bank."""
|
||||
player = Crossfire.FindPlayer(name)
|
||||
if player is None:
|
||||
return 0
|
||||
old_balance = _balance_legacy(player)
|
||||
if old_balance > 0:
|
||||
Crossfire.Log(Crossfire.LogInfo,
|
||||
"Converting bank account for %s with %d silver" \
|
||||
% (name, old_balance))
|
||||
self.deposit(name, old_balance)
|
||||
player.WriteKey("balance", "moved-to-bank-file", 1)
|
||||
|
||||
def convert_bank(player):
|
||||
"""Move a player's balance from the bank file to the player file."""
|
||||
bank = CFBank('ImperialBank_DB')
|
||||
old_balance = bank.getbalance(player.Name)
|
||||
if old_balance > 0:
|
||||
Crossfire.Log(Crossfire.LogInfo,
|
||||
"Converting bank account for %s with %d silver" \
|
||||
% (player.Name, old_balance))
|
||||
player.WriteKey("balance", str(old_balance), 1)
|
||||
bank.remove_account(player.Name)
|
||||
bank.close()
|
||||
return old_balance
|
||||
def open():
|
||||
return CFBank('ImperialBank_DB')
|
||||
|
||||
def balance(player):
|
||||
def _balance_legacy(player):
|
||||
"""Return the balance of the given player's bank account."""
|
||||
try:
|
||||
balance_str = player.ReadKey("balance")
|
||||
return int(balance_str)
|
||||
except ValueError:
|
||||
# If 'balance' key does not exist, try to convert from bank file.
|
||||
return convert_bank(player)
|
||||
|
||||
def deposit(player, amount):
|
||||
"""Deposit the given amount to the player's bank account."""
|
||||
if amount < 0:
|
||||
raise ValueError("Deposits must be positive")
|
||||
new_balance = balance(player) + int(amount)
|
||||
player.WriteKey("balance", str(new_balance), 1)
|
||||
|
||||
def withdraw(player, amount):
|
||||
"""Withdraw the given amount from the player's bank account."""
|
||||
if amount < 0:
|
||||
raise ValueError("Withdrawals must be positive")
|
||||
new_balance = balance(player) - int(amount)
|
||||
if new_balance < 0:
|
||||
return False
|
||||
else:
|
||||
player.WriteKey("balance", str(new_balance), 1)
|
||||
return True
|
||||
return 0
|
||||
|
|
|
@ -11,8 +11,6 @@ import Crossfire
|
|||
import CFBank
|
||||
import CFItemBroker
|
||||
|
||||
bank = CFBank.CFBank('ImperialBank_DB')
|
||||
|
||||
activator = Crossfire.WhoIsActivator()
|
||||
whoami = Crossfire.WhoAmI()
|
||||
x = activator.X
|
||||
|
@ -82,9 +80,10 @@ def get_inventory(obj):
|
|||
|
||||
def do_deposit(player, amount):
|
||||
"""Deposit the given amount for the player."""
|
||||
CFBank.deposit(player, amount)
|
||||
whoami.Say("%s credited to your account." \
|
||||
% Crossfire.CostStringFromValue(amount))
|
||||
with CFBank.open() as bank:
|
||||
bank.deposit(player.Name, amount)
|
||||
whoami.Say("%s credited to your account." \
|
||||
% Crossfire.CostStringFromValue(amount))
|
||||
|
||||
def deposit_box_close():
|
||||
"""Find the total value of items in the deposit box and deposit."""
|
||||
|
@ -105,7 +104,9 @@ def cmd_help():
|
|||
|
||||
def cmd_balance(argv):
|
||||
"""Find out how much money the player has in his/her account."""
|
||||
balance = CFBank.balance(activator)
|
||||
balance = 0
|
||||
with CFBank.open() as bank:
|
||||
balance = bank.getbalance(activator.Name)
|
||||
if len(argv) >= 2:
|
||||
# Give balance using the desired coin type.
|
||||
coinName = getCoinNameFromArgs(argv[1:])
|
||||
|
@ -159,17 +160,18 @@ def cmd_withdraw(argv):
|
|||
return
|
||||
|
||||
# Make sure the player has sufficient funds.
|
||||
if CFBank.withdraw(activator, amount * exchange_rate):
|
||||
message = "%d %s withdrawn from your account. %s" \
|
||||
% (amount, coinName, random.choice(thanks_message))
|
||||
with CFBank.open() as bank:
|
||||
if bank.withdraw(activator.Name, amount * exchange_rate):
|
||||
message = "%d %s withdrawn from your account. %s" \
|
||||
% (amount, coinName, random.choice(thanks_message))
|
||||
|
||||
# Drop the money and have the player pick it up.
|
||||
withdrawal = activator.Map.CreateObject(
|
||||
ArchType.get(coinName.upper()), x, y)
|
||||
CFItemBroker.Item(withdrawal).add(amount)
|
||||
activator.Take(withdrawal)
|
||||
else:
|
||||
message = "I'm sorry, you don't have enough money."
|
||||
# Drop the money and have the player pick it up.
|
||||
withdrawal = activator.Map.CreateObject(
|
||||
ArchType.get(coinName.upper()), x, y)
|
||||
CFItemBroker.Item(withdrawal).add(amount)
|
||||
activator.Take(withdrawal)
|
||||
else:
|
||||
message = "I'm sorry, you don't have enough money."
|
||||
else:
|
||||
message = "How much money would you like to withdraw?"
|
||||
Crossfire.AddReply("withdraw <amount> <coin name>", "This much!")
|
||||
|
@ -201,6 +203,3 @@ else:
|
|||
main_employee()
|
||||
except ValueError:
|
||||
whoami.Say("I don't know how much money that is.")
|
||||
|
||||
# Close bank database (required) and return.
|
||||
bank.close()
|
||||
|
|
|
@ -29,5 +29,5 @@ name = activator.Name
|
|||
|
||||
#If you add a new bank database add an entry here to remove their account
|
||||
#when the player quits
|
||||
bank = CFBank.CFBank('ImperialBank_DB')
|
||||
bank.remove_account(name)
|
||||
with CFBank.open() as bank:
|
||||
bank.remove_account(name)
|
||||
|
|
Loading…
Reference in New Issue