游戏辅助工具(python3+pyqt4)

danny posted @ 2014年3月21日 14:37 in python with tags python game , 2874 阅读

有个游戏,杀星很麻烦. 星的信息是从谣言频道发出的,但是谣言频道信息太多,需要提取. 星是有时效的,所以只显示最近的几十项就好.

本来不想做界面的,可是cmd实在是太丑了,而且占桌面空间,本来屏幕就小.

使用工具: python3+pyqt4

实际运行图是这样的. 

界面截图

游戏窗口是1024*768居中屏幕, 必须偏移一下辅助程序窗口,所以辅助程序窗口没有了右边框.

 

要读取的聊天记录样例

#W12:47:18#n #[#image<0>#]#W听闻#Y#<シ淡味ˇby#>#n在通天塔中大展雄风,成功完成了通天塔的所有挑战,真是实力超群啊!
#W12:47:20#n #[#image<0>#]#W听闻在#R钱塘观潮五线#n,#Y地猛星#n#R(84级)#n将在#R三分钟后#n下凡云游到#Z五龙窟四层#Z,期间星君将挑选幸运的道友进行指点,各位道友快去该地图等候吧!
#W12:47:22#n #[#image<0>#]#W财神巡游,在低等级练功区地图留下了一些宝箱,来帮助50级以下的新手玩家,大家快去拣吧!
#W12:47:22#n #[#image<0>#]#W听闻在#R钱塘观潮六线#n,#Y地猛星#n#R(84级)#n将在#R三分钟后#n下凡云游到#Z五龙窟四层#Z,期间星君将挑选幸运的道友进行指点,各位道友快去该地图等候吧!
#W12:47:24#n #[#image<0>#]#W#Y地煞星#n#R(63级)#n已经出现在#Z乾元山#Z,各位道友若有实力,可前往挑战!
#W12:47:33#n #[#image<0>#]#W听闻在#R钱塘观潮二线#n,#Y地猛星#n#R(84级)#n将在#R三分钟后#n下凡云游到#Z五龙窟三层#Z,期间星君将挑选幸运的道友进行指点,各位道友快去该地图等候吧!

程序源码

写了两个版本, 第一版本使用QTableWidget, 第二版使用QTableView

QTableWidget

#!/usr/bin/env python3
import os
import sys
import re
import stat
import datetime
from collections import OrderedDict
from itertools import islice
from PyQt4 import QtGui

class Table(QtGui.QDialog):
    def __init__(self, parent=None):
        super(Table, self).__init__(parent)
        self.setGeometry(1075, 85, 320, 640)
        self.setWindowIcon(QtGui.QIcon('.\\qt.ico'))
        layout = QtGui.QGridLayout() 
        #self.led = QtGui.QLineEdit("Sample")
        self.searchboxLayout = QtGui.QGridLayout()
        self.label1 = QtGui.QLabel("等级: 从")
        self.searchboxLayout.addWidget(self.label1, 0, 0)
        self.lineEdit_start = QtGui.QLineEdit()
        self.lineEdit_start.setText("30")
        self.searchboxLayout.addWidget(self.lineEdit_start, 0, 1)
        self.label = QtGui.QLabel("到")
        self.searchboxLayout.addWidget(self.label, 0, 2)
        self.lineEdit_end = QtGui.QLineEdit()
        self.lineEdit_end.setText("105")
        self.searchboxLayout.addWidget(self.lineEdit_end, 0, 3)
        self.btn = QtGui.QPushButton("刷新")
        self.searchboxLayout.addWidget(self.btn, 0, 4)
        layout.addLayout(self.searchboxLayout, 0, 0, 1, 1)
        self.table = QtGui.QTableWidget()
        self.table.setColumnCount(5)
        #layout.addWidget(self.led, 0, 0)
        #layout.addWidget(self.btn, 0, 0)
        #layout.addWidget(self.table, 1, 0)
        layout.addWidget(self.table, 1, 0, 1, 1)
        self.table.setHorizontalHeaderLabels(["时间","星名","等级","地点","线"])
        self.table.setColumnWidth(0, 56)
        self.table.setColumnWidth(1, 48)
        self.table.setColumnWidth(2, 30)
        self.table.setColumnWidth(3, 70)
        self.table.setColumnWidth(4, 52)
        self.show_data()
        self.btn.clicked.connect(self.show_data)
        self.setLayout(layout)
        QtGui.QShortcut(QtGui.QKeySequence("Ctrl+R"), self, self.get_data)

    def show_data(self):
        level_start = int(self.lineEdit_start.text())
        if not level_start:
            level_start = 35
        level_end = int(self.lineEdit_end.text())
        if not level_end:
            level_end= 200
        if level_start > level_end:
            level_start, level_end = level_end, level_start
        print(level_start, level_end)
        self.ct, self.server, self.myfile, self.foo = self.get_data()
        self.bar = list(filter(lambda x: level_start <= int(x[2]) <= level_end, self.foo.values()))
        self.table.setRowCount(len(self.bar))
        n = 0
        for i in self.bar:
            self.table.setItem(n, 0, QtGui.QTableWidgetItem(i[0]))
            self.table.setItem(n, 1, QtGui.QTableWidgetItem(i[1]))
            self.table.setItem(n, 2, QtGui.QTableWidgetItem(i[2]))
            self.table.setItem(n, 3, QtGui.QTableWidgetItem(i[3]))
            self.table.setItem(n, 4, QtGui.QTableWidgetItem(i[4]))
            self.table.setRowHeight(n, 21)
            n += 1
        item = self.table.item(n, 0)
        #self.table.scrollToItem(item, QtGui.QAbstractItemView.PositionAtCenter)
        #self.table.selectRow(n)
        print(n, self.ct, self.myfile, len(self.foo))
        self.setWindowTitle("%s %s" % (self.server, self.ct))

    def get_data(self):
        return main_h()


