Example #1
0
class Entry(DirectObject):
    def __init__(self, placeholder, pos, on_enter, focus=False, sort_order=0):
        """
        Object of a simple entry field
        @param placeholder: text to appear in textbox automatically
        @type placeholder: string
        @param pos: where to place the textbox
        @type pos: (float, float, float)
        @param on_enter: function to call upon them submitting a response
        @type on_enter: function
        @param focus: Should the entry auto-focus?
        @type focus: bool
        @param sort_order: Where should Entry display? (Alert is at 1000)
        @type sort_order: int
        """
        DirectObject.__init__(self)
        self.accept('mouse1', self.click_out)
        self.placeholder = placeholder
        self.on_enter = on_enter
        self.entry = DirectEntry(initialText=self.placeholder,
                                 scale=0.05,
                                 focus=focus,
                                 focusOutCommand=self.focus_out,
                                 focusInCommand=self.focus_in,
                                 pos=pos,
                                 sortOrder=sort_order)

    def focus_out(self):
        if self.entry.get() == "":
            self.entry.enterText(self.placeholder)
        else:
            # they typed Something.
            # TODO validate
            self.on_enter(self.entry.get())

    def focus_in(self):
        self.entry.set("")

    def click_out(self):
        self.entry.setFocus()

    def destroy(self):
        self.entry.destroy()
        self.ignoreAll()
Example #2
0
class Fighter(DirectObject):
    def __init__(self):
        
        base.disableMouse()

        # Carga el fondo del juego
        self.bg = loader.loadModel("models/plane")
        self.bg.reparentTo(camera)
        self.bg.setPos(0, 200, 0)
        self.bg.setScale(300, 0, 146)
        self.bg.setTexture(loader.loadTexture("models/Backgrounds/farback.png"), 1)
        
        # Inicializa el gestor de teclado y los objetos del juego
        self.inputManager = InputManager()

        # Inicializa el menu del juego
        self.inicializarMenu()

        self.marcador = None
        self.barraEnergia = None
        self.marcadorFinalNP = None
        self.entrada = None
        self.rankingNP = None

        self.mostrarMenuJuego()
        self.accept("m", self.cambiarMenuJuego)
        self.accept("q", self.salir)

    # Inicializa el menu
    def inicializarMenu(self):
        self.menuGraphics = loader.loadModel("models/MenuGraphics")
        self.fonts = {"silver" : loader.loadFont("fonts/LuconSilver"),
                      "blue" : loader.loadFont("fonts/LuconBlue"),
                      "orange" : loader.loadFont("fonts/LuconOrange")}
        self.menu = Menu(self.menuGraphics, self.fonts, self.inputManager)
        self.menu.initMenu([0, None, 
            ["Nueva Partida", "Salir"],
            [[self.nuevaPartida], [self.salir]],
            [[None], [None]]])

    # Comienza una partida
    def nuevaPartida(self):
        
        if (not self.marcadorFinalNP is None):
            self.marcadorFinalNP.detachNode()
            self.marcadorFinalNP.remove()

        if (not self.rankingNP is None):
            self.rankingNP.detachNode()
            self.rankingNP.remove()

        self.ship = Ship(self.inputManager)
        self.mostrarInfo()

        taskMgr.add(self.actualizarInfo, "Actualizar Puntuacion")

    # Inicializa y muestra el marcador del jugador
    def mostrarInfo(self):

        self.marcador = TextNode("Marcador")
        self.marcador.setText("Puntos: " + str(self.ship.puntos))
        self.marcador.setCardColor(0, 0, 0, 1)
        self.marcador.setCardDecal(True)
        self.marcador.setCardAsMargin(0.4, 0.4, 0.4, 0.4)
        self.marcadorNP = aspect2d.attachNewNode(self.marcador)
        self.marcadorNP.reparentTo(base.a2dTopLeft)
        self.marcadorNP.setPos(0.02, 0, -0.05)
        self.marcadorNP.setScale(0.07)

        self.barraEnergia = DirectWaitBar(text = "Energia", value = 5, 
            range = 5, scale = 0.3, pos = (0, 0, 0.95))

    # Actualiza la puntuacion del jugador en pantalla
    def actualizarInfo(self, tarea):
        self.marcador.setText("Puntos: " + str(self.ship.puntos))
        self.barraEnergia["value"] = self.ship.vida
        self.barraEnergia.setValue()

        # Termina la partida
        if (self.ship.terminarPartida):
            self.terminarPartida()
            return tarea.done

        return tarea.cont

    # Termina partida liberando recursos para poder empezar una nueva
    # sin reiniciar el juego
    def terminarPartida(self):
        # Solicita al usuario un nombre para la tabla de puntuaciones
        self.entrada = DirectEntry(width = 15, numLines = 1, scale = 0.07,
            cursorKeys = 1, frameSize = (0, 15, 0, 1), command = self.almacenarPuntuacion,
            pos = (-0.3, 0, 0.1), focus = True, text_pos = (0.2, 0.2))
        self.puntos = self.ship.puntos

        self.ship.ship.detachNode()
        self.ship.ship.remove()
        taskMgr.remove("Mover Nave")
        taskMgr.remove("Generar Enemigos")
        taskMgr.remove("Comprobar Impactos")
        taskMgr.remove("Actualizar Puntuacion")
        taskMgr.remove("Explosionar*")

        self.mostrarFinPartida()

        # Libera los recursos de la partida que ha terminado
        self.ship.eliminarObjetos()
        del self.ship
        del self.menuGraphics
        del self.menu
        self.marcadorNP.detachNode()
        self.marcadorNP.remove()
        self.barraEnergia.destroy()
        del self.marcador
        del self.barraEnergia

        #self.inicializarMenu()

    # Almacena la puntuacion del jugador
    def almacenarPuntuacion(self, valor):

        self.crearBDD()

        db = sqlite3.connect("datos.db")
        cursor = db.cursor()
        parametros = (valor, self.puntos)
        cursor.execute("insert into puntuaciones values (?, ?)", parametros)
        db.commit()
        cursor.close()

        self.entrada.destroy()

        self.mostrarTopPuntuacion()

        self.inicializarMenu()

    # Crea la Base de Datos si no existe ya
    def crearBDD(self):
        db = sqlite3.connect("datos.db")
        cursor = db.cursor()
        args = ("puntuaciones",)
        cursor.execute("select name from sqlite_master where name = ?", args)
        if len(cursor.fetchall()) == 0:
            cursor.execute("create table puntuaciones (nombre text, puntuacion numeric)")
            db.commit()
        cursor.close()

    # Muestra las 10 mejores puntuaciones
    def mostrarTopPuntuacion(self):
        # Extrae las 10 mejores puntuaciones de la base de datos
        db = sqlite3.connect("datos.db")
        cursor = db.cursor()
        cursor.execute("select nombre, puntuacion from puntuaciones order by puntuacion desc limit 10")
        puntuaciones = cursor.fetchall()
        cursor.close()
        resultado = "-- MEJORES PUNTUACIONES --\n-Jugador-  -Puntuacion-\n\n"
        for nombre, puntuacion in puntuaciones:
            resultado += nombre + " " + str(puntuacion) + "\n"

        # Muestra las 10 mejores puntuaciones
        self.ranking = TextNode("Ranking")
        self.ranking.setText(resultado)
        self.ranking.setCardColor(0, 0, 0, 1)
        self.ranking.setCardDecal(True)
        self.ranking.setCardAsMargin(0.4, 0.4, 0.4, 0.4)
        self.rankingNP = aspect2d.attachNewNode(self.ranking)
        self.rankingNP.reparentTo(base.a2dTopLeft)
        self.rankingNP.setPos(1, 0, -1)
        self.rankingNP.setScale(0.07)

    # Muestra el mensaje de fin de partida
    def mostrarFinPartida(self):
        self.marcadorFinal = TextNode("Marcador Final")
        self.marcadorFinal.setText("Game Over!\nPuntuacion: " + str(self.ship.puntos) +"\n\n" +
            "Escribe tu nombre:")
        self.marcadorFinal.setCardColor(0, 0, 0, 1)
        self.marcadorFinal.setCardDecal(True)
        self.marcadorFinal.setCardAsMargin(0.4, 0.4, 0.4, 0.4)
        self.marcadorFinalNP = aspect2d.attachNewNode(self.marcadorFinal)
        self.marcadorFinalNP.setPos(-0.3, 0, 0.5)
        self.marcadorFinalNP.setScale(0.07)

    # Muestra un menu con las opciones durante el juego
    def mostrarMenuJuego(self):
        self.textoMenu = {}
        self.textoMenu["titulo"] = OnscreenText(text = "", pos = (0, 0.92), scale = 0.08, 
            fg = (1, 1, 1, 1), bg = (0, 0, 1, 0.7))
        self.textoMenu["descripcion"] = OnscreenText(text = "", pos = (0, 0.84), scale = 0.05,
            fg = (1, 1, 0, 1), bg = (0, 0, 0, 0.5))
        self.textoMenu["opciones"] = OnscreenText(text = "", pos = (-1.3, 0), scale = 0.05,
            fg = (1, 1, 1, 1), bg = (1, 0.3, 0, 0.6), align=TextNode.ALeft, wordwrap = 15)

        self.textoMenu["opciones"].setText("** OPCIONES **\n" + 
            "m = ocultar menu\n" +
            "q = salir")

        # Inicialmente el menu se deja oculto
        for linea in self.textoMenu.values():
            linea.hide()

    # Muestra / Oculta el menu de juego
    def cambiarMenuJuego(self):
        for linea in self.textoMenu.values():
            if linea.isHidden():
                linea.show()
            else:
                linea.hide()

    # Sale del juego
    def salir(self):
        print("Saliendo . . .")
        sys.exit()
