- 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
#
#Updated to use new path functions in CFPython -Todd Mitchell
import shelve
import os.path
# Updated to use new path functions in CFPython -Todd Mitchell
#
# Updated to add new fields and functions (kick, muzzle)
# and rewritten to use plain text file storage (CFDataFile) instead of shelve.
import CFPython
from time import localtime, strftime, time
from CFDataFile import CFDataFile, CFData
class CFLog:
logdb_file = os.path.join(CFPython.GetLocalDirectory(),'crossfirelog')
logdb = {}
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):
date = strftime("%a, %d %b %Y %H:%M:%S CEST", localtime(time()))
count=1
self.logdb[name]=['unknown', date, count]
def update(self, name, ip):
date = strftime("%a, %d %b %Y %H:%M:%S CEST", localtime(time()))
count=0
if self.logdb.has_key(name):
oldip, olddate, count=self.logdb[name]
count+=1
self.logdb[name]=[ip, date, count]
record={'#': name
,'Born':date
,'IP':'unknown'
,'Last_Login_Date':date
,'Login_Count':0
,'Kick_Count':0
,'Last_Kick_Date':'never'
,'Muzzle_Count':0
,'Last_Muzzle_Date':'never'}
self.log.put_record(record)
def remove(self, name):
if self.logdb.has_key(name):
del self.logdb[name]
def exist(self, name):
if self.logdb.has_key(name):
return 1
self.log.remove_record(name)
def login_update(self, name, ip):
date = strftime("%a, %d %b %Y %H:%M:%S CEST", localtime(time()))
record = self.log.get_record(name)
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:
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':
if len(text)==2:
if log.exist(text[1]):
if log.info(text[1]):
if (CFPython.PayAmount(activator, priceMailScroll*50)):
CFPython.Say(whoami, 'Here is your mailscroll')
id = CFPython.CreateObject('scroll', (x, y))
@ -92,7 +92,7 @@ elif text[0] == 'mailscroll':
elif text[0] == 'mailwarning':
if (CFPython.IsDungeonMaster(activator)):
if len(text)==2:
if log.exist(text[1]):
if log.info(text[1]):
CFPython.Say(whoami, 'Here is your mailwarning')
id = CFPython.CreateObject('diploma', (x, y))
CFPython.SetName(id, 'mailwarning T: '+text[1]+' F: '+ activatorname)
@ -105,16 +105,5 @@ elif text[0] == 'mailwarning':
else:
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:
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
#
# seen - tells player information from logger
# seen - tells player information from logger
import CFPython
import sys
import string
import os.path
sys.path.append(os.path.join(CFPython.GetDataDirectory(),CFPython.GetMapDirectory(),'python'))
import CFLog
activator=CFPython.WhoIsActivator()
activatorname=CFPython.GetName(activator)
whoami=CFPython.WhoAmI()
isDM=CFPython.IsDungeonMaster(activator)
x=CFPython.GetXPosition(activator)
y=CFPython.GetYPosition(activator)
@ -40,18 +43,65 @@ log = CFLog.CFLog()
text = string.split(CFPython.WhatIsMessage())
if text[0] == 'seen':
if len(text)==2:
if log.exist(text[1]):
ip, date, count = log.info(text[1])
if (CFPython.IsDungeonMaster(activator)):
CFPython.Say(whoami, "I have seen '%s' %d times.\nI saw them last coming from\nIP: %s\non %s." % (text[1], count, ip, date))
else:
CFPython.Say(whoami, "I have seen '%s' %d times.\nI saw them last at %s." % (text[1], count, date))
else:
CFPython.Say(whoami, "I have never seen '%s'." % text[1])
else:
CFPython.Say(whoami, 'Usage "seen <friend>"')
if len(text)==2:
record = log.info(text[1])
if record:
if isDM:
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:
message = "I have seen '%s' %d times.\nI saw them last at %s." % (text[1], int(record['Login_Count']), record['Last_Login_Date'])
else:
message = "I have never seen '%s'." % text[1]
else:
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:
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 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 string
activator = CFPython.WhoIsActivator()
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 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 CFLog
import string
activator = CFPython.WhoIsActivator()
name = CFPython.GetName(activator)
@ -34,7 +34,7 @@ ip = CFPython.WhatIsMessage()
mail = CFMail.CFMail()
log = CFLog.CFLog()
total = mail.countmail(name)
log.update(name, ip)
log.login_update(name, ip)
if total > 0:
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 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 CFBank