吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 6844|回复: 22
上一主题 下一主题
收起左侧

[Python 转载] [Python] 【Python3】教你写页游自动化Python脚本 1.界面篇(模仿某键精灵)

  [复制链接]
跳转到指定楼层
楼主
DDFer 发表于 2019-12-18 23:30 回帖奖励
本帖最后由 DDFer 于 2019-12-20 16:42 编辑

自学py写的第一个脚本
本教程为新手向


废话少说,下面开始教程
我们先用tkinter搭建好脚本的基本界面

[Python] 纯文本查看 复制代码
import tkinter as tk#[size=3]首先导入tkinter,需要事先用pip安装进python里(方法自行百度)[/size]

def init_window():
    global cs,wd
    wd = tk.Tk()
    cs = tk.Canvas(wd,
                   width = 800,
                   height = 500,
                   bg = 'white')
    wd.minsize(800, 500)   # 最小尺寸
    wd.maxsize(800, 500)#最大尺寸,使最大化失效
    wd.title('DDTHelper')
    pic = tk.PhotoImage(file="pic.png")#设置背景图片,最好是800*500和png格式的
    cs.create_image(400,250,image = pic)
    cs.pack()
    bt = tk.Button(wd,
                   text='初始化',
                   bg=('white'),
                   font=('微软雅黑',20),
                   width=155,
                   height=48,
                   command=BT_onCreat)
    bt.pack()
    cs.create_window(530,70,
                     width=155,
                     height=48,
                     window=bt)
    wd.mainloop()
def BT_onCreat():
    print("初始化。。。")
#入口,这行代码需要一直都待在脚本的最底下
#设置字典
hwnd_title = dict()
init_window()

(不过在图片上叠加控件其实有更好的方案,使控件的背景为透明的,但是那篇文章的代码运行不来)
运行效果


现在我们为点击  初始化  按钮添加一些事项
让他在被点击的时候识别当前的游戏窗口
(因为我用的是36jb大厅登录的游戏,抓取句柄的时候可以根据他的title来区别游戏窗口)
这里我偷了个懒,利用该登录器游戏窗口的title来获取



更改上面的导入库和 BT_onCreat()方法
[Python] 纯文本查看 复制代码
import win32com.client as wc,win32gui as wg,threading as xc,time,tkinter as tk,win32api as wa,win32con as wn#需要事先用pip安装pywin32插件进python里(方法自行百度)

def init_window():
    global cs,wd
    wd = tk.Tk()
    cs = tk.Canvas(wd,
                   width = 800,
                   height = 500,
                   bg = 'white')
    wd.minsize(800, 500)   # 最小尺寸
    wd.maxsize(800, 500)#最大尺寸,使最大化失效
    wd.title('DDTHelper')
    pic = tk.PhotoImage(file="pic.png")#设置背景图片,最好是800*500和png格式的
    cs.create_image(400,250,image = pic)
    cs.pack()
    bt = tk.Button(wd,
                   text='初始化',
                   bg=('white'),
                   font=('微软雅黑',20),
                   width=155,
                   height=48,
                   command=BT_onCreat)
    bt.pack()
    cs.create_window(530,70,
                     width=155,
                     height=48,
                     window=bt)
    wd.mainloop()
def BT_onCreat():
    global is_run,Znum,t1,t2,t3
    Znum = 0#当前已经登陆的游戏账号数量
    wg.EnumWindows(get_all_hwnd, 0)
    for h,t in hwnd_title.items():
        if "4399" in t:#根据title里包含的 4399 来提取游戏窗口
            hwnd = t.split("|")[3]
            name = t.split("|")[2]
            print("账号:" + name + "句柄:" + hwnd)
            Znum = Znum + 1
            hwnd = int(hwnd)#将句柄转化为int,因为句柄是从标题获取的string,导致了类型错误,我就是被这个坑了好久。。
            if Znum==1:#为每一个游戏界面创建一个单独的操作线程,为了方便用global传递,没有用exec。
                t1 = xc.Thread(target=Con,args=(hwnd,name,Znum))
            elif Znum==2:
                t2 = xc.Thread(target=Con,args=(hwnd,name,Znum))
            elif Znum==3:
                t3 = xc.Thread(target=Con,args=(hwnd,name,Znum))
            init_control(Znum,name)
#下面再添加几个方法进去
#获取句柄用的
def get_all_hwnd(hwnd,mouse):
    if wg.IsWindow(hwnd) and wg.IsWindowEnabled(hwnd) and wg.IsWindowVisible(hwnd):
        hwnd_title.update({hwnd:wg.GetWindowText(hwnd)})
#为每一个线程创建一个对应的控件来控制线程的运行
def init_control(Znum,name):
    global cs,wd,v1,v2,v3,tx1,t2,tx2,t3,tx3,txn1,txn2,txn3
    if Znum==1:
        v1=tk.IntVar()
        tx1=tk.StringVar()
        txn1=tk.StringVar()
    elif Znum==2:
        v2=tk.IntVar()
        tx2=tk.StringVar()
        txn2=tk.StringVar()
    elif Znum==3:
        v3=tk.IntVar()
        tx3=tk.StringVar()
        txn3=tk.StringVar()
    exec('tx{}.set("未运行")'.format(Znum)) 
    exec('lb{} = tk.Label(wd,text="{}",bg=("#ffffff"),font=("微软雅黑",20))'.format(Znum,name))
    exec('lbn{} = tk.Label(wd,textvariable=txn{},bg=("#ffffff"),font=("微软雅黑",10))'.format(Znum,Znum))
    exec('cb{} = tk.Checkbutton(wd,textvariable=tx{},bg=("#ffffff"),font=("微软雅黑",10),variable = v{}, height=5,width = 0,command=BT_onRun{})'.format(Znum,Znum,Znum,Znum))
    exec('cb{}.pack()'.format(Znum))
    exec('lb{}.pack()'.format(Znum))
    exec('lbn{}.pack()'.format(Znum))
    Ytmp=Znum*100
    Ytmp=Ytmp+70
    exec('cs.create_window(630,{},width=0,height=0,window=lb{})'.format(Ytmp,Znum))
    Ytmp=Ytmp+40
    exec('cs.create_window(630,{},width=35,height=25,window=lbn{})'.format(Ytmp,Znum))
    exec('cs.create_window(710,{},width=70,height=25,window=cb{})'.format(Ytmp,Znum))
#线程方法
def Con(hwnd,name,xc):
print("启动成功")
#多选框点击事件
def BT_onRun1():
    global v1,tx1,t1,ct1
    if v1.get()==1:#判断是否被选中
        ct1=0
        tx1.set('正运行')
        t1.start()
    else:
        ct1=1#用来控制线程终止
        tx1.set('未运行')  
def BT_onRun2():
    global v2,tx2,ct2
    if v2.get()==1:#判断是否被选中
        ct2=0
        tx2.set('正运行')
        t2.start()
    else:
        ct2 = 1
        tx2.set('未运行')
def BT_onRun3():
    global v3,tx3,ct3
    if v3.get()==1:#判断是否被选中
        ct3=0
        tx3.set('正运行')
        t3.start()
    else:
        ct3=1
        tx3.set('未运行')
#入口,这行代码需要一直都待在脚本的最底下
#设置字典
hwnd_title = dict()
init_window()


运行后,点击初始化的效果

可以看到,当只有一个游戏窗口的时候,脚本就自动识别出了该游戏窗口。(目前最多识别3个,且不能二次点击初始化,否则会报错。听说用exce动态封装线程时可以用dict来接收,而目前二次识别也有了大致方案)

并在勾选  未运行  旁边的   框框  时,运行对应的线程。


接下来就要到脚本的线程模块了,而有过py基础的人都知道,py的线程是没有stopThread的
但我们将要实现如何控制脚本执行游戏操作的线程,让它收放自如
下篇见
第一次写52的 帖子,排版可能不怎么好请见谅

免费评分

参与人数 8吾爱币 +8 热心值 +7 收起 理由
cengjf + 1 感谢分享,我要抓紧学起来就可以自己给自己心爱的游戏编脚本了嘻嘻
zaaqqqwenshao + 1 用心讨论,共获提升!
一杯橙汁 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
wdxm2008 + 1 + 1 用心讨论,共获提升!
bingooer + 1 + 1 谢谢@Thanks!
wushaominkk + 3 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
15777772317 + 1 + 1 谢谢@Thanks!
foxcdwapj + 1 + 1 热心回复!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

推荐
wdxm2008 发表于 2019-12-20 08:44
[Python] 纯文本查看 复制代码
#!/usr/bin/python3
# coding=utf-8

import codecs
import os
import sys
import time
import traceback
import win32con
import win32evtlog
import win32evtlogutil
import winerror
from datetime import datetime


def getAllEvents(companyId, pickUplogTypes, basePath):
    """
    """
    if not companyId:
        serverName = "未列出主机"
    else:
        serverName = companyId
    for logtype in pickUplogTypes:
        path = os.path.join(basePath, "%s_%s_日志.log" % (serverName, logtype))
        print('输出日志位置为:', path)
        getEventLogs(companyId, logtype, path)


