Prechádzať zdrojové kódy

Added various magic words to the interface. Will need to split base functions and product specific functions in the near future.

Joe Hager 18 rokov pred
rodič
commit
2fc3c4873c
1 zmenil súbory, kde vykonal 143 pridanie a 4 odobranie
  1. 143 4
      direct/src/http/webAIInspector.py

+ 143 - 4
direct/src/http/webAIInspector.py

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