- add new CF module - classes CFDataFile and CFData

- replace crossfirelog shelf with plain text datafile (less efficient
but more accessable) - add logging for kick and muzzle
- add more dm commands for seen (chicken oracle, guy in goths...)
- make sure you make a datafiles dir in var/crossfire or have make
install do it for you.


git-svn-id: svn://svn.code.sf.net/p/crossfire/code/trunk/maps@2902 282e977c-c81d-0410-88c4-b93c2d0d6712
master
temitchell 2004-09-01 02:03:26 +00:00
parent bbe821711a
commit 6a517e7fe6
9 changed files with 324 additions and 60 deletions

View File

@ -0,0 +1,144 @@
# CFDataFile.py - CFData classes
#
# Copyright (C) 2002 Joris Bontje
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#
import os
import string
import CFPython
class CFDataFile:
'''Plain text storage for Crossfire data'''
def __init__(self, datafile_name):
self.datafile_name = datafile_name
self.filename = os.path.join((CFPython.GetLocalDirectory()),'datafiles',datafile_name)
def exists(self):
'''checks for datafile'''
if os.path.isfile(self.filename):
return 1
else:
return 0
def make_file(self, header):
'''creates a datafile, making the column header from a list'''
try:
file = open(self.filename,'w')
except:
print "Can't create datafile %s" % self.datafile_name
return 0
else:
temp = []
for item in header:
temp.append(str(item))
contents = '#|%s\n' %(string.join(temp,'|'))
file.write(contents)
file.close()
print "New datafile created: %s" % self.datafile_name
def getData(self):
'''Gets the formatted file as a dictionary
The # key contains the column headers for the file'''''
try:
file = open(self.filename,'r')
except:
raise 'Unable to read %s' % self.datafile_name
else:
temp = file.read().split('\n')
file.close()
contents = temp[:-1]
DF = {}
templist = []
for list in contents:
templist = list.split('|')
DF[templist[0]] = templist[1:]
return DF
def putData(self, dic):
'''Writes dictionary to formatted file'''
try:
file = open(self.filename,'w')
except:
raise 'Unable to open %s for writing' % self.datafile_name
else:
header = dic['#']
del dic['#']
index = dic.keys()
index.sort()
contents = '#|%s\n' %(string.join(header,'|'))
file.write(contents)
for entry in index:
tmp = []
stringlist = dic[entry]
for item in stringlist:
tmp.append(str(item))
temp = '%s|%s\n' %(entry, (string.join(tmp,'|')))
file.write(temp)
file.close()
class CFData:
'''CFData Object is basically a dictionary parsed from the datafile'''
def __init__(self, filename, header):
self.header = header
self.datafile = CFDataFile(filename)
if self.datafile.exists():
self.datadb = self.datafile.getData()
if self.datadb['#'] != self.header:
raise 'Header does not match! You may need to fix the object or the datafile.'
else:
self.datafile.make_file(self.header)
self.datadb = self.datafile.getData()
def remove_record(self, name):
if self.datadb.has_key(name):
del self.datadb[name]
self.datafile.putData(self.datadb)
return 1
else:
return 0
def exist(self, name):
if self.datadb.has_key(name):
return 1
else:
return 0
def get_record(self, name):
if self.exist(name):
record = {}
for header, item in zip(self.header,self.datadb[name]):
record[header]=item
record['#'] = name
return record
else:
return 0
def put_record(self, record):
name = record['#']
del record['#']
temp = []
for item in self.header:
temp.append(record[item])
self.datadb[name]=temp
self.datafile.putData(self.datadb)

View File