# ----------------------------------------------------------------------
def getEventLogs(companyId, logtype, logPath):
    """
    Get the event logs from the specified machine according to the
    logtype (Example: Application) and save it to the appropriately
    named log file
    """
    print("载入%s事件" % logtype)
    log = codecs.open(logPath, encoding='utf-8', mode='w')
    line_break = '-' * 80 + '\n'
    log.write("服务器:%s 日志事件类型:%s " % (companyId, logtype))
    log.write("创建时间: %s \n" % datetime.now().strftime("%Y-%m-%d %H:%S:%M"))
    log.write(line_break)
    # 读取本机的,system系统日志
    hand = win32evtlog.OpenEventLog(None, logtype)
    # 获取system日志的总行数
    total = win32evtlog.GetNumberOfEventLogRecords(hand)
    print("%s总日志数量为%s" % (logtype, total))
    flags = win32evtlog.EVENTLOG_BACKWARDS_READ | win32evtlog.EVENTLOG_SEQUENTIAL_READ
    events = win32evtlog.ReadEventLog(hand, flags, 0)
    # 错误级别类型
    # evt_dict = {win32con.EVENTLOG_AUDIT_FAILURE: 'EVENTLOG_AUDIT_FAILURE',
    #             win32con.EVENTLOG_AUDIT_SUCCESS: 'EVENTLOG_AUDIT_SUCCESS',
    #             win32con.EVENTLOG_INFORMATION_TYPE: 'EVENTLOG_INFORMATION_TYPE',
    #             win32con.EVENTLOG_WARNING_TYPE: 'EVENTLOG_WARNING_TYPE',
    #             win32con.EVENTLOG_ERROR_TYPE: 'EVENTLOG_ERROR_TYPE'}

    evt_dict = {win32con.EVENTLOG_WARNING_TYPE: '警告',
                win32con.EVENTLOG_ERROR_TYPE: '错误',
                win32con.EVENTLOG_AUDIT_FAILURE: '审核失败',
                win32con.EVENTLOG_AUDIT_SUCCESS: '审核成功',
                win32con.EVENTLOG_INFORMATION_TYPE: '信息'
                }

    try:
        events = 1
        while events:
            events = win32evtlog.ReadEventLog(hand, flags, 0)

            for ev_obj in events:
                the_time = ev_obj.TimeGenerated.Format()  #  '12/23/99 15:54:09'
                time_obj = datetime.strptime(the_time, '%c')
                evt_id = int(winerror.HRESULT_CODE(ev_obj.EventID))
                computer = str(ev_obj.ComputerName)
                cat = ev_obj.EventCategory
                # seconds=date2sec(the_time)
                record = ev_obj.RecordNumber
                msg = win32evtlogutil.SafeFormatMessage(ev_obj, logtype)
                source = str(ev_obj.SourceName)
                nowtime = datetime.today()
                daySpace = nowtime.__sub__(time_obj).days
                if not ev_obj.EventType in evt_dict.keys():
                    evt_type = "未知"
                else:
                    evt_type = str(evt_dict[ev_obj.EventType])
                if evt_type in pickUpEventTypes and evt_id in pickUpEventIDs and daySpace <= needDaySpace:
                    log.write("计算机名:%s\n" % computer)
                    log.write("记录编码:%s\n" % record)
                    log.write("事件时间: %s\n" % time_obj)
                    log.write("事件ID:%s | 事件类别: %s\n" % (evt_id, evt_type))
                    log.write("来源: %s\n" % source)
                    log.write(msg + '\n')
                    log.write(line_break)
    except:
        print(traceback.print_exc(sys.exc_info()))

    print("日志文件创建完成:%s" % logPath)


if __name__ == "__main__":
    companyId = 1204  # None = local machine
    needDaySpace = 7  # 需要几天前的事件日志
    pickUplogTypes = ["System"]  # 目前只获取日志名称为:系统的日志
    # EventTypes = ['win32con.EVENTLOG_WARNING_TYPE', 'win32con.EVENTLOG_ERROR_TYPE',
    # 'win32con.EVENTLOG_INFORMATION_TYPE', 'win32con.EVENTLOG_AUDIT_FAILURE', 'win32con.EVENTLOG_AUDIT_SUCCESS']
    pickUpEventTypes = ['错误']  # 需要提取的类别列表
    pickUpEventIDs = [7, 8, 9, 14, 6008]  # 需要提取的事件ID列表
    # pickUplogTypes = ["System", "Application", "Security"]
    getAllEvents(companyId, pickUplogTypes, ".\\")  # todo需要修改输出位置
    # print()


推荐
wdxm2008 发表于 2019-12-20 10:32
本帖最后由 wdxm2008 于 2019-12-20 10:34 编辑
DDFer 发表于 2019-12-20 09:40
噢噢,我会尝试把所有代码打包起来,
但这样好像不利于讲解

可以一段一段的插入的
[Python] 纯文本查看 复制代码
import os

def test():


用这个标签
[Python] 纯文本查看 复制代码
 '''[mw_shl_code=python,true] /mw_shl_code]'''
沙发
goblin0427 发表于 2019-12-19 00:25
3#
Leehuajey 发表于 2019-12-19 00:46
不明觉厉,支持一下
4#
zjk414 发表于 2019-12-19 01:07
这个有点厉害了
5#
qinrongling 发表于 2019-12-19 02:02
楼主好人,楼主辛苦了(*^__^*)
6#
二又二分之一 发表于 2019-12-19 07:33
不明觉厉,楼主辛苦了
7#
老飞机 发表于 2019-12-19 07:59
做的软件可以使用吗
8#
zhangjj001 发表于 2019-12-19 08:30
收听!!!!!!!
9#
mosou 发表于 2019-12-19 08:36
这个如何引入其他dll呢 比如乐玩 大漠 或者其他
10#
so_so_so 发表于 2019-12-19 09:16
楼主辛苦了
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-26 06:12

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表