Esempio n. 1
0
 def gotoHexView(self, offset, lenData):
     index = self.mainTab.indexOf(self.hexView)
     if index == -1:
         self.hexView = HexView(BinaryAnalysis.rawData)
         self.addNewTab(self.hexView, "Hex View")
     self.hexView.toOffset(offset, lenData)
     self.focusWidgetInTab(self.hexView)
Esempio n. 2
0
	def __init__(self, window):
		self.window = window
		self.colours = {'white' : (255, 255, 255, 0), 'outerspace': (65, 74, 76, 0) }
		pyglet.gl.glClearColor(*self.colours['outerspace'])
		
		#Load images, create batch-groups, a batch
		pyglet.resource.path = ['tiles']
		pyglet.resource.reindex()
		#self.explosion_stream = open('explosion2strip.png', 'rb')
		#self.explosion = pyglet.image.load('explosion1strip.png')
		self.hexWater = pyglet.resource.image('hex.png')
		self.hexMud = pyglet.resource.image('hexDirt.png')
		self.hexUnwalkable = pyglet.resource.image('hexUnwalkable.png')
		self.ship = pyglet.resource.image('ship.png')
		self.background = pyglet.graphics.OrderedGroup(0)
		self.foreground = pyglet.graphics.OrderedGroup(1)
		self.effectslayer = pyglet.graphics.OrderedGroup(2)
		self.cellbatch = pyglet.graphics.Batch()
		
		self.grid = Grid(12, 8)	
		
		self.hexView = HexView(self.grid, 64, 55, 17, 0, 0) #todo: something to get this centered in the screen automatically
		self.screenCoordinates = self.hexView.screenCoordinates()
		
		self.selectedCell = None
		self.phase = 1
		self.movingUnit = False #True if a unit is being moved
		self.currentFaction = "Viper"
Esempio n. 3
0
    def __init__(self):
        super(HMainWindow, self).__init__(
        )  # does something magical about inheritance and preventing infinite recursion?

        self.files = []
        self.current_file = None

        # self.last_selected = 0

        # QtCore.QCoreApplication.setOrganizationName("L-3Com")
        # QtCore.QCoreApplication.setOrganizationName("l-3com.com")
        # QtCore.QCoreApplication.setApplicationName("Hexotomy")
        self.setWindowTitle("Hexotomy")

        QtCore.QSettings.setPath(QtCore.QSettings.IniFormat,
                                 QtCore.QSettings.UserScope, ".")
        self.read_settings()

        self.show()
        # self.showMaximized()
        self.setAcceptDrops(True)

        # self.file_watcher = QtCore.QFileSystemWatcher()
        # self.file_watcher.fileChanged.connect(self.file_changed)
        self.file_watch = HexFileWatch(self)

        self.hex_view = HexView(self)
        self.setCentralWidget(self.hex_view)

        self.create_actions()
        self.create_menus()
        self.create_toolbars()
        self.create_statusbar()
        self.create_dock_windows()

        self.load_project(self.project_file)

        self.save_timer = QtCore.QTimer()
        self.save_timer.timeout.connect(self.save_project)
        self.save_timer.start(30000)
Esempio n. 4
0
 def openHexView(self):
     if self.hexView is not None:
         self.focusWidgetInTab(self.hexView)
     else:
         self.hexView = HexView(BinaryAnalysis.rawData)
         self.addNewTab(self.hexView, "Hex View")
Esempio n. 5
0
 def changeData(self, offset, data):
     index = self.mainTab.indexOf(self.hexView)
     if index == -1:
         self.hexView = HexView(BinaryAnalysis.rawData)
         self.addNewTab(self.hexView, "Hex View")
     self.hexView.changeData(offset, data)