def fun(x):
    return re.findall('#W(.{2}:.{2}:.{2})#n.*image.*#W听闻在#R.{3,4}.{1,3}线#n,#Y[天地].星#n#R(\d+级)#n.*云游到#Z.*#Z', x)

def reader(myfile):
    with open(myfile, 'rb') as f:
        buf = f.read()
        ubuf = buf.decode('cp936', 'ignore')
        stars = list(filter(fun, ubuf.split('\n')))
        if len(stars) <= 60:
            last = 0
        else:
            last = -60
        return  stars[last:]

def get_info(orig):
    return re.findall('#W(.{2}:.{2}:.{2})#n.*image.*#W听闻在#R(.{3,4})(.{1,3}线)#n,#Y([天地].星)#n#R((\d+)级)#n.*云游到#Z(.*)#Z', orig)[0]

def main_h():
    path = r'D:\Program Files (x86)\asktao\chat'
    stars = OrderedDict()
    for myfile in map(lambda x: os.path.join(path, x), os.listdir(path)[-1:]):
        for m, orig in enumerate(reader(myfile)[::-1]):
            t, server, line, name, level, position = get_info(orig)
            if len(position) < 4:
                position += "    "
            #if int(level.replace('级', '')) < 105:
            stars[str(m)] = [t, name, level, position, line]
    #for k, v in stars.items():
        #print("\t".join(v))
    ct = os.stat(myfile).st_mtime + 8*3600
    ct = datetime.datetime.utcfromtimestamp(ct).strftime("%Y-%m-%d %H:%M:%S")
    return (ct, server, myfile, stars)

def main():
    import sys
    app = QtGui.QApplication(sys.argv)
    t = Table()
    t.show()
    sys.exit(app.exec_())

if __name__ == '__main__':
    main()

QTableView

 

#!/usr/bin/env python3
#coding=gbk
import os
import sys
import re
import stat
import datetime
from collections import OrderedDict
from itertools import islice
from PyQt4 import QtCore, QtGui,QtSql