@ -18,46 +18,66 @@
# #
# The author can be reached via e-mail at jbontje@suespammers.org # The author can be reached via e-mail at jbontje@suespammers.org
# #
#Updated to use new path functions in CFPython -Todd Mitchell
import shelve # Updated to use new path functions in CFPython -Todd Mitchell
import os.path #
# Updated to add new fields and functions (kick, muzzle)
# and rewritten to use plain text file storage (CFDataFile) instead of shelve.
import CFPython import CFPython
from time import localtime, strftime, time from time import localtime, strftime, time
from CFDataFile import CFDataFile, CFData
class CFLog: class CFLog:
logdb_file = os.path.join(CFPython.GetLocalDirectory(),'crossfirelog')
logdb = {}
def __init__(self): def __init__(self):
self.logdb = shelve.open(self.logdb_file) logheader = ['Born', 'IP', 'Last_Login_Date', 'Login_Count', 'Kick_Count'
, 'Last_Kick_Date', 'Muzzle_Count', 'Last_Muzzle_Date']
self.log = CFData('Player_log', logheader)
def create(self, name): def create(self, name):
date = strftime("%a, %d %b %Y %H:%M:%S CEST", localtime(time())) date = strftime("%a, %d %b %Y %H:%M:%S CEST", localtime(time()))
count=1 record={'#': name
self.logdb[name]=['unknown', date, count] ,'Born':date
,'IP':'unknown'
def update(self, name, ip): ,'Last_Login_Date':date
date = strftime("%a, %d %b %Y %H:%M:%S CEST", localtime(time())) ,'Login_Count':0
count=0 ,'Kick_Count':0
if self.logdb.has_key(name): ,'Last_Kick_Date':'never'
oldip, olddate, count=self.logdb[name] ,'Muzzle_Count':0
count+=1 ,'Last_Muzzle_Date':'never'}
self.logdb[name]=[ip, date, count] self.log.put_record(record)
def remove(self, name): def remove(self, name):
if self.logdb.has_key(name): self.log.remove_record(name)
del self.logdb[name]
def login_update(self, name, ip):
def exist(self, name): date = strftime("%a, %d %b %Y %H:%M:%S CEST", localtime(time()))
if self.logdb.has_key(name): record = self.log.get_record(name)
return 1 record['IP']=ip
record['Last_Login_Date']=date
record['Login_Count']=int(record['Login_Count'])+1
self.log.put_record(record)
def kick_update(self, name):
date = strftime("%a, %d %b %Y %H:%M:%S CEST", localtime(time()))
record = self.log.get_record(name)
record['Kick_Count']=int(record['Kick_Count'])+1
record['Last_Kick_Date']=date
self.log.put_record(record)
def muzzle_update(self, name):
date = strftime("%a, %d %b %Y %H:%M:%S CEST", localtime(time()))
record = self.log.get_record(name)
record['Muzzle_Count']=int(record['Muzzle_Count'])+1
record['Last_Muzzle_Date']=date
self.log.put_record(record)
def info(self, name):
record = self.log.get_record(name)
if record:
return record
else: else:
return 0 return 0
def info(self, name):
if self.exist(name):
ip, date, count=self.logdb[name]
return ip, date, count

View File

@ -74,7 +74,7 @@ elif text[0] == 'literacy':
elif text[0] == 'mailscroll': elif text[0] == 'mailscroll':
if len(text)==2: if len(text)==2:
if log.exist(text[1]): if log.info(text[1]):
if (CFPython.PayAmount(activator, priceMailScroll*50)): if (CFPython.PayAmount(activator, priceMailScroll*50)):
CFPython.Say(whoami, 'Here is your mailscroll') CFPython.Say(whoami, 'Here is your mailscroll')
id = CFPython.CreateObject('scroll', (x, y)) id = CFPython.CreateObject('scroll', (x, y))
@ -92,7 +92,7 @@ elif text[0] == 'mailscroll':
elif text[0] == 'mailwarning': elif text[0] == 'mailwarning':
if (CFPython.IsDungeonMaster(activator)): if (CFPython.IsDungeonMaster(activator)):
if len(text)==2: if len(text)==2:
if log.exist(text[1]): if log.info(text[1]):
CFPython.Say(whoami, 'Here is your mailwarning') CFPython.Say(whoami, 'Here is your mailwarning')
id = CFPython.CreateObject('diploma', (x, y)) id = CFPython.CreateObject('diploma', (x, y))
CFPython.SetName(id, 'mailwarning T: '+text[1]+' F: '+ activatorname) CFPython.SetName(id, 'mailwarning T: '+text[1]+' F: '+ activatorname)
@ -105,16 +105,5 @@ elif text[0] == 'mailwarning':
else: else:
CFPython.Say(whoami, 'You need to be DM to be able to use this command') CFPython.Say(whoami, 'You need to be DM to be able to use this command')
elif text[0] == 'seen':
if len(text)==2:
if log.exist(text[1]):
ip, date, count = log.info(text[1])
CFPython.Say(whoami, "I have seen '%s' joining %d times, last at %s." % (text[1], count, date))
else:
CFPython.Say(whoami, "I have never seen '%s' joining" % text[1])
else:
CFPython.Say(whoami, 'Usage "seen <friend>"')
else: else:
CFPython.Say(whoami, 'Do you need help?') CFPython.Say(whoami, 'Do you need help?')