Example #3
0
class DeveloperConsole(InteractiveInterpreter, DirectObject):
  """The name says it all."""
  def __init__(self):
    sys.stdout = PseudoFile(self.writeOut)
    sys.stderr = PseudoFile(self.writeErr)
    tpErr = TextProperties()
    tpErr.setTextColor(1, 0.5, 0.5, 1)
    TextPropertiesManager.getGlobalPtr().setProperties("err", tpErr)
    #font = loader.loadFont("cmss12")
    self.frame = DirectFrame(parent = base.a2dTopCenter, text_align = TextNode.ALeft, text_pos = (-base.getAspectRatio() + TEXT_MARGIN[0], TEXT_MARGIN[1]), text_scale = 0.05, text_fg = (1, 1, 1, 1), frameSize = (-2.0, 2.0, -0.5, 0.0), frameColor = (0, 0, 0, 0.5), text = '')#, text_font = font)
    self.entry = DirectEntry(parent = base.a2dTopLeft, command = self.command, scale = 0.05, width = 1000.0, pos = (-0.02, 0, -0.48), relief = None, text_pos = (1.5, 0, 0), text_fg = (1, 1, 0.5, 1), rolloverSound = None, clickSound = None)#, text_font = font)
    self.otext = OnscreenText(parent = self.entry, scale = 1, align = TextNode.ALeft, pos = (1, 0, 0), fg = (1, 1, 0.5, 1), text = ':')#, font = font)
    self.lines = [''] * 9
    self.commands = []  # All previously sent commands
    self.cscroll = None # Index of currently navigated command, None if current
    self.command = ''   # Currently entered command
    self.block = ''     # Temporarily stores a block of commands
    self.hide()
    self.initialized = False
  
  def prevCommand(self):
    if self.hidden: return
    if len(self.commands) == 0: return
    if self.cscroll == None:
      self.cscroll = len(self.commands)
      self.command = self.entry.get()
    elif self.cscroll <= 0:
      return
    else:
      self.commands[self.cscroll] = self.entry.get()
    self.cscroll -= 1
    self.entry.set(self.commands[self.cscroll])
    self.entry.setCursorPosition(len(self.commands[self.cscroll]))
  
  def nextCommand(self):
    if self.hidden: return
    if len(self.commands) == 0: return
    if self.cscroll == None: return
    self.commands[self.cscroll] = self.entry.get()
    self.cscroll += 1
    if self.cscroll >= len(self.commands):
      self.cscroll = None
      self.entry.set(self.command)
      self.entry.setCursorPosition(len(self.command))
    else:
      self.entry.set(self.commands[self.cscroll])
      self.entry.setCursorPosition(len(self.commands[self.cscroll]))

  def writeOut(self, line, copy = True):
    if copy: sys.__stdout__.write(line)
    lines = line.split('\n')
    firstline = lines.pop(0)
    self.lines[-1] += firstline
    self.lines += lines
    self.frame['text'] = '\n'.join(self.lines[-9:])

  def writeErr(self, line, copy = True):
    if copy: sys.__stderr__.write(line)
    line = '\1err\1%s\2' % line
    lines = line.split('\n')
    firstline = lines.pop(0)
    self.lines[-1] += firstline
    self.lines += lines
    self.frame['text'] = '\n'.join(self.lines[-9:])

  def command(self, text):
    if not self.hidden:
      self.cscroll = None
      self.command = ''
      self.entry.set('')
      self.entry['focus'] = True
      self.writeOut(self.otext['text'] + ' ' + text + '\n', False)
      if text != '' and (len(self.commands) == 0 or self.commands[-1] != text):
        self.commands.append(text)
      
      # Insert plugins into the local namespace
      locals = __main__.__dict__
      #locals['manager'] = self.manager
      #for plugin in self.manager.named.keys():
      #  locals[plugin] = self.manager.named[plugin]
      locals['panda3d'] = panda3d
      
      # Run it and print the output.
      if not self.initialized:
        InteractiveInterpreter.__init__(self, locals = locals)
        self.initialized = True
      try:
        if self.runsource(self.block + '\n' + text) and text != '':
          self.otext['text'] = '.'
          self.block += '\n' + text
        else:
          self.otext['text'] = ':'
          self.block = ''      
      except Exception: # Not just "except", it will also catch SystemExit
        # Whoops! Print out a traceback.
        self.writeErr(traceback.format_exc())

  def toggle(self):
    if self.hidden:
      self.show()
    else:
      self.hide()

  def show(self):
    self.accept('arrow_up', self.prevCommand)
    self.accept('arrow_up-repeat', self.prevCommand)
    self.accept('arrow_down', self.nextCommand)
    self.accept('arrow_down-repeat', self.nextCommand)
    self.hidden = False
    self.entry['focus'] = True
    self.frame.show()
    self.entry.show()
    self.otext.show()

  def hide(self):
    self.ignoreAll()
    self.hidden = True
    self.entry['focus'] = False
    self.frame.hide()
    self.entry.hide()
    self.otext.hide()

  def destroy(self):
    sys.stdout = sys.__stdout__
    sys.stderr = sys.__stderr__
    self.ignoreAll()
    self.frame.destroy()
    self.entry.destroy()
    self.otext.destroy()