class Table(QtGui.QWidget):
    def __init__(self, parent=None):
        super(Table, self).__init__(parent)
        self.db = self.conn()
        self.ct, self.server, self.myfile, self.foo = "", "", "", ""
        self.query = ""
        self.setGeometry(1070, 85, 320, 640)
        self.setWindowIcon(QtGui.QIcon('.\\qt.ico'))
        self.layout = QtGui.QGridLayout() 
        self.searchboxLayout = QtGui.QGridLayout()
        self.label1 = QtGui.QLabel("等级: 从")
        self.searchboxLayout.addWidget(self.label1, 0, 0)
        self.lineEdit_start = QtGui.QLineEdit()
        self.lineEdit_start.setText("30")
        self.searchboxLayout.addWidget(self.lineEdit_start, 0, 1)
        self.label = QtGui.QLabel("到")
        self.searchboxLayout.addWidget(self.label, 0, 2)
        self.lineEdit_end = QtGui.QLineEdit()
        self.lineEdit_end.setText("105")
        self.searchboxLayout.addWidget(self.lineEdit_end, 0, 3)
        self.btn = QtGui.QPushButton("刷新")
        self.searchboxLayout.addWidget(self.btn, 0, 4)
        self.labelnote = QtGui.QLabel("<strong>提示:</strong>")
        self.searchboxLayout.addWidget(self.labelnote, 1, 0)
        self.labelnote1 = QtGui.QLabel("先保存再刷新")
        self.searchboxLayout.addWidget(self.labelnote1, 1, 1)
        self.layout.addLayout(self.searchboxLayout, 0, 0, 1, 1)
        self.table = QtGui.QTableView()
        self.layout.addWidget(self.table, 1, 0, 1, 1)
        self.show_data()
        self.btn.clicked.connect(self.show_data)
        QtGui.QShortcut(QtGui.QKeySequence("Ctrl+R"), self, self.show_data)
        self.setLayout(self.layout)

    def conn(self):
        db = QtSql.QSqlDatabase.addDatabase("QSQLITE");
        db.setDatabaseName(":memory:")
        #db.setDatabaseName("test.db3")
        db.open()
        self.ddl(db)
        return db

    def ddl(self, db):
        self.query = QtSql.QSqlQuery(db)
        self.query.exec_("create table foo1(a1 char(255),\
                a2 char(255), a3 int, a4 char(255),\
                a5 char(255), a6 text unique)")

    def insert(self):
        self.ct, self.server, self.myfile, self.foo = self.get_data()
        self.query = QtSql.QSqlQuery(self.db)
        for k, v in self.foo.items():
            sql = "insert into foo1 values\
                    ('%s', '%s', '%s', '%s', '%s',\
                    '%s %s')" % (v[0], v[1], v[2], v[3],\
                    v[4], self.server, " ".join(v))
            self.query.exec(sql)
        self.db.commit()
            

    def select(self):
        model = QtSql.QSqlQueryModel() 
        level_start = int(self.lineEdit_start.text())
        if not level_start:
            level_start = 35
        level_end = int(self.lineEdit_end.text())
        if not level_end:
            level_end= 200
        if level_start > level_end:
            level_start, level_end = level_end, level_start
        sql = """
        select a1,a2,a3,a4,a5 from 
        foo1 where a3 >= %s and a3 <= %s order by a1 desc limit 
        30""" % (level_start, level_end)
        model.setQuery(sql, self.db)
        title = ("时间","星名","等级","地点","线")
        for n, s in enumerate(title):
            model.setHeaderData(n, QtCore.Qt.Horizontal, s)
        return model


    def show_data(self):
        self.insert()
        model = self.select()
        self.table.setModel(model)
        width = (56, 48, 30, 70, 52)
        for n, w in enumerate(width):
            self.table.setColumnWidth(n, w)
        for i in range(40):
            self.table.setRowHeight(i, 21)
        r = len(self.foo)
        self.table.selectRow(r)
        self.setWindowTitle("%s %s" % (self.server, self.ct))
        print(self.ct, self.myfile, r)

    def get_data(self):
        return main_h()


def fun(x):
    return re.findall('#W(.{2}:.{2}:.{2})#n.*image.*#W听闻在#R.{3,4}.{1,3}线#n,#Y[天地].星#n#R(\d+级)#n.*云游到#Z.*#Z', x)

def reader(myfile):
    with open(myfile, 'rb') as f:
        buf = f.read()
        ubuf = buf.decode('cp936', 'ignore')
        stars = list(filter(fun, ubuf.split('\n')))
        if len(stars) <= 60:
            last = 0
        else:
            last = -60
        return  stars[last:]

def get_info(orig):
    return re.findall('#W(.{2}:.{2}:.{2})#n.*image.*#W听闻在#R(.{3,4})(.{1,3}线)#n,#Y([天地].星)#n#R((\d+)级)#n.*云游到#Z(.*)#Z', orig)[0]

def main_h():
    path = r'D:\Program Files (x86)\asktao\chat'
    stars = OrderedDict()
    files = os.listdir(path)
    keeper = lambda x: os.path.join(path, x) if x is files[-1] else\
            os.unlink(os.path.join(path, x))
    for myfile in filter(lambda x: x, map(keeper, files)):
        for m, orig in enumerate(reader(myfile)):
            t, server, line, name, level, position = get_info(orig)
            if len(position) < 4:
                position += "    "
            stars[str(m)] = [t, name, level, position, line]
    for k, v in stars.items():
        print("\t".join(v))
    ct = os.stat(myfile).st_mtime + 8*3600
    ct = datetime.datetime.utcfromtimestamp(ct).strftime("%Y-%m-%d %H:%M:%S")
    return (ct, server, myfile, stars)

def main():
    import sys
    app = QtGui.QApplication(sys.argv)
    t = Table()
    t.show()
    sys.exit(app.exec_())

if __name__ == '__main__':
    main()

 

文本筛选,关键就是正则了, 正则能写得出来,其它都是小事了.

有些东西不想改了.像时间这种 ct = os.stat(myfile).st_mtime + 8*3600 , 一直记不住用哪个类里的方法来获取.

最近更新了wine, 那个游戏终于比较流畅地在运行了, 不过,fcitx无法输入文字, 如果是从clipboard复制, 得到的是类似"\x243"这种, 源编码呃.所以,还是windows下玩比较好了.  


登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter