- 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-b93c2d0d6712master
parent
bbe821711a
commit
6a517e7fe6
|
@ -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)
|
||||
|
||||
|
||||
|
||||
|
|
@ -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
|
||||
|
|
|
@ -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?')
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
|
@ -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
|
||||
|
||||
|
|
Loading…
Reference in New Issue