Example #4
0
class DeveloperConsole(InteractiveInterpreter, DirectObject):
    """The name says it all."""
    def __init__(self, manager, xml):
        sys.stdout = PseudoFile(self.writeOut)
        sys.stderr = PseudoFile(self.writeErr)
        tpErr = TextProperties()
        tpErr.setTextColor(1, 0.5, 0.5, 1)
        TextPropertiesManager.getGlobalPtr().setProperties("err", tpErr)
        self.manager = manager
        font = loader.loadFont("cmss12")
        self.frame = DirectFrame(parent=base.a2dTopCenter,
                                 text_align=TextNode.ALeft,
                                 text_pos=(-base.getAspectRatio() +
                                           TEXT_MARGIN[0], TEXT_MARGIN[1]),
                                 text_scale=0.05,
                                 text_fg=(1, 1, 1, 1),
                                 frameSize=(-2.0, 2.0, -0.5, 0.0),
                                 frameColor=(0, 0, 0, 0.5),
                                 text='',
                                 text_font=font)
        self.entry = DirectEntry(parent=base.a2dTopLeft,
                                 command=self.command,
                                 scale=0.05,
                                 width=1000.0,
                                 pos=(-0.02, 0, -0.48),
                                 relief=None,
                                 text_pos=(1.5, 0, 0),
                                 text_fg=(1, 1, 0.5, 1),
                                 rolloverSound=None,
                                 clickSound=None,
                                 text_font=font)
        self.otext = OnscreenText(parent=self.entry,
                                  scale=1,
                                  align=TextNode.ALeft,
                                  pos=(1, 0, 0),
                                  fg=(1, 1, 0.5, 1),
                                  text=':',
                                  font=font)
        self.lines = [''] * 9
        self.commands = []  # All previously sent commands
        self.cscroll = None  # Index of currently navigated command, None if current
        self.command = ''  # Currently entered command
        self.block = ''  # Temporarily stores a block of commands
        self.hide()
        self.initialized = False

    def prevCommand(self):
        if self.hidden: return
        if len(self.commands) == 0: return
        if self.cscroll == None:
            self.cscroll = len(self.commands)
            self.command = self.entry.get()
        elif self.cscroll <= 0:
            return
        else:
            self.commands[self.cscroll] = self.entry.get()
        self.cscroll -= 1
        self.entry.set(self.commands[self.cscroll])
        self.entry.setCursorPosition(len(self.commands[self.cscroll]))

    def nextCommand(self):
        if self.hidden: return
        if len(self.commands) == 0: return
        if self.cscroll == None: return
        self.commands[self.cscroll] = self.entry.get()
        self.cscroll += 1
        if self.cscroll >= len(self.commands):
            self.cscroll = None
            self.entry.set(self.command)
            self.entry.setCursorPosition(len(self.command))
        else:
            self.entry.set(self.commands[self.cscroll])
            self.entry.setCursorPosition(len(self.commands[self.cscroll]))

    def writeOut(self, line, copy=True):
        if copy: sys.__stdout__.write(line)
        lines = line.split('\n')
        firstline = lines.pop(0)
        self.lines[-1] += firstline
        self.lines += lines
        self.frame['text'] = '\n'.join(self.lines[-9:])

    def writeErr(self, line, copy=True):
        if copy: sys.__stderr__.write(line)
        line = '\1err\1%s\2' % line
        lines = line.split('\n')
        firstline = lines.pop(0)
        self.lines[-1] += firstline
        self.lines += lines
        self.frame['text'] = '\n'.join(self.lines[-9:])

    def command(self, text):
        if not self.hidden:
            self.cscroll = None
            self.command = ''
            self.entry.set('')
            self.entry['focus'] = True
            self.writeOut(self.otext['text'] + ' ' + text + '\n', False)
            if text != '' and (len(self.commands) == 0
                               or self.commands[-1] != text):
                self.commands.append(text)

            # Insert plugins into the local namespace
            locals = __main__.__dict__
            locals['manager'] = self.manager
            for plugin in self.manager.named.keys():
                locals[plugin] = self.manager.named[plugin]
            locals['panda3d'] = panda3d

            # Run it and print the output.
            if not self.initialized:
                InteractiveInterpreter.__init__(self, locals=locals)
                self.initialized = True
            try:
                if self.runsource(self.block + '\n' + text) and text != '':
                    self.otext['text'] = '.'
                    self.block += '\n' + text
                else:
                    self.otext['text'] = ':'
                    self.block = ''
            except Exception:  # Not just "except", it will also catch SystemExit
                # Whoops! Print out a traceback.
                self.writeErr(traceback.format_exc())

    def toggle(self):
        if self.hidden:
            self.show()
        else:
            self.hide()

    def show(self):
        self.accept('arrow_up', self.prevCommand)
        self.accept('arrow_up-repeat', self.prevCommand)
        self.accept('arrow_down', self.nextCommand)
        self.accept('arrow_down-repeat', self.nextCommand)
        self.hidden = False
        self.entry['focus'] = True
        self.frame.show()
        self.entry.show()
        self.otext.show()

    def hide(self):
        self.ignoreAll()
        self.hidden = True
        self.entry['focus'] = False
        self.frame.hide()
        self.entry.hide()
        self.otext.hide()

    def destroy(self):
        sys.stdout = sys.__stdout__
        sys.stderr = sys.__stderr__
        self.ignoreAll()
        self.frame.destroy()
        self.entry.destroy()
        self.otext.destroy()
Example #5
0
class DeveloperConsole(InteractiveInterpreter, DirectObject):
    def __init__(self):
        sys.stdout = PseudoFile(self.write_out)
        sys.stderr = PseudoFile(self.write_err)
        tp_err = TextProperties()
        tp_err.setTextColor(1, 0.5, 0.5, 1)
        TextPropertiesManager.getGlobalPtr().setProperties('err', tp_err)
        font = loader.loadFont('cmss12')
        self.frame = DirectFrame(parent=base.a2dTopCenter,
                                 text_align=TextNode.ALeft,
                                 text_pos=(base.a2dLeft + TEXT_MARGIN[0],
                                           TEXT_MARGIN[1]),
                                 text_scale=0.05,
                                 text_fg=(1, 1, 1, 1),
                                 frameSize=(-2.0, 2.0, -1, 0.0),
                                 frameColor=(0, 0, 0, 0.5),
                                 text='',
                                 text_font=font,
                                 sortOrder=4)
        self.entry = DirectEntry(parent=base.a2dTopLeft,
                                 command=self.command,
                                 scale=0.05,
                                 width=1000.0,
                                 pos=(-0.02, 0, -0.98),
                                 relief=None,
                                 text_pos=(1.5, 0, 0),
                                 text_fg=(1, 1, 0.5, 1),
                                 rolloverSound=None,
                                 clickSound=None,
                                 text_font=font)
        self.otext = OnscreenText(parent=self.entry,
                                  scale=1,
                                  align=TextNode.ALeft,
                                  pos=(1, 0, 0),
                                  fg=(1, 1, 0.5, 1),
                                  text=':',
                                  font=font)
        self.lines = [''] * 19
        self.commands = []  # All previously sent commands
        self.cscroll = None  # Index of currently navigated command, None if current
        self.command = ''  # Currently entered command
        self.block = ''  # Temporarily stores a block of commands
        self.hide()
        self.initialized = False

    def prev_command(self):
        if self.hidden:
            return
        if len(self.commands) == 0:
            return
        if self.cscroll is None:
            self.cscroll = len(self.commands)
            self.command = self.entry.get()
        elif self.cscroll <= 0:
            return
        else:
            self.commands[self.cscroll] = self.entry.get()
        self.cscroll -= 1
        self.entry.set(self.commands[self.cscroll])
        self.entry.setCursorPosition(len(self.commands[self.cscroll]))

    def next_command(self):
        if self.hidden:
            return
        if len(self.commands) == 0:
            return
        if self.cscroll is None:
            return
        self.commands[self.cscroll] = self.entry.get()
        self.cscroll += 1
        if self.cscroll >= len(self.commands):
            self.cscroll = None
            self.entry.set(self.command)
            self.entry.setCursorPosition(len(self.command))
        else:
            self.entry.set(self.commands[self.cscroll])
            self.entry.setCursorPosition(len(self.commands[self.cscroll]))

    def write_out(self, line, copy=True):
        if copy:
            sys.__stdout__.write(line)
        lines = line.split('\n')
        firstline = lines.pop(0)
        self.lines[-1] += firstline
        self.lines += lines
        self.frame['text'] = '\n'.join(self.lines[-19:])

    def write_err(self, line, copy=True):
        if copy:
            sys.__stderr__.write(line)
        line = '\1err\1%s\2' % line
        lines = line.split('\n')
        firstline = lines.pop(0)
        self.lines[-1] += firstline
        self.lines += lines
        self.frame['text'] = '\n'.join(self.lines[-19:])

    def command(self, text):
        if self.hidden:
            return

        self.cscroll = None
        self.command = ''
        self.entry.set('')
        self.entry['focus'] = True
        self.write_out(self.otext['text'] + ' ' + text + '\n', False)
        if text != '' and (len(self.commands) == 0
                           or self.commands[-1] != text):
            self.commands.append(text)

        if not self.initialized:
            InteractiveInterpreter.__init__(self)
            self.initialized = True
        try:
            if self.runsource(self.block + '\n' + text) and text != '':
                self.otext['text'] = '.'
                self.block += '\n' + text
            else:
                self.otext['text'] = ':'
                self.block = ''
        except Exception:
            self.write_err(traceback.format_exc())

    def toggle(self):
        if self.hidden:
            self.show()
        else:
            self.hide()

    def show(self):
        self.accept('arrow_up', self.prev_command)
        self.accept('arrow_up-repeat', self.prev_command)
        self.accept('arrow_down', self.next_command)
        self.accept('arrow_down-repeat', self.next_command)
        self.hidden = False
        self.entry['focus'] = True
        self.frame.show()
        self.entry.show()
        self.otext.show()

    def hide(self):
        self.ignoreAll()
        self.hidden = True
        self.entry['focus'] = False
        self.entry.set(self.entry.get()[:-1])
        self.frame.hide()
        self.entry.hide()
        self.otext.hide()

    def destroy(self):
        sys.stdout = sys.__stdout__
        sys.stderr = sys.__stderr__
        self.ignoreAll()
        self.frame.destroy()
        self.entry.destroy()
        self.otext.destroy()
