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-b93c2d0d6712
master
partmedia 2017-07-27 06:35:06 +00:00
parent 45f873736b
commit 739ca3508b
3 changed files with 47 additions and 64 deletions

View File

@ -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

View File

@ -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()

View File

@ -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)