|
|
@@ -1,5 +1,5 @@
|
|
|
"""This is a web based inspector for the AI System. It can be accessed via
|
|
|
-http://hostname.domain:port/ai
|
|
|
+http://hostname.domain:port/inspect
|
|
|
|
|
|
The hostname.domain would of course be the computer that the AI is running on.
|
|
|
The port will need to be defined when the instance is inited.
|
|
|
@@ -12,6 +12,8 @@ from direct.http import WebRequest
|
|
|
from socket import gethostname
|
|
|
from direct.task.Task import Task
|
|
|
from sys import platform
|
|
|
+from pirates.uberdog.AIMagicWordTrade import AIMagicWordTrade
|
|
|
+from pirates.quest.QuestDB import QuestDict
|
|
|
|
|
|
# Need to figure out which systeminfo module to import
|
|
|
if platform == 'win32':
|
|
|
@@ -26,6 +28,7 @@ class aiWebServer(SystemInformation):
|
|
|
def __init__(self, air, listenPort=8080):
|
|
|
SystemInformation.__init__(self)
|
|
|
self.listenPort = listenPort
|
|
|
+ self.air = simbase.air
|
|
|
# self.taskMgr = Task.TaskManager()
|
|
|
if __debug__:
|
|
|
print "Listen port set to: %d" % self.listenPort
|
|
|
@@ -35,21 +38,157 @@ class aiWebServer(SystemInformation):
|
|
|
self.localHostName = gethostname()
|
|
|
self.web.registerGETHandler('inspect', self.inspect)
|
|
|
self.web.registerGETHandler('systemInfo', self.systemInfo)
|
|
|
+ self.web.registerGETHandler('oMenu', self.oMenu)
|
|
|
self.web.registerGETHandler('oType', self.oType)
|
|
|
self.web.registerGETHandler('oInst', self.oInst)
|
|
|
self.web.registerGETHandler('blank', self.blank)
|
|
|
+ self.web.registerGETHandler('magicWord', self.magicWord)
|
|
|
self.startCheckingIncomingHTTP()
|
|
|
|
|
|
+ def magicWord(self, replyTo, **kw):
|
|
|
+ # This will process Magic Word requests
|
|
|
+ # Currently the following words are supported:
|
|
|
+ # ~aiobjectcount
|
|
|
+ # ~aitaskmgr
|
|
|
+ # ~aijobmgr
|
|
|
+ # ~assignQuest
|
|
|
+ # ~money
|
|
|
+
|
|
|
+ # First we need to figure out which magic word is being called
|
|
|
+ try:
|
|
|
+ theMagicWord = kw['magicWord']
|
|
|
+ except KeyError:
|
|
|
+ # MagicWord issue. Malformed URL
|
|
|
+ replyTo.respond('<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">\n<html>\n<head>\n<meta content="text/html; charset=ISO-8859-1" http-equiv="content-type">\n<TITLE>Magic Word Error</title>\n</head><body>Please check the URL. Transaction could not be completed. Malformed URL.</BODY>\n</HTML>')
|
|
|
+ return
|
|
|
+
|
|
|
+ # Next we execute the magic word request
|
|
|
+ if theMagicWord == 'aiobjectcount':
|
|
|
+ replyTo.respond('<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">\n<html>\n<head>\n<meta content="text/html; charset=ISO-8859-1" http-equiv="content-type">\n<TITLE>%s</title>\n</head><body><PRE>%s</PRE></body>\n</HTML>' % (theMagicWord, simbase.air.webPrintObjectCount()))
|
|
|
+ return
|
|
|
+ elif theMagicWord == 'aitaskmgr':
|
|
|
+ replyTo.respond('<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">\n<html>\n<head>\n<meta content="text/html; charset=ISO-8859-1" http-equiv="content-type">\n<TITLE>%s</title>\n</head><body><PRE>%s</PRE></body>\n</HTML>' % (theMagicWord, taskMgr))
|
|
|
+ return
|
|
|
+ elif theMagicWord == 'aijobmgr':
|
|
|
+ replyTo.respond('<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">\n<html>\n<head>\n<meta content="text/html; charset=ISO-8859-1" http-equiv="content-type">\n<TITLE>%s</title>\n</head><body><PRE>%s</PRE></body>\n</HTML>' % (theMagicWord, jobMgr))
|
|
|
+
|
|
|
+ elif theMagicWord == 'money':
|
|
|
+ # First, generate the Avatar HTML Select widget.
|
|
|
+
|
|
|
+ selectWidget = self.genAvSelect()
|
|
|
+
|
|
|
+ # Now that we've built the avatar list, we can repond with the HTML
|
|
|
+
|
|
|
+ replyTo.respond('<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">\n<html>\n<head>\n<meta content="text/html; charset=ISO-8859-1" http-equiv="content-type">\n<TITLE>Money</title>\n</head><body><form method="get" action="magicWord" name="magicWord">AvatarID: %s\nAmmount: <input maxlength="3" size="3" name="amount" value="100"><br><INPUT TYPE=HIDDEN NAME="magicWord" value="MONEY_ADD"><button value="Submit" name="Submit"></button><br></form></body>\n</HTML>' % selectWidget)
|
|
|
+
|
|
|
+ elif theMagicWord == 'MONEY_ADD':
|
|
|
+ av = kw['avatarId']
|
|
|
+ count = kw['amount']
|
|
|
+ try:
|
|
|
+ av = int(av)
|
|
|
+ count = int(count)
|
|
|
+ except ValueError:
|
|
|
+ # One or both of the two args could not be converted into a int
|
|
|
+ # This being the case, the transaction mut be stopped.
|
|
|
+ # The most likely cause is the input of a non num type into
|
|
|
+ # the amount field
|
|
|
+
|
|
|
+ print 'Incorrect value entered.'
|
|
|
+ replyTo.respond('<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">\n<html>\n<head>\n<meta content="text/html; charset=ISO-8859-1" http-equiv="content-type">\n<TITLE>Money Error</title>\n</head><body>Please check the Amount field. Transaction could not be completed.</BODY>\n</HTML>')
|
|
|
+ return
|
|
|
+
|
|
|
+ try:
|
|
|
+ av = simbase.air.doId2do[av]
|
|
|
+ except KeyError:
|
|
|
+ replyTo.respond('<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">\n<html>\n<head>\n<meta content="text/html; charset=ISO-8859-1" http-equiv="content-type">\n<TITLE>Money Error</title>\n</head><body>Please check the AvatarID field; the Avatar might have logged out. Transaction could not be completed.</BODY>\n</HTML>')
|
|
|
+ return
|
|
|
+ curGold = av.getInventory().getGoldInPocket()
|
|
|
+ # print "Debug: Args being passed to AIMAgicWordTrade:\t%s" % av
|
|
|
+ trade = AIMagicWordTrade(av, av.getDoId(), avatarId = av.getDoId())
|
|
|
+ if count > curGold:
|
|
|
+ trade.giveGoldInPocket(count - curGold)
|
|
|
+ else:
|
|
|
+ trade.takeGoldInPocket(curGold - count)
|
|
|
+ trade.sendTrade()
|
|
|
+ # I don't think I need to issue a tradeRejected or
|
|
|
+ # tradeSucceesed call here.
|
|
|
+
|
|
|
+ replyTo.respond('<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">\n<html>\n<head>\n<meta content="text/html; charset=ISO-8859-1" http-equiv="content-type">\n<TITLE>Money Modified</title>\n</head><body>Transaction complete.</BODY>\n</HTML>')
|
|
|
+ return
|
|
|
+
|
|
|
+ elif theMagicWord == 'assignQuest':
|
|
|
+
|
|
|
+ avSelectWidget = self.genAvSelect()
|
|
|
+ questSelectWidget = self.genQuestSelect()
|
|
|
+
|
|
|
+ # Present HTML menu with options
|
|
|
+
|
|
|
+ replyTo.respond('<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">\n<html>\n<head>\n<meta content="text/html; charset=ISO-8859-1" http-equiv="content-type">\n<TITLE>AssignQuest</title>\n</head><body><form method="get" action="magicWord" name="magicWord">AvatarID: %s\nQuest to Assign: %s<br><INPUT TYPE=HIDDEN NAME="magicWord" value="QUEST_ADD"><button value="Submit" name="Submit"></button><br></form></body>\n</HTML>' % (avSelectWidget, questSelectWidget))
|
|
|
+
|
|
|
+ elif theMagicWord == 'QUEST_ADD':
|
|
|
+ av = kw['avatarId']
|
|
|
+ av = int(av)
|
|
|
+ questId = kw['questId']
|
|
|
+ # print 'Avatarid = %s\nQuestID = %s' % (av, questId)
|
|
|
+ try:
|
|
|
+ av = simbase.air.doId2do[av]
|
|
|
+ except KeyError:
|
|
|
+ replyTo.respond('<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">\n<html>\n<head>\n<meta content="text/html; charset=ISO-8859-1" http-equiv="content-type">\n<TITLE>Money Error</title>\n</head><body>Please check the AvatarID field; the Avatar might have logged out. Transaction could not be completed.</BODY>\n</HTML>')
|
|
|
+ return
|
|
|
+ av.assignQuest(questId)
|
|
|
+ replyTo.respond('<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">\n<html>\n<head>\n<meta content="text/html; charset=ISO-8859-1" http-equiv="content-type">\n<TITLE>Quest Assigned</title>\n</head><body>The avatar with id: %s<BR>Has been assigned Quest: %s</body>\n</HTML>' % (kw['avatarId'], questId))
|
|
|
+ return
|
|
|
+
|
|
|
+ else:
|
|
|
+ # No word Matches
|
|
|
+ replyTo.respond('<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">\n<html>\n<head>\n<meta content="text/html; charset=ISO-8859-1" http-equiv="content-type">\n<TITLE>No Word Matches</title>\n</head><body>The Magic word provided does not exist or is not accessable via the web interface at this time.</body>\n</HTML>')
|
|
|
+ return
|
|
|
+
|
|
|
def timeStamp(self):
|
|
|
# Returns the local time in the following string format:
|
|
|
# Month-Day-Year Hour:Minute:Seconds
|
|
|
# Example: 09-17-2007 15:36:04
|
|
|
return time.strftime("%m-%d-%Y %H:%M:%S", time.localtime())
|
|
|
|
|
|
+ def oMenu(self, replyTo, **kw):
|
|
|
+ # Menu listing Magic words and Raw object list (all HTML links)
|
|
|
+ replyTo.respond('<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">\n<html>\n<head>\n<meta content="text/html; charset=ISO-8859-1" http-equiv="content-type">\n<TITLE>Menu Options</title>\n</head><body>Magic Words:<BR><UL><LI><A HREF="magicWord?magicWord=money" TARGET="oInst">Money</a><LI><A HREF="magicWord?magicWord=assignQuest" TARGET="oInst">AssignQuest</A>\n<LI><A HREF="magicWord?magicWord=aijobmgr" TARGET="oInst">AIjobMgr</A>\n<LI><A HREF="magicWord?magicWord=aitaskmgr" TARGET="oInst">AITaskMgr</a><LI><A HREF="magicWord?magicWord=aiobjectcount" TARGET="oInst">AIObjectCount</A>\n</UL><P><A HREF="oType" TARGET="oType">Raw Object List</a></body>\n</HTML>')
|
|
|
+ return
|
|
|
+
|
|
|
+ def genAvSelect(self):
|
|
|
+ # We will need to populate HTML FORM menus to make this work.
|
|
|
+ # We will need to provide a list of Avatars on the AI
|
|
|
+ # along with a field to allow an int value to be sent
|
|
|
+ # First, we need to get a dict of DistributedPlayerPirateAI's
|
|
|
+
|
|
|
+ playerPirates = []
|
|
|
+ objList = self.generateSortedIDList()
|
|
|
+ objList.reverse()
|
|
|
+ while objList:
|
|
|
+ tempObjElement = objList.pop()
|
|
|
+ if str(tempObjElement[0]).find('DistributedPlayerPirateAI') != -1:
|
|
|
+ playerPirates.append(tempObjElement[1])
|
|
|
+
|
|
|
+ # OK, now playerPirates should be a list of avatar ids
|
|
|
+ # We should build a HTML select widget with the new list
|
|
|
+ selectWidget = '<select name="avatarId">\n'
|
|
|
+ while playerPirates:
|
|
|
+ selectWidget = '%s<option>%s</option>\n' % (selectWidget, str(playerPirates.pop()))
|
|
|
+ selectWidget = '%s</select><br>\n' % selectWidget
|
|
|
+ return selectWidget
|
|
|
+
|
|
|
+ def genQuestSelect(self):
|
|
|
+ # Will generate an HTML select widget, with the Key vals from the QuestDB
|
|
|
+ selectWidget = '<select name="questId">\n'
|
|
|
+ for k, v in QuestDict.iteritems():
|
|
|
+ selectWidget = '%s<option>%s</option>\n' % (selectWidget, k)
|
|
|
+ selectWidget = '%s</select><br>\n' % selectWidget
|
|
|
+ return selectWidget
|
|
|
+
|
|
|
def blank(self, replyTo, **kw):
|
|
|
# This simple generates a blank page for the middle and right
|
|
|
# frames;( for when the page is first accessed)
|
|
|
- replyTo.respond('<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">\n<html>\n<head>\n<meta content="text/html; charset=ISO-8859-1" http-equiv="content-type">\n<TITLE>BLANK</title>\n</head><body></body>\n</HTML>')
|
|
|
+ replyTo.respond('<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">\n<html>\n<head>\n<meta content="text/html; charset=ISO-8859-1" http-equiv="content-type">\n<TITLE>Word not found</title>\n</head><body></body>\n</HTML>')
|
|
|
|
|
|
def oInst(self, replyTo, **kw):
|
|
|
# This will populate the middle frame with list of the members of
|
|
|
@@ -94,7 +233,7 @@ class aiWebServer(SystemInformation):
|
|
|
# tempObjElement[0].replace('<','')
|
|
|
# tempObjElement[0].replace('>','')
|
|
|
# if str(tempObjElement[0]).find('render') == -1:
|
|
|
- body = '%s<LI><A HREF="oInst?id=%s" target="oInst">%s</A>\n' % (body, tempObjElement[1], str(tempObjElement[0]).replace('<','').replace('>',''))
|
|
|
+ body = '%s<LI><A HREF="oInst?id=%s" target="oInst">%s:%s</A>\n' % (body, tempObjElement[1], tempObjElement[1], str(tempObjElement[0]).replace('<','').replace('>',''))
|
|
|
replyTo.respond('%s%s%s' % (head,body,foot))
|
|
|
|
|
|
def inspect(self, replyTo, **kw):
|
|
|
@@ -103,7 +242,7 @@ class aiWebServer(SystemInformation):
|
|
|
# Three frames on the bottom row
|
|
|
# frameset = '<frameset rows="35\%,65\%">\n<frame src="systemInfo" name="systemInfo" frameborder=1>\n<frameset cols="25\%,25\%,50\%">\n<frame src="oType" name="oType" frameborder=1>\n<frame src="blank" name="oInst" frameborder=1>\n<frame src="blank" name="oAttrib" frameborder=1>\n</frameset>\n</frameset>\n</html>'
|
|
|
# Two Frames on the bottom row
|
|
|
- frameset = '<frameset rows="35\%,65\%">\n<frame src="systemInfo" name="systemInfo" frameborder=1>\n<frameset cols="50\%,50\%">\n<frame src="oType" name="oType" frameborder=1>\n<frame src="blank" name="oInst" frameborder=1>\n</frameset>\n</frameset>\n</html>'
|
|
|
+ frameset = '<frameset rows="35\%,65\%">\n<frame src="systemInfo" name="systemInfo" frameborder=1>\n<frameset cols="50\%,50\%">\n<frame src="oMenu" name="oType" frameborder=1>\n<frame src="blank" name="oInst" frameborder=1>\n</frameset>\n</frameset>\n</html>'
|
|
|
#print "%s|Index Frame Accessed" % self.timeStamp()
|
|
|
# print str(simbase.air.doid2do)
|
|
|
replyTo.respond('<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">\n<html lang="en">\n<head>\n<title>AI HTTP Interface: %s</title>\n</head>\n%s' % (self.localHostName, frameset))
|