Example #6
0
class ChatBox(DirectObject):
    
    MESSAGE_LIFE = 10
    MAX_NUM_MESSAGES = 15
    
    (TYPE_GLOBAL,
     TYPE_TEAM,
     TYPE_CONSOLE) = range(3)
     
    messageTypeToPrefix = { TYPE_GLOBAL : 'Global:', 
                            TYPE_TEAM : 'Team:',
                            TYPE_CONSOLE : 'Console' }
    
    def __init__(self):
        self.textNodes = []
        self.messageType = None
        
        self.rootFrame = DirectFrame(pos = (0.03, 0, 0.2),
                                 frameColor = (0, 0, 0, 0),
                                 frameSize = (0, 1, 0, 1),
                                 parent = base.a2dBottomLeft)
        self.rootFrame.setBin('fixed', GUIOrder.ORDER[GUIOrder.CHAT])
        
        self.entryFrame = DirectFrame(pos = (0, 0, 0),
                                 frameColor = (0, 0, 0, 0.1),
                                 frameSize = (0, 1, 0, 0.1),
                                 parent = self.rootFrame)
        
        self.chatarea = DirectEntry(width = 27,
                                    scale = Settings.CHAT_HEIGHT,
                                    pos = (0, 0, 0),
                                    frameColor = (0, 0, 0, 0),
                                    text_fg = (1, 1, 1, 1),
                                    numLines = 1,
                                    cursorKeys = 1,
                                    rolloverSound = None,
                                    clickSound = None,
                                    focus = 0,
                                    command = self.OnChatEntered,
                                    parent = self.entryFrame)
        
        self.typeText = OnscreenText(text = '', 
                                     pos = (0, Settings.CHAT_HEIGHT + 0.01), 
                                     scale = Settings.CHAT_HEIGHT,
                                     fg = (1, 1, 1, 1),
                                     mayChange = True,
                                     align = TextNode.ALeft,
                                     parent = self.entryFrame)
        
        self.displayFrame = DirectFrame(pos = (0, 0, 0.1),
                                 frameColor = (0, 0, 0, 0),
                                 frameSize = (0, 1, 0, 0.42),
                                 parent = self.rootFrame)
        
        self.chatarea.enterText('')
        self.entryFrame.hide()
        self.chatarea['focus'] = 0
        self.chatarea.setFocus()    
        
    def OnChatEntered(self, enteredText):
        enteredText = enteredText.strip()
        self.Hide()
        if(len(enteredText) > 0):
            ChatEnteredEvent(self.messageType, enteredText).Fire()
        
    def AddMessage(self, prefix, prefixColor, message):
        parent = self.displayFrame.attachNewNode('messageParent')
        
        prefixTextNode = TextNode('prefixMessage')
        prefixTextNode.setText(prefix)
        prefixTextNode.setTextColor(prefixColor)
        prefixTextNode.setShadow(0.05, 0.05)
        prefixTextNode.setShadowColor(Globals.COLOR_BLACK)
        prefixTextNodePath = parent.attachNewNode(prefixTextNode)
        prefixTextNodePath.setScale(Settings.CHAT_HEIGHT)
        
        messageTextNode = TextNode('prefixMessage')
        messageTextNode.setText(message)
        messageTextNode.setTextColor(1, 1, 1, 1)
        messageTextNode.setShadow(0.05, 0.05)
        messageTextNode.setShadowColor(Globals.COLOR_BLACK)
        messageTextNodePath = parent.attachNewNode(messageTextNode)
        messageTextNodePath.setScale(Settings.CHAT_HEIGHT)
        messageTextNodePath.setPos(Vec3(prefixTextNode.calcWidth(prefix) * Settings.CHAT_HEIGHT, 0, 0))
        
        taskMgr.remove('HideMessageLog')
        taskMgr.doMethodLater(ChatBox.MESSAGE_LIFE, self.HideMessageLog, 'HideMessageLog') 
        self.ShowMessageLog()
        
        self.textNodes.append(parent)
        
        if(len(self.textNodes) > ChatBox.MAX_NUM_MESSAGES):
            self.RemoveMessage(self.textNodes[0])
            
        self.RedrawMessages()
        
    def RedrawMessages(self):
        n = len(self.textNodes)
        for i, textNode in enumerate(self.textNodes):
            LerpPosInterval(textNode, 0.5, (0, 0, (n-i) * (Settings.CHAT_HEIGHT + 0.01))).start()
            
    def RemoveMessage(self, textNode):
        self.textNodes.remove(textNode)
        textNode.removeNode()
        
    def HideMessageLog(self, task = None):
        self.displayFrame.hide()
        
    def ShowMessageLog(self):
        self.displayFrame.show()
        
    def Hide(self):
        self.chatarea.enterText('')
        self.entryFrame.hide()
        self.chatarea['focus'] = 0
        self.chatarea.setFocus()
        self.HideMessageLog()
        ChatCloseEvent().Fire()
        
    def Show(self, messageType):
        self.messageType = messageType
        self.entryFrame.show()
        self.chatarea['focus'] = 1
        self.chatarea.setFocus()
        self.typeText.setText(ChatBox.GetPrefix(self.messageType))
        self.ShowMessageLog()
        ChatOpenEvent().Fire()
        
    def EnableKeyboardListening(self):
        self.acceptOnce('escape', self.Hide)
        
    def DisableKeyboardListening(self):
        self.ignoreAll()
        
    @staticmethod
    def GetPrefix(messageType):
        return ChatBox.messageTypeToPrefix[messageType]
    
    def Destroy(self):
        taskMgr.remove('HideMessageLog')
        self.rootFrame.destroy()
        self.entryFrame.destroy()
        self.chatarea.destroy()
        self.typeText.destroy()
        self.displayFrame.destroy()
        self.ignoreAll()
        