Esempio n. 6
0
class Window(QMainWindow):
    def __init__(self):
        super(Window, self).__init__()
        screenShape = QDesktopWidget().screenGeometry()
        SCREEN_WIDTH = screenShape.width()
        SCREEN_HIGHT = screenShape.height()
        self.setWindowTitle(APPNAME)
        self.setWindowIcon(QIcon(ICON))
        self.setMinimumWidth(SCREEN_WIDTH // 3)
        self.setMinimumHeight(SCREEN_HIGHT // 3)
        self.statusBar = self.statusBar()
        self.mainMenu = self.menuBar()
        QApplication.setStyle(QStyleFactory.create(STYLE))
        self.iraChache = {}
        self.mainTab = None
        self.stringView = None
        self.asmLinear = None
        self.hexView = None
        self.initMenu()
        self.initToolBar()
        self.showMaximized()

    def initMenu(self):
        names = ['File', 'View', 'Tool']
        items = {
            'File': [
                ('Open', 'Ctrl+O', 'Open file', self.openFile),
                ('Save', 'Ctrl+S', 'Save file', self.saveFile),
                ('Save As', 'Ctrl+Shift+S', 'Save file as', self.saveFileAs),
                ('Quit', 'Ctrl+Q', 'Quit the program', self.closeApp),
            ],
            'View': [
                ('Linear Diassembly', 'Ctrl+L', 'Linear Dissembly View',
                 self.openAsmLinearView),
                ('Asm Graph', 'Ctrl+G', 'Graph View', self.openAsmCFGView),
                ('IR Linear', 'Ctrl+G', 'IR Linear View',
                 self.openIRLinearView),
                ('IR Graph', 'Ctrl+G', 'IR Graph View', self.openIRCFGView),
                ('Hex', 'Ctrl+H', 'Hex View', self.openHexView),
                ('String', 'Ctrl+L', 'String View', self.openStringView),
            ],
            'Tool': [('Basic Deobfuscate', 'Ctrl+R', "Basic Deobfuscate",
                      self.recoverAlgorithm)]
        }
        for name in names:
            menu = self.mainMenu.addMenu('&' + name)
            for item, shortcut, status, func in items[name]:
                menu.addAction(
                    self.createActionWithShortcut(item, shortcut, status,
                                                  func))

    def initToolBar(self):
        names = ['File Utils', 'View']
        items = {
            'File Utils': [
                ('imgs/open.png', 'Open', 'Open file', self.openFile),
                ('imgs/save.png', 'Save', 'Save file', self.saveFile),
                ('imgs/saveas.png', 'Save as', 'Save file as',
                 self.saveFileAs),
            ],
            'View': [
                ('imgs/hex.png', 'Hex', 'Hex View', self.openHexView),
                ('imgs/graph.png', 'Graph', 'Graph View', self.openAsmCFGView),
                ('imgs/linear.png', 'Linear Disassembly',
                 'Linear Disassembly View', self.openAsmLinearView),
            ],
        }
        for name in names:
            toolBar = self.addToolBar(name)
            for img, desc, status, func in items[name]:
                toolBar.addAction(
                    self.createActionWithIcon(img, desc, status, func))

    def createActionWithShortcut(self, name, shortcut, status, func):
        """
        Tao action gan voi shortcut key. VD: createActionWithShortcut('Quit', 'Ctrl+Q', closeApp)
        :param name: ten action
        :param shortcut: phim shortcut gan voi action
        :param func: ham se chay khi bi click
        :return: QAction
        """
        action = QAction(name, self)
        action.setShortcut(shortcut)
        action.setStatusTip(status)
        action.triggered.connect(func)
        return action

    def createActionWithIcon(self, icon, description, status, func):
        """
        Tao action bieu tuong icon. VD: createActionWithIcon('ifa.png', 'Quit', closeApp)
        :param icon: ten file icon
        :param description: text hien thi khi de chuot vao
        :param func: ham se chay neu icon duoc click
        :return: QAction
        """
        action = QAction(QIcon(icon), description, self)
        action.setStatusTip(status)
        action.triggered.connect(func)
        return action

    # ==============================================================

    def closeApp(self):
        """
        Quit App
        :return:
        """
        sys.exit()

    def openFile(self):
        """"
        Open File, Load Function to ListFunction and Info
        :return:
        """
        try:
            f = open('cache', 'r')
            dir = f.read()
        except FileNotFoundError:
            dir = ''
        file, _ = QFileDialog.getOpenFileName(
            self,
            "Open File",
            dir,
            "All File (*);;Python File (*.elf);;PE File (*.exe",
            options=QFileDialog.DontUseNativeDialog)
        if file:
            dir = os.path.dirname(file)
            open('cache', 'w').write(dir)
            self.centralWidget = QWidget(self)
            self.setCentralWidget(self.centralWidget)
            QVBoxLayout(self.centralWidget)
            allLayout = self.centralWidget.layout()
            BinaryAnalysis.init(file)

            self.outputLog = QTextEdit()

            self.binInfo = QTextEdit()
            self.binInfo.setReadOnly(True)
            self.binInfo.setText(BinaryAnalysis.binaryInfo.info())

            self.listFunctions = ListFuncs(BinaryAnalysis.funcs)
            self.listFunctions.gotoFunc.connect(self.gotoAddress)

            leftTopBottomSplitter = QSplitter(Qt.Vertical)
            leftTopBottomSplitter.setSizePolicy(QSizePolicy.Minimum,
                                                QSizePolicy.Minimum)
            leftTopBottomSplitter.addWidget(self.binInfo)
            leftTopBottomSplitter.addWidget(self.listFunctions)
            leftTopBottomSplitter.setStretchFactor(0, 1)
            leftTopBottomSplitter.setStretchFactor(1, 9)

            leftRightSplitter = QSplitter()

            self.mainTab = QTabWidget()
            self.mainTab.setTabsClosable(True)
            self.mainTab.tabCloseRequested.connect(self.closeTab)
            self.mainTab.setSizePolicy(QSizePolicy.Expanding,
                                       QSizePolicy.Expanding)

            self.asmLinear = AsmLinear()
            self.mainTab.addTab(self.asmLinear, "Disassembly")
            self.asmLinear.focusAddress(BinaryAnalysis.binaryInfo.entryPoint)
            self.bindAsmLinear()

            self.hexView = HexView(BinaryAnalysis.rawData)
            self.mainTab.addTab(self.hexView, "Hex View")

            self.stringView = StringView(BinaryAnalysis.binaryInfo.strings)
            self.stringView.clicked.connect(self.gotoAddress)
            self.mainTab.addTab(self.stringView, "String List")

            self.importView = ImportView(BinaryAnalysis.binaryInfo.imports)
            self.importView.clicked.connect(self.gotoLibFunc)
            self.mainTab.addTab(self.importView, "Imports")

            self.exportView = ExportView(BinaryAnalysis.binaryInfo.exports)
            self.exportView.clicked.connect(self.gotoLibFunc)
            self.mainTab.addTab(self.exportView, "Exports")

            leftRightSplitter.addWidget(leftTopBottomSplitter)
            leftRightSplitter.addWidget(self.mainTab)
            leftRightSplitter.setStretchFactor(0, 2)
            leftRightSplitter.setStretchFactor(1, 8)
            topBottomSplitter = QSplitter(Qt.Vertical)
            topBottomSplitter.addWidget(leftRightSplitter)
            topBottomSplitter.addWidget(self.outputLog)
            topBottomSplitter.setStretchFactor(0, 8)
            topBottomSplitter.setStretchFactor(1, 2)
            allLayout.addWidget(topBottomSplitter)
            self.asmLinear.setFocus()

    def gotoLibFunc(self, name):
        for func in BinaryAnalysis.funcs:
            if func.name.endswith(name):
                self.gotoAsmLinear(func.address)
                break

    def bindAsmLinear(self):
        self.asmLinear.addCFG.connect(self.addAsmCFGView)
        self.asmLinear.gotoHexView.connect(self.gotoHexView)
        self.asmLinear.log.connect(self.outputLog.append)
        self.asmLinear.changedData.connect(self.changeData)
        self.asmLinear.addIRLinear.connect(self.addIRLinearView)

    def changeData(self, offset, data):
        index = self.mainTab.indexOf(self.hexView)
        if index == -1:
            self.hexView = HexView(BinaryAnalysis.rawData)
            self.addNewTab(self.hexView, "Hex View")
        self.hexView.changeData(offset, data)

    def addIRLinearView(self, func):
        from IRAnalysis import IRAnalysis
        from IRView import IRWidget
        if func in self.iraChache:
            if not func.changed:
                ira = self.iraChache[func]
            else:
                func.changed = False
                ira = IRAnalysis(func.address, func.cfg)
                self.iraChache[func] = ira
        else:
            ira = IRAnalysis(func.address, func.cfg)
            self.iraChache[func] = ira
        irLinearView = IRWidget(ira, 0)
        self.addNewTab(irLinearView, "IR Linear %s" % func.name)

    def addIRCFGView(self, func):
        from IRAnalysis import IRAnalysis
        from IRView import IRWidget
        if func in self.iraChache:
            if not func.changed:
                ira = self.iraChache[func]
            else:
                func.changed = False
                func.ircfg = None
                func.defUse = None
                func.ira = None
                ira = IRAnalysis(func.address, func.cfg)
                self.iraChache[func] = ira
        else:
            ira = IRAnalysis(func.address, func.cfg)
            self.iraChache[func] = ira
        irLinearView = IRWidget(ira, 2)
        self.addNewTab(irLinearView, "IR CFG %s" % func.name)

    def addAsmCFGView(self, line):
        for i in range(self.mainTab.count()):
            widget = self.mainTab.widget(i)
            if isinstance(widget, AsmCFGView):
                if line.func == widget.func:
                    if not line.func.changed:
                        self.mainTab.setCurrentIndex(i)
                        return
                    else:
                        self.mainTab.removeTab(i)
                        line.func.changed = False
                        line.func.ircfg = None
                        line.func.ira = None
                        line.func.defUse = None
                        if line.func in self.iraChache:
                            del self.iraChache[line.func]
                        break
        asmCFGView = AsmCFGView(line.func)
        asmCFGView.gotoAsmLinear.connect(self.gotoAsmLinear)
        asmCFGView.changeCFG.connect(self.replaceAsmCFG)
        asmCFGView.gotoHexView.connect(self.gotoHexView)
        asmCFGView.gotoIRCFG.connect(self.addIRCFGView)
        asmCFGView.gotoAddress.connect(self.gotoAsmLinear)
        asmCFGView.log.connect(self.outputLog.append)
        indexes = self.asmLinear.selectedIndexes()
        for index in indexes:
            item = self.asmLinear.getItemFormIndex(index)
            if hasattr(item, 'instr'):
                asmCFGView.selectAddress(item.instr.offset, False, False)
        asmCFGView.selectAddress(line.address, True, False)
        self.addNewTab(asmCFGView, "AsmCFG")

    def gotoAsmLinear(self, address):
        index = self.mainTab.indexOf(self.asmLinear)
        if index == -1:
            self.asmLinear = AsmLinear()
            self.bindAsmLinear()
            self.addNewTab(self.asmLinear, "Disassmbly")
        if address in self.asmLinear.addressMap:
            self.focusWidgetInTab(self.asmLinear)
            self.asmLinear.focusAddress(address)
            self.asmLinear.setFocus()

    def gotoHexView(self, offset, lenData):
        index = self.mainTab.indexOf(self.hexView)
        if index == -1:
            self.hexView = HexView(BinaryAnalysis.rawData)
            self.addNewTab(self.hexView, "Hex View")
        self.hexView.toOffset(offset, lenData)
        self.focusWidgetInTab(self.hexView)

    def addNewTab(self, widget, name):
        index = self.mainTab.currentIndex()
        self.mainTab.insertTab(index + 1, widget, name)
        self.mainTab.setCurrentIndex(index + 1)
        widget.setFocus()

    def gotoAddress(self, address):
        from IRView import IRWidget
        widget = self.getCurrentWidget()
        if isinstance(widget, AsmCFGView):
            self.replaceAsmCFG(address)
        elif isinstance(widget, IRWidget):
            for func in BinaryAnalysis.funcs:
                if func.address == address:
                    if widget.viewType == 0:
                        self.addIRLinearView(func)
                    else:
                        self.addIRCFGView(func)
                    self.mainTab.removeTab(self.mainTab.currentIndex() - 1)
                    break
        elif address in self.asmLinear.addressMap:
            linearIndex = self.mainTab.indexOf(self.asmLinear)
            self.mainTab.setCurrentIndex(linearIndex)
            self.asmLinear.focusAddress(address)
            self.asmLinear.setFocus()
        else:
            hexIndex = self.mainTab.indexOf(self.hexView)
            self.mainTab.setCurrentIndex(hexIndex)
            offset = BinaryAnalysis.binaryInfo.getOffsetAtAddress(address)
            self.hexView.toOffset(offset)
            self.hexView.setFocus()

    def replaceAsmCFG(self, address):
        newFunc = None
        index = self.mainTab.currentIndex()
        for func in BinaryAnalysis.funcs:
            if address == func.address:
                newFunc = func
                break
        if newFunc is not None:
            asmCFGView = AsmCFGView(newFunc)
            self.addNewTab(asmCFGView, "AsmCFG")
            asmCFGView.changeCFG.connect(self.replaceAsmCFG)
            self.mainTab.removeTab(index)
            asmCFGView.setFocus()

    def getCurrentWidget(self):
        return self.mainTab.currentWidget()

    def closeTab(self, index):
        self.mainTab.removeTab(index)
        self.mainTab.setCurrentIndex(index - 1)
        self.mainTab.widget(index - 1).setFocus()

    def focusWidgetInTab(self, widget):
        index = self.mainTab.indexOf(widget)
        self.mainTab.setCurrentIndex(index)
        widget.setFocus()

    def saveFile(self):
        if BinaryAnalysis.path is not None:
            button_pressed = QMessageBox.question(
                self, 'Save File', "Do you want to save?",
                QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
            if button_pressed == QMessageBox.Yes:
                f = open(BinaryAnalysis.path, 'wb')
                f.write(bytearray(BinaryAnalysis.rawData))
                f.close()

    def saveFileAs(self):
        if BinaryAnalysis.path is not None:
            name, _ = QFileDialog.getSaveFileName(self, "Save File as")
            if name:
                f = open(name, 'wb')
                f.write(bytearray(BinaryAnalysis.rawData))
                f.close()

    def openAsmLinearView(self):
        if BinaryAnalysis.path is not None:
            self.gotoAsmLinear(BinaryAnalysis.binaryInfo.entryPoint)

    def openAsmCFGView(self):
        if BinaryAnalysis.path is not None:
            if self.mainTab.currentWidget() == self.asmLinear:
                indexes = self.asmLinear.selectedIndexes()
                if len(indexes) > 0:
                    line = self.asmLinear.getItemFormIndex(indexes[0])
                    self.addAsmCFGView(line)

    def openIRLinearView(self):
        if BinaryAnalysis.path is not None:
            if self.mainTab.currentWidget() == self.asmLinear:
                indexes = self.asmLinear.selectedIndexes()
                if len(indexes) > 0:
                    line = self.asmLinear.getItemFormIndex(indexes[0])
                    self.addIRLinearView(line.func)
            elif isinstance(self.mainTab.currentWidget(), AsmCFGView):
                self.addIRLinearView(self.mainTab.currentWidget().func)

    def openIRCFGView(self):
        if BinaryAnalysis.path is not None:
            if self.mainTab.currentWidget() == self.asmLinear:
                indexes = self.asmLinear.selectedIndexes()
                if len(indexes) > 0:
                    line = self.asmLinear.getItemFormIndex(indexes[0])
                    self.addIRCFGView(line.func)
            elif isinstance(self.mainTab.currentWidget(), AsmCFGView):
                self.addIRCFGView(self.mainTab.currentWidget().func)

    def openHexView(self):
        if self.hexView is not None:
            self.focusWidgetInTab(self.hexView)
        else:
            self.hexView = HexView(BinaryAnalysis.rawData)
            self.addNewTab(self.hexView, "Hex View")

    def openStringView(self):
        if self.stringView is not None:
            self.focusWidgetInTab(self.stringView)
        else:
            self.stringView = StringView(BinaryAnalysis.binaryInfo.strings)
            self.addNewTab(self.stringView, "Strings")

    def recoverAlgorithm(self):
        from IRAnalysis import IRAnalysis
        from IRView import IRCFGRecover, IRWidget
        widget = self.mainTab.currentWidget()
        func = None
        if isinstance(widget, AsmLinear):
            indexes = widget.selectedIndexes()
            if len(indexes) > 0:
                line = widget.getItemFormIndex(indexes[0])
                func = line.func
        elif isinstance(widget, AsmCFGView):
            func = widget.func
        elif isinstance(widget, IRWidget):
            address = widget.ira.address
            for f in BinaryAnalysis.funcs:
                if f.address == address:
                    func = f
                    break
        if func is not None:
            if func in self.iraChache:
                ira = self.iraChache[func]
            else:
                ira = IRAnalysis(func.address, func.cfg)
            newLocDB, newIRCFG = ira.recoverAlgorithm()
            recoverIRCFG = IRCFGRecover(newIRCFG)
            for block in recoverIRCFG.mapItems:
                line = block.model.item(0, 0)
                line.setText(newLocDB.pretty_str(line.lockey))
            self.addNewTab(recoverIRCFG, "Recovered IRCFG")
Esempio n. 7
0
    def openFile(self):
        """"
        Open File, Load Function to ListFunction and Info
        :return:
        """
        try:
            f = open('cache', 'r')
            dir = f.read()
        except FileNotFoundError:
            dir = ''
        file, _ = QFileDialog.getOpenFileName(
            self,
            "Open File",
            dir,
            "All File (*);;Python File (*.elf);;PE File (*.exe",
            options=QFileDialog.DontUseNativeDialog)
        if file:
            dir = os.path.dirname(file)
            open('cache', 'w').write(dir)
            self.centralWidget = QWidget(self)
            self.setCentralWidget(self.centralWidget)
            QVBoxLayout(self.centralWidget)
            allLayout = self.centralWidget.layout()
            BinaryAnalysis.init(file)

            self.outputLog = QTextEdit()

            self.binInfo = QTextEdit()
            self.binInfo.setReadOnly(True)
            self.binInfo.setText(BinaryAnalysis.binaryInfo.info())

            self.listFunctions = ListFuncs(BinaryAnalysis.funcs)
            self.listFunctions.gotoFunc.connect(self.gotoAddress)

            leftTopBottomSplitter = QSplitter(Qt.Vertical)
            leftTopBottomSplitter.setSizePolicy(QSizePolicy.Minimum,
                                                QSizePolicy.Minimum)
            leftTopBottomSplitter.addWidget(self.binInfo)
            leftTopBottomSplitter.addWidget(self.listFunctions)
            leftTopBottomSplitter.setStretchFactor(0, 1)
            leftTopBottomSplitter.setStretchFactor(1, 9)

            leftRightSplitter = QSplitter()

            self.mainTab = QTabWidget()
            self.mainTab.setTabsClosable(True)
            self.mainTab.tabCloseRequested.connect(self.closeTab)
            self.mainTab.setSizePolicy(QSizePolicy.Expanding,
                                       QSizePolicy.Expanding)

            self.asmLinear = AsmLinear()
            self.mainTab.addTab(self.asmLinear, "Disassembly")
            self.asmLinear.focusAddress(BinaryAnalysis.binaryInfo.entryPoint)
            self.bindAsmLinear()

            self.hexView = HexView(BinaryAnalysis.rawData)
            self.mainTab.addTab(self.hexView, "Hex View")

            self.stringView = StringView(BinaryAnalysis.binaryInfo.strings)
            self.stringView.clicked.connect(self.gotoAddress)
            self.mainTab.addTab(self.stringView, "String List")

            self.importView = ImportView(BinaryAnalysis.binaryInfo.imports)
            self.importView.clicked.connect(self.gotoLibFunc)
            self.mainTab.addTab(self.importView, "Imports")

            self.exportView = ExportView(BinaryAnalysis.binaryInfo.exports)
            self.exportView.clicked.connect(self.gotoLibFunc)
            self.mainTab.addTab(self.exportView, "Exports")

            leftRightSplitter.addWidget(leftTopBottomSplitter)
            leftRightSplitter.addWidget(self.mainTab)
            leftRightSplitter.setStretchFactor(0, 2)
            leftRightSplitter.setStretchFactor(1, 8)
            topBottomSplitter = QSplitter(Qt.Vertical)
            topBottomSplitter.addWidget(leftRightSplitter)
            topBottomSplitter.addWidget(self.outputLog)
            topBottomSplitter.setStretchFactor(0, 8)
            topBottomSplitter.setStretchFactor(1, 2)
            allLayout.addWidget(topBottomSplitter)
            self.asmLinear.setFocus()
Esempio n. 8
0
class HMainWindow(QtGui.QMainWindow):
    def __init__(self):
        super(HMainWindow, self).__init__(
        )  # does something magical about inheritance and preventing infinite recursion?

        self.files = []
        self.current_file = None

        # self.last_selected = 0

        # QtCore.QCoreApplication.setOrganizationName("L-3Com")
        # QtCore.QCoreApplication.setOrganizationName("l-3com.com")
        # QtCore.QCoreApplication.setApplicationName("Hexotomy")
        self.setWindowTitle("Hexotomy")

        QtCore.QSettings.setPath(QtCore.QSettings.IniFormat,
                                 QtCore.QSettings.UserScope, ".")
        self.read_settings()

        self.show()
        # self.showMaximized()
        self.setAcceptDrops(True)

        # self.file_watcher = QtCore.QFileSystemWatcher()
        # self.file_watcher.fileChanged.connect(self.file_changed)
        self.file_watch = HexFileWatch(self)

        self.hex_view = HexView(self)
        self.setCentralWidget(self.hex_view)

        self.create_actions()
        self.create_menus()
        self.create_toolbars()
        self.create_statusbar()
        self.create_dock_windows()

        self.load_project(self.project_file)

        self.save_timer = QtCore.QTimer()
        self.save_timer.timeout.connect(self.save_project)
        self.save_timer.start(30000)

    # Create:
    def create_actions(self):
        self.openAction = QtGui.QAction(QtGui.QIcon('document-open.png'),
                                        "&Open...",
                                        self,
                                        shortcut=QtGui.QKeySequence.Open,
                                        statusTip="Open an existing file",
                                        triggered=self.open_file)
        self.projectAction = QtGui.QAction(
            QtGui.QIcon('system-file-manager.png'),
            "&Load Project File...",
            self,
            shortcut=QtGui.QKeySequence.Open,
            statusTip="Load a Project file where all work will be saved",
            triggered=self.choose_project)
        self.exitAction = QtGui.QAction("E&xit",
                                        self,
                                        shortcut="Ctrl-Q",
                                        statusTip="Exit Hexotomy",
                                        triggered=self.close)
        self.aboutAction = QtGui.QAction(
            "&About",
            self,
            statusTip="Show the application's About box",
            triggered=self.about)

    def create_menus(self):
        self.fileMenu = self.menuBar().addMenu("&File")
        self.fileMenu.addAction(self.projectAction)
        self.fileMenu.addSeparator()
        self.fileMenu.addAction(self.openAction)
        self.fileMenu.addSeparator()
        self.fileMenu.addAction(self.exitAction)

        self.menuBar().addSeparator()

        self.helpMenu = self.menuBar().addMenu("&Help")
        self.helpMenu.addAction(self.aboutAction)

    def create_toolbars(self):
        self.fileToolBar = self.addToolBar("File")
        self.fileToolBar.setObjectName("fileToolBar")
        self.fileToolBar.addAction(self.projectAction)
        self.fileToolBar.addSeparator()
        self.fileToolBar.addAction(self.openAction)

    def create_statusbar(self):
        self.statusBar().showMessage("")

    def create_dock_windows(self):
        self.revision_dock = QtGui.QDockWidget("Files/Revisions", self)
        self.revision_dock.setObjectName("revision_dock")
        # self.self().self.selfie.self() = self.selfy.self%self().selfself
        self.revision_dock.setFeatures(QtGui.QDockWidget.DockWidgetFloatable
                                       | QtGui.QDockWidget.DockWidgetMovable)
        self.revision_tree = HexRevisionTree(self)
        self.revision_dock.setWidget(self.revision_tree)
        # self.revision_dock.setGeometry(0, 0, 400, 600)
        self.addDockWidget(QtCore.Qt.LeftDockWidgetArea, self.revision_dock)

        self.inspector_dock = QtGui.QDockWidget("Inspector Gadget", self)
        self.inspector_dock.setObjectName("inspector_dock")
        self.inspector_dock.setFeatures(QtGui.QDockWidget.DockWidgetFloatable
                                        | QtGui.QDockWidget.DockWidgetMovable)
        # self.inspector_table = QtGui.QTableWidget(self.inspector_dock)
        self.inspector_table = HexInspectorTable(self)
        self.inspector_dock.setWidget(self.inspector_table)
        # self.inspector_dock.setGeometry(0, 0, 400, 600)  # useless
        self.addDockWidget(QtCore.Qt.LeftDockWidgetArea, self.inspector_dock)

        self.interpreter_dock = QtGui.QDockWidget("Interpreter", self)
        self.interpreter_dock.setObjectName("interpreter_dock")
        self.interpreter_dock.setFeatures(
            QtGui.QDockWidget.DockWidgetFloatable
            | QtGui.QDockWidget.DockWidgetMovable)
        self.interpreter_table = HexInterpreterTable(self)
        self.interpreter_dock.setWidget(self.interpreter_table)
        # self.inspector_dock.setGeometry(0, 0, 400, 600)  # useless
        self.addDockWidget(QtCore.Qt.RightDockWidgetArea,
                           self.interpreter_dock)

        self.interpreter_detail_dock = QtGui.QDockWidget(
            "Interpret Detail", self)
        self.interpreter_detail_dock.setObjectName("interpreter_detail_dock")
        self.interpreter_detail_dock.setFeatures(
            QtGui.QDockWidget.DockWidgetFloatable
            | QtGui.QDockWidget.DockWidgetMovable)
        self.interpreter_table.detail = HexInterpreterDetail(
            self.interpreter_table)
        self.interpreter_detail_dock.setWidget(self.interpreter_table.detail)
        # self.inspector_dock.setGeometry(0, 0, 400, 600)  # useless
        self.addDockWidget(QtCore.Qt.RightDockWidgetArea,
                           self.interpreter_detail_dock)

    # Do stuff:
    def about(self):
        QtGui.QMessageBox.about(
            self, "About Hexotomy",
            "Hexotomy is a tool to help understand small binary files.<p>"
            "Uses PySide (LGPL) and Tango Icons (Public Domain)")

    def read_settings(self):
        settings = QtCore.QSettings(QtCore.QSettings.IniFormat,
                                    QtCore.QSettings.UserScope, "L-3com",
                                    "Hexotomy")
        self.project_file = settings.value("project", "default.hxt")
        print "project_file: " + self.project_file
        #print "GRRR: isfile-%s getsize-%d" % (str(os.path.isfile(self.project_file)), os.path.getsize(self.project_file))
        if not os.path.isfile(
                self.project_file) or os.path.getsize(self.project_file) < 20:
            print "read_settings: '%s' is not a real project file. Defaulting to default.hxt" % (
                self.project_file)
            self.project_file = "default.hxt"
        self.restoreGeometry(settings.value("geometry"))
        #if not self.restoreState(settings.value("windowState")):
        #self.showMaximized()

    def write_settings(self):
        settings = QtCore.QSettings(QtCore.QSettings.IniFormat,
                                    QtCore.QSettings.UserScope, "L-3com",
                                    "Hexotomy")
        settings.setValue("project", self.project_file)
        settings.setValue("geometry", self.saveGeometry())
        settings.setValue("windowState", self.saveState())

    def choose_project(self):
        filename, _ = QtGui.QFileDialog.getSaveFileName(
            self,
            caption="Load Project File",
            filter="Hexotomy Project (*.hxt);;All Files (*)",
            options="QFileDialog.DontConfirmOverwrite")
        if filename:
            self.save_project()
            self.load_project(filename)

    def load_project(self, filename):
        if not filename:
            print "empty db filename"
            return

        if os.path.isfile(filename) and os.path.getsize(filename) > 0:
            try:
                project_file = open(str(filename), "rb")
                self.files = cPickle.load(project_file)
                self.interpreter_table.interprets = cPickle.load(project_file)
            except IOError as err:
                # TODO: I should really use some variable with the app name here
                QtGui.QMessageBox.warning(
                    self, "Hexotomy",
                    "Cannot load project %s:\n%s." % (filename, err.strerror))
                return
            except EOFError as err:
                QtGui.QMessageBox.warning(
                    self, "Hexotomy",
                    "Corrupted project file %s." % (filename))
            finally:
                project_file.close()

        self.project_file = os.path.abspath(filename)
        self.revision_tree.update()
        self.select_file(0)
        self.interpreter_table.update_interpreter()

        for i in range(0, len(self.files)):
            self.file_watch.add(self.files[i]["fullfilename"])

        print "really loaded db!"
        self.setWindowTitle("Hexotomy (%s)" % os.path.basename(filename))
        print "loaded db! " + str(self.project_file)

    def save_project(self):
        # print "trying to save project: " + self.project_file
        if self.project_file:
            try:
                project_file = open(str(self.project_file), "w+b")
                cPickle.dump(self.files, project_file)
                cPickle.dump(self.interpreter_table.interprets, project_file)
                project_file.close()
            except IOError as err:
                QtGui.QMessageBox.warning(
                    self, "Application?", "Cannot save project %s:\n%s." %
                    (self.project_file, err.strerror))
                return False
            # print "saved db!"
            return True

    def open_file(self):
        filename, _ = QtGui.QFileDialog.getOpenFileName(self)
        if filename:
            self.load_file(filename)

    def load_file(self, filename):
        rawfile = QtCore.QFile(filename)
        rawfileinfo = QtCore.QFileInfo(rawfile)
        if not rawfile.open(QtCore.QFile.ReadOnly):
            QtGui.QMessageBox.warning(
                self, "Application?", "Cannot read file %s:\n%s." %
                (filename, rawfile.errorString()))
            return

        QtGui.QApplication.setOverrideCursor(QtCore.Qt.WaitCursor)
        rawbinary = rawfile.readAll().data()
        self.files.append({
            "filename":
            rawfileinfo.fileName(),
            "timestamp":
            rawfileinfo.lastModified().toString("yyyy-MM-dd hh:mm:ss"),
            "comment":
            "",
            "fullfilename":
            rawfileinfo.canonicalFilePath(),
            "rawfile":
            rawbinary,
            "diff":
            "true"
        })
        file_index = len(self.files) - 1

        self.statusBar().showMessage("File Loaded", 2000)

        self.revision_tree.update()

        self.select_file(file_index)

        QtGui.QApplication.restoreOverrideCursor()

        self.file_watch.add(rawfileinfo.canonicalFilePath())
        # print "Currently watched files: "
        # self.file_watch.list()

    def remove_file_rightclick(self):
        # find file in files
        selected = self.revision_tree.selectedIndexes()[0]
        row = self.revision_tree.model.itemFromIndex(selected).row()

        self.remove_file(row)

    def remove_file(self, index):
        # remove filewatch
        self.file_watch.remove(self.files[index]["fullfilename"], 1)
        # statusbar message
        self.statusBar().showMessage(
            "Removed file '%s'" % self.files[index]["fullfilename"], 5000)
        # delete from files
        del self.files[index]
        # select a different file if necessary
        if self.current_file == index:
            if index < len(self.files):
                self.select_file(index)
            elif index != 0:
                self.select_file(index - 1)
            else:
                # I don't want to handle empty :(
                pass
        else:
            # current_file needs to be relocated!
            if self.current_file > index:
                self.select_file(index)
        # remove from HexRevisionTree
        self.revision_tree.update()
        # print "Currently watched files: "
        # self.file_watch.list()

    def stop_file_watch_rightclick(self):
        # find file in files
        selected = self.revision_tree.selectedIndexes()[0]
        row = self.revision_tree.model.itemFromIndex(selected).row()

        self.stop_file_watch(row)

    def stop_file_watch(self, index):
        # remove filewatch
        # print "removing file watch for %d  %s" % (index, self.files[index]["fullfilename"])
        self.file_watch.remove(self.files[index]["fullfilename"], 99999)
        # print "Currently watched files: "
        # self.file_watch.list()

    def select_file(self, index):
        if index < len(self.files):
            self.current_file = index
            # start = time.time()
            self.hex_view.set_binary(self.current_file)
            # print "hex_view.set_binary(%d): %f" % (index, time.time() - start)
            #start = time.time()
            self.inspector_table.update_inspector(
            )  # Inspector Gadget will show info at loc
            #print "inspector_table.update_inspector: %f" % (time.time() - start)
            #start = time.time()
            self.interpreter_table.update_interpreter()
            #print "interpreter_table.update_interpreter: %f" % (time.time() - start)
            self.statusBar().showMessage(
                "selected file %s" %
                self.files[self.current_file]["fullfilename"])

        else:
            print "somebody tried to call select_file(%d), but there are only %d files loaded (ok on init)" \
                  % (index, len(self.files))

    # Handle stuff
    def dragEnterEvent(self, event):
        if event.mimeData().hasUrls():
            event.acceptProposedAction()

    def dragMoveEvent(self, event):
        event.acceptProposedAction()

    def dropEvent(self, event):
        # print "got a dropEvent!"
        event.acceptProposedAction()
        # print "mime: " + str(event.mimeData().formats())
        # print "text: " + str(event.mimeData().text())
        # print "urls: " + str(event.mimeData().urls())
        # print "name: " + str(event.mimeData().data("FileName"))
        if event.mimeData().hasUrls():
            for url in event.mimeData().urls():
                # print "attempting to load: " + str(url)
                self.load_file(url.toLocalFile())

    def dragLeaveEvent(self, event):
        event.acceptProposedAction()

    def closeEvent(self, event):
        self.write_settings()
        if self.save_project():
            event.accept()
Esempio n. 9
0
class Game():
	def __init__(self, window):
		self.window = window
		self.colours = {'white' : (255, 255, 255, 0), 'outerspace': (65, 74, 76, 0) }
		pyglet.gl.glClearColor(*self.colours['outerspace'])
		
		#Load images, create batch-groups, a batch
		pyglet.resource.path = ['tiles']
		pyglet.resource.reindex()
		#self.explosion_stream = open('explosion2strip.png', 'rb')
		#self.explosion = pyglet.image.load('explosion1strip.png')
		self.hexWater = pyglet.resource.image('hex.png')
		self.hexMud = pyglet.resource.image('hexDirt.png')
		self.hexUnwalkable = pyglet.resource.image('hexUnwalkable.png')
		self.ship = pyglet.resource.image('ship.png')
		self.background = pyglet.graphics.OrderedGroup(0)
		self.foreground = pyglet.graphics.OrderedGroup(1)
		self.effectslayer = pyglet.graphics.OrderedGroup(2)
		self.cellbatch = pyglet.graphics.Batch()
		
		self.grid = Grid(12, 8)	
		
		self.hexView = HexView(self.grid, 64, 55, 17, 0, 0) #todo: something to get this centered in the screen automatically
		self.screenCoordinates = self.hexView.screenCoordinates()
		
		self.selectedCell = None
		self.phase = 1
		self.movingUnit = False #True if a unit is being moved
		self.currentFaction = "Viper"
		
		#self.exp_seq = pyglet.image.ImageGrid(self.explosion, 1, 32)
		#self.boom = pyglet.image.Animation.from_image_sequence(self.exp_seq, 0.09) 
		#self.boomsprite = pyglet.sprite.Sprite(self.boom, x=10, y=10, batch=self.cellbatch, group=self.foreground)
	
	def initializeCellSprites(self): # use iteritems and refactor this nonsense
		for cell in self.grid.CellDict.iterkeys():
			if not self.grid.CellDict[cell].walkable: self.grid.CellDict[cell].baseImg = pyglet.sprite.Sprite(self.hexUnwalkable, x=self.grid.CellDict[cell].screenCoordinates[0], y=self.grid.CellDict[cell].screenCoordinates[1], batch=self.cellbatch, group=self.background)
			else: self.grid.CellDict[cell].baseImg = pyglet.sprite.Sprite(self.hexWater, x=self.grid.CellDict[cell].screenCoordinates[0], y=self.grid.CellDict[cell].screenCoordinates[1], batch=self.cellbatch, group=self.background)
		
	
	def initializeUnits(self):
		self.grid.addUnit((3,3), pyglet.sprite.Sprite(self.ship, batch=self.cellbatch, group=self.foreground), faction = "Viper")
		self.grid.addUnit((3,4), pyglet.sprite.Sprite(self.ship, batch=self.cellbatch, group=self.foreground), faction = "Viper")
		self.grid.addUnit((5,3), pyglet.sprite.Sprite(self.ship, batch=self.cellbatch, group=self.foreground), faction = "Raider")
		self.grid.addUnit((2,3), pyglet.sprite.Sprite(self.ship, batch=self.cellbatch, group=self.foreground), faction = "Raider")
		
		
	def on_draw(self):
		glEnable(GL_BLEND) 
		glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) 
		self.window.clear()
		self.cellbatch.draw()
		#self.boomsprite.draw()
		#pyglet.clock.ClockDisplay().draw()
	
	def validCell(self, coords):
		return coords in self.grid.CellDict #Should this be here?
		
	def on_mouse_motion(self,x, y, dx, dy):
		pass

	def moveUnit(self, startCell, endCell):
		path = self.grid.findPath(startCell, endCell)
		startCell.unit.path = path
		for cell in path: print cell
		self.movingUnit = False
	
	def resolveMove(self):
		for unit in self.grid.units:
			print unit 
	
	def on_mouse_press(self, x, y, button, modifiers):
		coords = self.hexView.getClickedCell(x,y) 
		if self.validCell(coords):
			cell = self.grid.CellDict[coords]
			if not self.movingUnit and cell.unit != None:
				if cell.unit.faction == self.currentFaction:
					self.movingUnit = True
					self.currentCell = cell
					print cell.unit
					return	
					
			if self.movingUnit and cell != None:
				self.moveUnit(self.currentCell, cell)
		if button == mouse.RIGHT:
			self.resolveMove()
			
	def startGame(self):
		self.initializeCellSprites()
		self.initializeUnits()
		self.window.on_draw = self.on_draw
		self.window.on_mouse_press = self.on_mouse_press
		self.window.on_mouse_motion = self.on_mouse_motion
		#self.window.event(self.on_draw)
		#self.window.event(self.on_mouse_press)
		pyglet.app.run()