View File

@ -20,19 +20,22 @@
# #
#Updated to use new path functions in CFPython, and broken into tiny bits by -Todd Mitchell #Updated to use new path functions in CFPython, and broken into tiny bits by -Todd Mitchell
# #
# seen - tells player information from logger # seen - tells player information from logger
import CFPython import CFPython
import sys import sys
import string
import os.path import os.path
sys.path.append(os.path.join(CFPython.GetDataDirectory(),CFPython.GetMapDirectory(),'python')) sys.path.append(os.path.join(CFPython.GetDataDirectory(),CFPython.GetMapDirectory(),'python'))
import CFLog import CFLog
activator=CFPython.WhoIsActivator() activator=CFPython.WhoIsActivator()
activatorname=CFPython.GetName(activator) activatorname=CFPython.GetName(activator)
whoami=CFPython.WhoAmI() whoami=CFPython.WhoAmI()
isDM=CFPython.IsDungeonMaster(activator)
x=CFPython.GetXPosition(activator) x=CFPython.GetXPosition(activator)
y=CFPython.GetYPosition(activator) y=CFPython.GetYPosition(activator)
@ -40,18 +43,65 @@ log = CFLog.CFLog()
text = string.split(CFPython.WhatIsMessage()) text = string.split(CFPython.WhatIsMessage())
if text[0] == 'seen': if text[0] == 'seen':
if len(text)==2: if len(text)==2:
if log.exist(text[1]): record = log.info(text[1])
ip, date, count = log.info(text[1]) if record:
if (CFPython.IsDungeonMaster(activator)): if isDM:
CFPython.Say(whoami, "I have seen '%s' %d times.\nI saw them last coming from\nIP: %s\non %s." % (text[1], count, ip, date)) message = "I have seen '%s' %d times.\nI saw them last coming from\nIP: %s\non %s." % (text[1], int(record['Login_Count']), record['IP'], record['Last_Login_Date'])
else: else:
CFPython.Say(whoami, "I have seen '%s' %d times.\nI saw them last at %s." % (text[1], count, date)) message = "I have seen '%s' %d times.\nI saw them last at %s." % (text[1], int(record['Login_Count']), record['Last_Login_Date'])
else: else:
CFPython.Say(whoami, "I have never seen '%s'." % text[1]) message = "I have never seen '%s'." % text[1]
else: else:
CFPython.Say(whoami, 'Usage "seen <friend>"') message = 'Usage "seen <player>"'
elif text[0] == 'help':
if isDM:
message = "How can I help you? Here is a quick list of commands:\nseen, muzzlestatus, muzzlecount, lastmuzzle, kickcount, lastkick"
else:
message = "I have seen just about everybody - go ahead and ask me."
elif text[0] == 'muzzlecount' and isDM:
if len(text)==2:
record = log.info(text[1])
if record:
message = "%s has been muzzled %d times" % (text[1],int(record['Muzzle_Count']))
else:
message = "I have no knowledge of '%s'." % text[1]
else:
message = 'Usage "muzzlecount <player>"'
elif text[0] == 'lastmuzzle' and isDM:
if len(text)==2:
record = log.info(text[1])
if record:
message = "%s was last muzzled on %s" % (text[1],record['Last_Muzzle_Date'])
else:
message = "I have no knowledge of '%s'." % text[1]
else:
message = 'Usage "muzzlestatus <player>"'
elif text[0] == 'kickcount' and isDM:
if len(text)==2:
record = log.info(text[1])
if record:
message = "%s has been kicked %d times" % (text[1],int(record['Kick_Count']))
else:
message = "I have no knowledge of '%s'." % text[1]
else:
message = 'Usage "kickcount <player>"'
elif text[0] == 'lastkick' and isDM:
if len(text)==2:
record = log.info(text[1])
if record:
message = "%s was last kicked out on %s" % (text[1],record['Last_Kick_Date'])
else:
message = "I have no knowledge of '%s'." % text[1]
else:
message = 'Usage "lastkick <player>"'
else: else:
CFPython.Say(whoami, 'You looking for someone?') message = "Do you need help?"
CFPython.Say(whoami, message)

View File

@ -22,9 +22,9 @@
import CFPython import CFPython
import sys import sys
sys.path.append('%s/%s/python' %(CFPython.GetDataDirectory(),CFPython.GetMapDirectory())) import os.path
sys.path.append(os.path.join(CFPython.GetDataDirectory(),CFPython.GetMapDirectory(),'python'))
import CFLog import CFLog
import string
activator = CFPython.WhoIsActivator() activator = CFPython.WhoIsActivator()
name = CFPython.GetName(activator) name = CFPython.GetName(activator)

View File

@ -0,0 +1,30 @@
# python_kick.py - handler for global KICK event
#
# Copyright (C) 2004 Todd Mitchell
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#
import CFPython
import sys
import os.path
sys.path.append(os.path.join(CFPython.GetDataDirectory(),CFPython.GetMapDirectory(),'python'))
import CFLog
activator = CFPython.WhoIsActivator()
name = CFPython.GetName(activator)
log = CFLog.CFLog()
log.kick_update(name)

View File

@ -22,10 +22,10 @@
import CFPython import CFPython
import sys import sys
sys.path.append('%s/%s/python' %(CFPython.GetDataDirectory(),CFPython.GetMapDirectory())) import os.path
sys.path.append(os.path.join(CFPython.GetDataDirectory(),CFPython.GetMapDirectory(),'python'))
import CFMail import CFMail
import CFLog import CFLog
import string
activator = CFPython.WhoIsActivator() activator = CFPython.WhoIsActivator()
name = CFPython.GetName(activator) name = CFPython.GetName(activator)
@ -34,7 +34,7 @@ ip = CFPython.WhatIsMessage()
mail = CFMail.CFMail() mail = CFMail.CFMail()
log = CFLog.CFLog() log = CFLog.CFLog()
total = mail.countmail(name) total = mail.countmail(name)
log.update(name, ip) log.login_update(name, ip)
if total > 0: if total > 0:
CFPython.Write('You have some mail waiting for you', activator) CFPython.Write('You have some mail waiting for you', activator)

View File

@ -0,0 +1,30 @@
# python_muzzle.py - handler for global MUZZLE event
#
# Copyright (C) 2004 Todd Mitchell
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#
import CFPython
import sys
import os.path
sys.path.append(os.path.join(CFPython.GetDataDirectory(),CFPython.GetMapDirectory(),'python'))
import CFLog
activator = CFPython.WhoIsActivator()
name = CFPython.GetName(activator)
log = CFLog.CFLog()
log.muzzle_update(name)

View File

@ -23,7 +23,8 @@
import CFPython import CFPython
import sys import sys
sys.path.append('%s/%s/python' %(CFPython.GetDataDirectory(),CFPython.GetMapDirectory())) import os.path
sys.path.append(os.path.join(CFPython.GetDataDirectory(),CFPython.GetMapDirectory(),'python'))
import CFLog import CFLog
import CFBank import CFBank