Example #7
0
class Login():
    def __init__(self, showbase):
        self.showbase = showbase

        self.background = DirectFrame(
            frameSize=(-1, 1, -1, 1),
            frameTexture='media/gui/login/bg.png',
            parent=self.showbase.render2d,
        )

        ### CONFIG LOADER ###
        config = ConfigParser.RawConfigParser()
        config.read('master.cfg')
        self.LOGIN_IP = config.get('MASTER SERVER CONNECTION', 'masterIp')
        self.LOGIN_PORT = config.getint('MASTER SERVER CONNECTION',
                                        'masterPort')

        config = ConfigParser.RawConfigParser()
        config.read('client.cfg')
        self.storeUsername = config.getint('USERDATA', 'storeUsername')
        if self.storeUsername == 1:
            self.username = config.get('USERDATA', 'username')
        else:
            self.username = ''
        self.storePassword = config.getint('USERDATA', 'storePassword')
        if self.storePassword == 1:
            self.password = config.get('USERDATA', 'password')
        else:
            self.password = ''
        ### CONFIG END ###

        self.loginScreen("Press 'Enter' to login")
        # draws the login screen

        self.usernameBox['focus'] = 1
        # sets the cursor to the username field by default

        self.showbase.accept('tab', self.cycleLoginBox)
        self.showbase.accept('shift-tab', self.cycleLoginBox)
        # enables the user to cycle through the text fields with the tab key
        # this is a standard feature on most login forms

        self.showbase.accept('enter', self.attemptLogin)
        # submits the login form, or you can just click the Login button

        # checking variable to stop multiple presses of the button spawn multiple tasks
        self.requestAttempt = False

        self.showbase.authCon = Client(self.showbase,
                                       self.LOGIN_IP,
                                       self.LOGIN_PORT,
                                       compress=True)
        if not self.showbase.authCon.getConnected():
            self.updateStatus(
                "Could not connect to the Login server\nOFFLINE MODE")
            self.showbase.online = False

    def updateConfig(self):
        config = ConfigParser.RawConfigParser()
        config.read('client.cfg')
        config.set('USERDATA', 'storeUsername',
                   self.usernameStoreBox["indicatorValue"])
        config.set('USERDATA', 'storePassword',
                   self.passwordStoreBox["indicatorValue"])
        if self.usernameStoreBox["indicatorValue"] == 1:
            config.set('USERDATA', 'username', self.usernameBox.get())
        if self.passwordStoreBox["indicatorValue"] == 1:
            config.set('USERDATA', 'password', self.passwordBox.get())
        with open('client.cfg', 'wb') as configfile:
            config.write(configfile)

    def loginScreen(self, statusText):
        # creates a basic login screen that asks for a username/password

        boxloc = Vec3(0.0, 0.0, 0.0)
        # all items in the login form will have a position relative to this
        # this makes it easier to shift the entire form around once we have
        # some graphics to display with it without having to change the
        # positioning of every form element

        # p is the position of the form element relative to the boxloc
        # coordinates set above it is changed for every form element
        p = boxloc + Vec3(-0.22, 0.09, 0.0)
        self.usernameText = OnscreenText(text="Username:"******"Username: "******"",
                                       pos=p,
                                       scale=.04,
                                       initialText=self.username,
                                       numLines=1)
        # Username textbox where you type in your username

        p = boxloc + Vec3(0.4, 0.0, 0.09)
        self.usernameStoreBox = DirectCheckButton(
            text="Save Username?",
            pos=p,
            scale=.04,
            indicatorValue=self.storeUsername)
        # Toggle to save/not save your username

        p = boxloc + Vec3(-0.22, 0.0, 0.0)
        self.passwordText = OnscreenText(text="Password:"******"Password: "******"",
                                       pos=p,
                                       scale=.04,
                                       initialText=self.password,
                                       numLines=1,
                                       obscured=1)
        # Password textbox where you type in your password
        # Note - obscured = 1 denotes that all text entered will be replaced
        # with a * like a standard password box

        p = boxloc + Vec3(0.4, 0.0, 0.0)
        self.passwordStoreBox = DirectCheckButton(
            text="Save Password?",
            pos=p,
            scale=.04,
            indicatorValue=self.storePassword)
        # Toggle to save/not save your username

        p = boxloc + Vec3(0, 0, -0.090)
        self.loginButton = DirectButton(text="Login",
                                        pos=p,
                                        scale=0.048,
                                        relief=DGG.GROOVE,
                                        command=self.attemptLogin)
        # The 'Quit' button that will trigger the Quit function
        # when clicked

        p = boxloc + Vec3(0.95, 0, -0.9)
        self.createAccButton = DirectButton(text="Create Account",
                                            scale=0.050,
                                            pos=p,
                                            relief=DGG.GROOVE,
                                            command=self.attemptCreateAccount)
        # Made a quick button for adding accounts. Its fugly

        p = boxloc + Vec3(1.20, 0, -0.9)
        self.quitButton = DirectButton(text="Quit",
                                       pos=p,
                                       scale=0.048,
                                       relief=DGG.GROOVE,
                                       command=self.showbase.quit)
        # The 'Quit' button that will trigger the Quit function
        # when clicked

        p = boxloc + Vec3(0, -0.4, 0)
        self.statusText = OnscreenText(text=statusText,
                                       pos=p,
                                       scale=0.043,
                                       fg=(1, 0.5, 0, 1),
                                       align=TextNode.ACenter)
        # A simple text object that you can display an error/status messages
        # to the user

    def updateStatus(self, statusText):
        self.statusText.setText(statusText)
        # all this does is change the status text.

    def checkBoxes(self):
        # checks to make sure the user inputed a username and password:
        #       if they didn't it will spit out an error message
        self.updateStatus("")
        if self.usernameBox.get() == "":
            if self.passwordBox.get() == "":
                self.updateStatus(
                    "You must enter a username and password before logging in."
                )
            else:
                self.updateStatus("You must specify a username")
                self.passwordBox['focus'] = 0
                self.usernameBox['focus'] = 1
            return False
        elif self.passwordBox.get() == "":
            self.updateStatus("You must enter a password")
            self.usernameBox['focus'] = 0
            self.passwordBox['focus'] = 1
            return False
        # if both boxes are filled then return True
        return True

    def attemptLogin(self):
        if self.checkBoxes():
            self.showbase.username = self.usernameBox.get()
            self.updateStatus("Attempting to login...")
            self.request(self.usernameBox.get(), self.passwordBox.get(),
                         'client')

    def attemptCreateAccount(self):
        if self.checkBoxes():
            self.updateStatus("Attempting to create account and login...")
            self.request(self.usernameBox.get(), self.passwordBox.get(),
                         'create')

    def request(self, username, password, request):
        if not self.requestAttempt:
            # attempt to connect again if it failed on startup
            if self.showbase.authCon.getConnected():
                self.requestAttempt = True
                self.loginButton["state"] = DGG.DISABLED
                self.createAccButton["state"] = DGG.DISABLED
                self.showbase.authCon.sendData((request, (username, password)))
                self.showbase.username = username
                self.showbase.online = True
                self.showbase.taskMgr.doMethodLater(0.2, self.responseReader,
                                                    'Update Login')
            else:
                # client not connected to login/auth server so display message
                self.updateStatus("Offline Mode")
                self.showbase.username = username
                self.showbase.online = False
                self.updateConfig()
                self.showbase.startMainmenu()

    def responseReader(self, task):
        if task.time > 2.5:
            self.loginButton["state"] = DGG.NORMAL
            self.createAccButton["state"] = DGG.NORMAL
            self.updateStatus("Timeout from Login server")
            return task.done
        else:
            temp = self.showbase.authCon.getData()
            for package in temp:
                if len(package) == 2:
                    print "Received: " + str(package)
                    print "Connected to login server"
                    if package[0] == 'loginFailed':
                        print "Login failed: ", package[1]
                        if package[1] == 'username':
                            self.updateStatus("Username Doesnt Exist")
                            self.passwordBox.set("")
                            self.usernameBox.set("")
                            self.passwordBox['focus'] = 0
                            self.usernameBox['focus'] = 1
                        elif package[1] == 'password':
                            self.updateStatus("Password Incorrect")
                            self.passwordBox.set("")
                            self.usernameBox['focus'] = 0
                            self.passwordBox['focus'] = 1
                        elif package[1] == 'logged':
                            self.updateStatus("Username already logged in")
                        self.requestAttempt = False
                        self.loginButton["state"] = DGG.NORMAL
                        self.createAccButton["state"] = DGG.NORMAL
                        return task.done
                    elif package[0] == 'loginValid':
                        print "Login valid: ", package[1]
                        self.updateStatus(package[1])
                        self.updateConfig()
                        self.showbase.startMainmenu()
                        return task.done
                    elif package[0] == 'createFailed':
                        print "Create failed: ", package[1]
                        if package[1] == 'exists':
                            self.updateStatus("Username Already Exists")
                            self.passwordBox.set("")
                            self.usernameBox.set("")
                            self.passwordBox['focus'] = 0
                            self.usernameBox['focus'] = 1
                        self.requestAttempt = False
                        self.loginButton["state"] = DGG.NORMAL
                        self.createAccButton["state"] = DGG.NORMAL
                        return task.done
                    elif package[0] == 'createSuccess':
                        print "Create success", package[1]
                        self.updateStatus("Account Created Successfully")
                        self.requestAttempt = False
                        self.attemptLogin()
                        return task.done
            return task.cont

    def cycleLoginBox(self):
        # function is triggered by the tab key so you can cycle between
        # the two input fields like on most login screens
        if self.passwordBox['focus'] == 1:
            self.passwordBox['focus'] = 0
            self.usernameBox['focus'] = 1
        elif self.usernameBox['focus'] == 1:
            self.usernameBox['focus'] = 0
            self.passwordBox['focus'] = 1
        # IMPORTANT: When you change the focus to one of the text boxes,
        # you have to unset the focus on the other textbox.  If you do not
        # do this Panda seems to get confused.

    def hide(self):
        self.background.destroy()
        self.usernameText.destroy()
        self.usernameBox.destroy()
        self.usernameStoreBox.destroy()
        self.passwordText.destroy()
        self.passwordBox.destroy()
        self.passwordStoreBox.destroy()
        self.loginButton.destroy()
        self.quitButton.destroy()
        self.createAccButton.destroy()
        self.statusText.destroy()

        self.showbase.ignore('tab')
        self.showbase.ignore('shift-tab')
        self.showbase.ignore('enter')
Example #8
0
class TextEntry(object):
    """Enter Text using Keyboard, disable shortcut keys"""
    def __init__(self,
                 path,
                 mode,
                 command,
                 initialText='',
                 title='Title',
                 lines=1,
                 width=20,
                 x=0,
                 z=0,
                 font=5,
                 titleWidth=30,
                 textDelta=0.055):
        self.titleWidth = titleWidth
        self.textDelta = textDelta
        self.path = path
        self.mode = mode
        self.command = command
        self.initial = initialText
        self.title = title
        self.lines = lines
        self.width = width
        self.myEntry = None
        self.myTitle = None
        self.x = x
        self.z = z
        self.y = 0
        self.scale = 0.03
        self.font = '%s/star%s' % (self.path, font)
        self.myFont = loader.loadFont(self.font)
        self.setMyEntry()
        self.createTitleCard()

    def createTitleCard(self):
        """Default Title label"""
        self.myTitle = textonscreen.TextOnScreen(self.path, self.title, 0.025,
                                                 5, aspect2d)
        self.myTitle.writeTextToScreen(self.x + 0.01, 0,
                                       self.z + self.textDelta,
                                       self.titleWidth)
        self.myTitle.setTitleStyle()

    def setMyEntry(self):
        self.myEntry = DirectEntry(text='',
                                   scale=self.scale,
                                   command=self.onCommand,
                                   numLines=self.lines,
                                   width=self.width,
                                   pos=(self.x, self.y, self.z),
                                   entryFont=self.myFont,
                                   focusInCommand=self.onFocus,
                                   focusOutCommand=self.onOutFocus,
                                   frameColor=(0, 0, 0, .7),
                                   text_fg=(1, 1, 1, 1),
                                   initialText=self.initial,
                                   clickSound=self.mode.game.app.beep01Sound,
                                   rolloverSound=None)

    def onCommand(self, textEntered):
        self.setShortcuts()
        myMethod = getattr(self.mode, self.command)
        myMethod(textEntered)

    def destroy(self):
        self.myEntry.destroy()
        self.myTitle.destroy()

    def onFocus(self):
        self.ignoreShortcuts()
        self.mode.onEntryFocus()

    def onOutFocus(self):
        self.mode.setShortcuts()
        self.mode.onEntryOutFocus()

    def ignoreShortcuts(self):
        """Ignore all keyboard shortcuts created"""
        self.mode.game.app.ignoreAll()

    def setShortcuts(self):
        self.mode.setShortcuts()
Example #9
0
class Login():
	def __init__(self, showbase):
		self.showbase = showbase
		
		self.background = DirectFrame(
			frameSize = (-1, 1, -1, 1),
			frameTexture  = 'media/gui/login/bg.png',
			parent = self.showbase.render2d,
		)

		### CONFIG LOADER ###
		config = ConfigParser.RawConfigParser()
		config.read('master.cfg')
		self.LOGIN_IP = config.get('MASTER SERVER CONNECTION', 'masterIp')
		self.LOGIN_PORT = config.getint('MASTER SERVER CONNECTION', 'masterPort')

		config = ConfigParser.RawConfigParser()
		config.read('client.cfg')
		self.storeUsername = config.getint('USERDATA', 'storeUsername')
		if self.storeUsername == 1:
			self.username = config.get('USERDATA', 'username')
		else:
			self.username = ''
		self.storePassword = config.getint('USERDATA', 'storePassword')
		if self.storePassword == 1:
			self.password = config.get('USERDATA', 'password')
		else:
			self.password = ''
		### CONFIG END ###

		self.loginScreen("Press 'Enter' to login")
		# draws the login screen

		self.usernameBox['focus'] = 1
		# sets the cursor to the username field by default

		self.showbase.accept('tab', self.cycleLoginBox)
		self.showbase.accept('shift-tab', self.cycleLoginBox)
		# enables the user to cycle through the text fields with the tab key
		# this is a standard feature on most login forms

		self.showbase.accept('enter', self.attemptLogin)         
		# submits the login form, or you can just click the Login button
		
		# checking variable to stop multiple presses of the button spawn multiple tasks
		self.requestAttempt = False
		
		self.showbase.authCon = Client(self.showbase, self.LOGIN_IP, self.LOGIN_PORT, compress = True)
		if not self.showbase.authCon.getConnected():
			self.updateStatus("Could not connect to the Login server\nOFFLINE MODE")
			self.showbase.online = False

	def updateConfig(self):
		config = ConfigParser.RawConfigParser()
		config.read('client.cfg')
		config.set('USERDATA', 'storeUsername', self.usernameStoreBox["indicatorValue"])
		config.set('USERDATA', 'storePassword', self.passwordStoreBox["indicatorValue"])
		if self.usernameStoreBox["indicatorValue"] == 1:
			config.set('USERDATA', 'username', self.usernameBox.get())
		if self.passwordStoreBox["indicatorValue"] == 1:
			config.set('USERDATA', 'password', self.passwordBox.get())
		with open('client.cfg', 'wb') as configfile:
			config.write(configfile)
	
	def loginScreen(self, statusText):
		# creates a basic login screen that asks for a username/password
		
		boxloc = Vec3(0.0, 0.0, 0.0)
		# all items in the login form will have a position relative to this
		# this makes it easier to shift the entire form around once we have
		# some graphics to display with it without having to change the
		# positioning of every form element

		# p is the position of the form element relative to the boxloc
		# coordinates set above it is changed for every form element
		p = boxloc + Vec3(-0.22, 0.09, 0.0)                                 
		self.usernameText = OnscreenText(text = "Username:"******"Username: "******"", pos = p, scale=.04, initialText = self.username, numLines = 1)
		# Username textbox where you type in your username
		
		p = boxloc + Vec3(0.4, 0.0, 0.09)
		self.usernameStoreBox = DirectCheckButton(text = "Save Username?", pos = p, scale = .04, indicatorValue = self.storeUsername)
		# Toggle to save/not save your username
		
		p = boxloc + Vec3(-0.22, 0.0, 0.0)       
		self.passwordText = OnscreenText(text = "Password:"******"Password: "******"", pos = p, scale = .04, initialText = self.password, numLines = 1, obscured = 1)
		# Password textbox where you type in your password
		# Note - obscured = 1 denotes that all text entered will be replaced
		# with a * like a standard password box
		
		p = boxloc + Vec3(0.4, 0.0, 0.0)
		self.passwordStoreBox = DirectCheckButton(text = "Save Password?", pos = p, scale = .04, indicatorValue = self.storePassword)
		# Toggle to save/not save your username
		
		p = boxloc + Vec3(0, 0, -0.090)
		self.loginButton = DirectButton(text = "Login", pos = p, scale = 0.048, relief = DGG.GROOVE, command = self.attemptLogin)
		# The 'Quit' button that will trigger the Quit function
		# when clicked
		
		p = boxloc + Vec3(0.95, 0, -0.9)
		self.createAccButton = DirectButton(text = "Create Account", scale = 0.050, pos = p, relief = DGG.GROOVE, command = self.attemptCreateAccount)
		# Made a quick button for adding accounts. Its fugly

		p = boxloc + Vec3(1.20, 0, -0.9)
		self.quitButton = DirectButton(text = "Quit", pos = p, scale = 0.048, relief = DGG.GROOVE, command = self.showbase.quit)
		# The 'Quit' button that will trigger the Quit function
		# when clicked
		
		p = boxloc + Vec3(0, -0.4, 0)
		self.statusText = OnscreenText(text = statusText, pos = p, scale = 0.043, fg = (1, 0.5, 0, 1), align = TextNode.ACenter)
		# A simple text object that you can display an error/status messages
		# to the user

	def updateStatus(self, statusText):
		self.statusText.setText(statusText)
		# all this does is change the status text.

	def checkBoxes(self):
		# checks to make sure the user inputed a username and password:
		#       if they didn't it will spit out an error message
		self.updateStatus("")
		if self.usernameBox.get() == "":
			if self.passwordBox.get() == "":
				self.updateStatus("You must enter a username and password before logging in.")
			else:
				self.updateStatus("You must specify a username")
				self.passwordBox['focus'] = 0
				self.usernameBox['focus'] = 1
			return False
		elif self.passwordBox.get() == "":
			self.updateStatus("You must enter a password")
			self.usernameBox['focus'] = 0
			self.passwordBox['focus'] = 1
			return False
		# if both boxes are filled then return True
		return True

	def attemptLogin(self):
		if self.checkBoxes():
			self.showbase.username = self.usernameBox.get()
			self.updateStatus("Attempting to login...")
			self.request(self.usernameBox.get(), self.passwordBox.get(), 'client')
			
	def attemptCreateAccount(self):
		if self.checkBoxes():
			self.updateStatus("Attempting to create account and login...")
			self.request(self.usernameBox.get(), self.passwordBox.get(), 'create')
	
	def request(self, username, password, request):
		if not self.requestAttempt:
			# attempt to connect again if it failed on startup
			if self.showbase.authCon.getConnected():
				self.requestAttempt = True
				self.loginButton["state"] = DGG.DISABLED
				self.createAccButton["state"] = DGG.DISABLED
				self.showbase.authCon.sendData((request, (username, password)))
				self.showbase.username = username
				self.showbase.online = True
				self.showbase.taskMgr.doMethodLater(0.2, self.responseReader, 'Update Login')
			else:
				# client not connected to login/auth server so display message
				self.updateStatus("Offline Mode")
				self.showbase.username = username
				self.showbase.online = False
				self.updateConfig()
				self.showbase.startMainmenu()
	
	def responseReader(self, task):
		if task.time > 2.5:
			self.loginButton["state"] = DGG.NORMAL
			self.createAccButton["state"] = DGG.NORMAL
			self.updateStatus("Timeout from Login server")
			return task.done
		else:
			temp = self.showbase.authCon.getData()
			for package in temp:
				if len(package) == 2:
					print "Received: " + str(package)
					print "Connected to login server"
					if package[0] == 'loginFailed':
						print "Login failed: ", package[1]
						if package[1] == 'username':
							self.updateStatus("Username Doesnt Exist")
							self.passwordBox.set("")
							self.usernameBox.set("")
							self.passwordBox['focus'] = 0
							self.usernameBox['focus'] = 1
						elif package[1] == 'password':
							self.updateStatus("Password Incorrect")
							self.passwordBox.set("")
							self.usernameBox['focus'] = 0
							self.passwordBox['focus'] = 1
						elif package[1] == 'logged':
							self.updateStatus("Username already logged in")
						self.requestAttempt = False
						self.loginButton["state"] = DGG.NORMAL
						self.createAccButton["state"] = DGG.NORMAL
						return task.done
					elif package[0] == 'loginValid':
						print "Login valid: ", package[1]
						self.updateStatus(package[1])
						self.updateConfig()
						self.showbase.startMainmenu()
						return task.done
					elif package[0] == 'createFailed':
						print "Create failed: ", package[1]
						if package[1] == 'exists':
							self.updateStatus("Username Already Exists")
							self.passwordBox.set("")
							self.usernameBox.set("")
							self.passwordBox['focus'] = 0
							self.usernameBox['focus'] = 1
						self.requestAttempt = False
						self.loginButton["state"] = DGG.NORMAL
						self.createAccButton["state"] = DGG.NORMAL
						return task.done
					elif package[0] == 'createSuccess':
						print "Create success", package[1]
						self.updateStatus("Account Created Successfully")
						self.requestAttempt = False
						self.attemptLogin()
						return task.done
			return task.cont
		
	def cycleLoginBox(self):
		# function is triggered by the tab key so you can cycle between
		# the two input fields like on most login screens
		if self.passwordBox['focus'] == 1:
			self.passwordBox['focus'] = 0
			self.usernameBox['focus'] = 1
		elif self.usernameBox['focus'] == 1:
			self.usernameBox['focus'] = 0
			self.passwordBox['focus'] = 1
		# IMPORTANT: When you change the focus to one of the text boxes,
		# you have to unset the focus on the other textbox.  If you do not
		# do this Panda seems to get confused.
	
	def hide(self):
		self.background.destroy()
		self.usernameText.destroy()
		self.usernameBox.destroy()
		self.usernameStoreBox.destroy()
		self.passwordText.destroy()
		self.passwordBox.destroy()
		self.passwordStoreBox.destroy()
		self.loginButton.destroy()
		self.quitButton.destroy()
		self.createAccButton.destroy()
		self.statusText.destroy()
		
		self.showbase.ignore('tab')
		self.showbase.ignore('shift-tab')
		self.showbase.ignore('enter') 
class AdminPage(BookPage):
    def __init__(self, book):
        BookPage.__init__(self, book, 'Admin Panel')
        self.fsm = ClassicFSM(
            'AdminPage',
            [
                State('off', self.enterOff, self.exitOff),
                State('basePage', self.enterBasePage, self.exitBasePage),
                State('kickSection', self.enterKickSection,
                      self.exitKickSection),
                #State('clickOnToon', self.enterClickOnToon, self.exitClickOnToon),
                State('sysMsgSection', self.enterSysMsgSection,
                      self.exitSysMsgSection)
            ],
            'off',
            'off')
        self.fsm.enterInitialState()

    def load(self):
        BookPage.load(self)
        icons = loader.loadModel('phase_4/models/gui/tfa_images.bam')
        self.icon = icons.find('**/hq-dialog-image')
        icons.detachNode()

    def enterOff(self):
        pass

    def exitOff(self):
        pass

    def enter(self):
        BookPage.enter(self)
        self.fsm.request('basePage')

    def exit(self):
        self.fsm.requestFinalState()
        BookPage.exit(self)

    def unload(self):
        del self.book
        del self.fsm
        BookPage.unload(self)

    def enterSysMsgSection(self):
        geom = CIGlobals.getDefaultBtnGeom()
        self.infoLbl = OnscreenText(
            text="Inform all online players about something.", pos=(0, 0.45))
        self.msgEntry = DirectEntry(
            initialText="System Message...",
            scale=0.055,
            width=15,
            numLines=4,
            command=self.sendSystemMessageCommand,
            focusInCommand=base.localAvatar.chatInput.disableKeyboardShortcuts,
            focusOutCommand=base.localAvatar.chatInput.enableKeyboardShortcuts,
            pos=(-0.4, 0, 0))
        self.sendBtn = DirectButton(
            geom=geom,
            text_scale=0.04,
            relief=None,
            scale=1.0,
            text="Send",
            pos=(0, 0, -0.35),
            text_pos=(0, -0.01),
            command=self.sendSystemMessageCommand,
        )
        self.cancelBtn = DirectButton(geom=geom,
                                      text_scale=0.04,
                                      relief=None,
                                      scale=1.0,
                                      text="Cancel",
                                      pos=(-0.45, 0.15, -0.55),
                                      text_pos=(0, -0.01),
                                      command=self.fsm.request,
                                      extraArgs=['basePage'])

    # Occasionally, extra arguments are sent and this extra variable must be here to capture them.
    def sendSystemMessageCommand(self, _=None):
        msg = self.msgEntry.get()
        DISTRICT_WIDE_MSG(msg)
        self.fsm.request('basePage')

    def exitSysMsgSection(self):
        self.infoLbl.destroy()
        del self.infoLbl
        self.msgEntry.destroy()
        del self.msgEntry
        self.sendBtn.destroy()
        del self.sendBtn
        self.cancelBtn.destroy()
        del self.cancelBtn

    def enterKickSection(self):
        geom = CIGlobals.getDefaultBtnGeom()
        self.infoLbl = OnscreenText(text="Kick or Ban?", pos=(0, 0.45))
        self.kickBtn = DirectButton(geom=geom,
                                    text_scale=0.04,
                                    relief=None,
                                    scale=1.0,
                                    text="Kick",
                                    pos=(0, 0, 0.1),
                                    text_pos=(0, -0.01),
                                    command=self.book.finishedResume,
                                    extraArgs=[KickBanDialog, [0]])
        self.banBtn = DirectButton(geom=geom,
                                   text_scale=0.04,
                                   relief=None,
                                   scale=1.0,
                                   text="Ban",
                                   pos=(0, 0, 0.0),
                                   text_pos=(0, -0.01),
                                   command=self.book.finishedResume,
                                   extraArgs=[KickBanDialog, [1]])
        self.cancelBtn = DirectButton(geom=geom,
                                      text_scale=0.04,
                                      relief=None,
                                      scale=1.0,
                                      text="Cancel",
                                      pos=(-0.45, 0.15, -0.45),
                                      text_pos=(0, -0.01),
                                      command=self.fsm.request,
                                      extraArgs=['basePage'])

    def exitKickSection(self):
        self.banBtn.destroy()
        del self.banBtn
        self.infoLbl.destroy()
        del self.infoLbl
        self.cancelBtn.destroy()
        del self.cancelBtn
        self.kickBtn.destroy()
        del self.kickBtn

    def enterBasePage(self):
        geom = CIGlobals.getDefaultBtnGeom()
        self.ghostBtn = DirectButton(geom=geom,
                                     text_scale=0.04,
                                     relief=None,
                                     scale=1.0,
                                     text="Toggle Ghost",
                                     pos=(-0.45, 0.15, 0.5),
                                     text_pos=(0, -0.01),
                                     command=TOGGLE_GHOST)
        self.bgBtn = DirectButton(geom=geom,
                                  text_scale=0.04,
                                  relief=None,
                                  scale=1.0,
                                  text="Toggle Background",
                                  pos=(-0.45, 0.15, 0.40),
                                  text_pos=(0, -0.01),
                                  command=self.toggleBackground)
        self.idBtn = DirectButton(geom=geom,
                                  text_scale=0.04,
                                  relief=None,
                                  scale=1.0,
                                  text="Toggle Player Ids",
                                  pos=(-0.45, 0.15, 0.3),
                                  text_pos=(0, -0.01),
                                  command=TOGGLE_PLAYER_IDS)
        self.kickBtn = DirectButton(geom=geom,
                                    text_scale=0.04,
                                    relief=None,
                                    scale=1.0,
                                    text="Kick/Ban Player",
                                    pos=(0.45, 0.15, 0.5),
                                    text_pos=(0, -0.01),
                                    command=self.openKickPage)
        self.systemMsgBtn = DirectButton(geom=geom,
                                         text_scale=0.04,
                                         relief=None,
                                         scale=1.0,
                                         text="System Message",
                                         pos=(-0.45, 0.15, 0.1),
                                         text_pos=(0, -0.01),
                                         command=self.openSysMsgPage)
        self.oobeBtn = DirectButton(geom=geom,
                                    text_scale=0.04,
                                    relief=None,
                                    scale=1.0,
                                    text="Toggle OOBE",
                                    pos=(-0.45, 0.15, 0.2),
                                    text_pos=(0, -0.01),
                                    command=base.oobe)
        self.directBtn = DirectButton(geom=geom,
                                      text_scale=0.04,
                                      relief=None,
                                      scale=1.0,
                                      text="Start DIRECT",
                                      pos=(-0.45, 0.15, 0.1),
                                      text_pos=(0, -0.01),
                                      command=self.doStartDirect)
        self.pstatsBtn = DirectButton(geom=geom,
                                      text_scale=0.04,
                                      relief=None,
                                      scale=1.0,
                                      text="Toggle PStats",
                                      pos=(-0.45, 0.15, 0.0),
                                      text_pos=(0, -0.01),
                                      command=self.togglePStats)
        self.pingBtn = DirectButton(geom=geom,
                                    text_scale=0.04,
                                    relief=None,
                                    scale=1.0,
                                    text="Toggle Ping",
                                    pos=(-0.45, 0.15, -0.1),
                                    text_pos=(0, -0.01),
                                    command=base.cr.togglePing)
        self.tokenBtn = DirectButton(geom=geom,
                                     text_scale=0.04,
                                     relief=None,
                                     scale=1.0,
                                     text="Modify Access Level",
                                     pos=(0.45, 0.15, 0.4),
                                     text_pos=(0, -0.01),
                                     command=self.book.finishedResume,
                                     extraArgs=[AdminTokenDialog, []])
        self.worldBtn = DirectButton(geom=geom,
                                     text_scale=0.04,
                                     relief=None,
                                     scale=1.0,
                                     text="Give World Access",
                                     pos=(0.45, 0.15, 0.3),
                                     text_pos=(0, -0.01),
                                     command=self.book.finishedResume,
                                     extraArgs=[WorldAccessDialog, []])
        self.allGagsBtn = DirectButton(geom=geom,
                                       text_scale=0.04,
                                       relief=None,
                                       scale=1.0,
                                       text="Restock All Gags",
                                       pos=(0.45, 0.15, 0.2),
                                       text_pos=(0, -0.01),
                                       command=SEND_REQ_UNLOCK_GAGS)

        self.allLaffBtn = DirectButton(geom=geom,
                                       text_scale=0.04,
                                       relief=None,
                                       scale=1.0,
                                       text="Refill Laff",
                                       pos=(0.45, 0.15, 0.1),
                                       text_pos=(0, -0.01),
                                       command=SEND_REQ_REFILL_LAFF)

        self.physDbgBtn = DirectButton(geom=geom,
                                       text_scale=0.039,
                                       relief=None,
                                       scale=1.0,
                                       text="Toggle Physics Debug",
                                       pos=(0.45, 0.15, 0.0),
                                       text_pos=(0, -0.01),
                                       command=self.togglePhysDbg)
        self.analyzeBtn = DirectButton(geom=geom,
                                       text_scale=0.04,
                                       relief=None,
                                       scale=1.0,
                                       text="Analyze Scene",
                                       pos=(0.45, 0.15, -0.1),
                                       text_pos=(0, -0.01),
                                       command=self.doAnalyzeScene)
        self.listBtn = DirectButton(geom=geom,
                                    text_scale=0.04,
                                    relief=None,
                                    scale=1.0,
                                    text="List Scene",
                                    pos=(0.45, 0.15, -0.2),
                                    text_pos=(0, -0.01),
                                    command=render.ls)
        self.noClipBtn = DirectButton(geom=geom,
                                      text_scale=0.04,
                                      relief=None,
                                      scale=1.0,
                                      text="Toggle No Clip",
                                      pos=(0.45, 0.15, -0.3),
                                      text_pos=(0, -0.01),
                                      command=self.toggleNoClip)
        base.cr.playGame.getPlace().maybeUpdateAdminPage()
        del geom

    def doStartDirect(self):
        base.startTk()
        base.startDirect()

    def doAnalyzeScene(self):
        render.analyze()

        ls = LineStream()
        sga = SceneGraphAnalyzer()
        sga.addNode(render.node())
        sga.write(ls)
        text = ""
        while ls.isTextAvailable():
            text += ls.getLine() + "\n"
        self.acceptOnce('analyzedone', self.__handleAnalyzeDone)
        self.analyzeDlg = GlobalDialog(message=text,
                                       style=Ok,
                                       doneEvent='analyzedone',
                                       text_scale=0.05)
        self.analyzeDlg.show()

    def __handleAnalyzeDone(self):
        self.analyzeDlg.cleanup()
        del self.analyzeDlg

    def toggleNoClip(self):
        ncl = not base.localAvatar.walkControls.controller.noClip
        base.localAvatar.walkControls.controller.noClip = ncl

        if ncl:
            base.cr.myDistrict.systemMessage("No Clip Enabled")
        else:
            base.cr.myDistrict.systemMessage("No Clip Disabled")

    def togglePhysDbg(self):
        base.setPhysicsDebug(not base.physicsDbgFlag)

    def togglePStats(self):
        if PStatClient.isConnected():
            PStatClient.disconnect()
        else:
            # in production, show stats viewer on the server
            if base.config.GetBool("pstats-view-on-server", False):
                PStatClient.connect("127.0.0.1" if not metadata.IS_PRODUCTION
                                    else "gameserver.coginvasion.online")
            else:
                PStatClient.connect("127.0.0.1")

    def toggleBackground(self):
        if render.isHidden():
            render.show()
        else:
            render.hide()
        if self.book.isBackgroundHidden():
            self.book.show()
            self.book.setBackgroundHidden(False)
        else:
            self.book.hide()
            self.book.setBackgroundHidden(True)

    def openKickPage(self):
        self.fsm.request('kickSection')

    def openSysMsgPage(self):
        self.fsm.request('sysMsgSection')

    def exitBasePage(self):
        self.noClipBtn.destroy()
        del self.noClipBtn
        self.systemMsgBtn.destroy()
        del self.systemMsgBtn
        self.idBtn.destroy()
        del self.idBtn
        self.kickBtn.destroy()
        del self.kickBtn
        self.bgBtn.destroy()
        del self.bgBtn
        self.ghostBtn.destroy()
        del self.ghostBtn
        self.oobeBtn.destroy()
        del self.oobeBtn
        self.tokenBtn.destroy()
        del self.tokenBtn
        self.worldBtn.destroy()
        del self.worldBtn
        self.allGagsBtn.destroy()
        del self.allGagsBtn
        self.allLaffBtn.destroy()
        del self.allLaffBtn
        self.physDbgBtn.destroy()
        del self.physDbgBtn
        self.analyzeBtn.destroy()
        del self.analyzeBtn
        if hasattr(self, 'analyzeDlg'):
            self.ignore('analyzedone')
            self.analyzeDlg.cleanup()
            del self.analyzeDlg
        self.directBtn.destroy()
        del self.directBtn
        self.listBtn.destroy()
        del self.listBtn
        self.pstatsBtn.destroy()
        del self.pstatsBtn
        self.pingBtn.destroy()
        del self.pingBtn