DOTA2攻速计算公式研究

常见的游戏中都有属于自己的一套伤害机制,最近发现DOTA2中攻速计算公式与明日方舟中的几乎一致,因此在学习之余记录下来。

1.名词概念

在介绍计算公式前,先引入几个基本概念

基础攻击间隔BAT(Base Attack Time):最核心的数据,所有的计算都必须依赖基础攻击间隔,是一个与模型(英雄单位)有关的常量,各个英雄的攻速差异主要体现在此常量上,也是代码中设定最核心的部分。

基础攻击速度BAS(Base Attack Speed):人为设定的数据,为了建立计算公式而人为规定的常量,基础攻击速度都设定为100

攻击速度AS(Attack Speed):人为定义的概念,游戏中自己单独的定义,并没有什么现实意义

攻速提升IAS(Increased Attack Speed,IAS):一个单位通过各种途径的获得的攻击速度提升

实际)攻击间隔AT(Attack Time):一个单位进行持续攻击时,两次连续攻击中间隔的时间,也是实际游戏中玩家所能感受的表现。

攻击频率APS(Attack Per Second):一个单位进行持续攻击时,一秒内能攻击的次数,注意:区别于攻击速度

其中,
基础攻击速度+攻速提升=攻击速度
攻击间隔*攻击频率=1

2.计算公式

攻击频率(每秒攻击次数)=(基础攻击速度+攻速加成)/(基础攻击间隔*100)

攻击间隔= 1 / 攻击频率

也就是说,对于一个攻速加成为50,基础攻击间隔为1.7的英雄来说
它的攻击频率为(100+50)/(1.7*100)=0.88
攻击间隔为1/0.88=1.13

DOTA2攻击速度设定最大值为600,
至于DOTA2中的攻击速度补偿以及明日方舟中的基础攻击间隔减少在此不作讨论

3.DOTA攻击速度提升性价比研究

//TODO

from netfilterqueue import NetfilterQueue from scapy.all import IP, TCP, send, conf import subprocess import logging import threading from queue import Queue from concurrent.futures import ThreadPoolExecutor # 数据包队列 packets_queue = Queue() # 使用线程安全的队列 queue_length = 5 # 队列长度阈值 packet_send_queue = Queue() # 使用线程安全的队列 # 线程池 executor = ThreadPoolExecutor(max_workers=10) # 设置线程池大小 # 定义数据包处理函数 def process_packet(packet): print(f"拦截到一个数据包,大小:{len(packet.get_payload())}") scapy_packet = IP(packet.get_payload()) # 将数据包转换为 Scapy 对象 packets_queue.put(scapy_packet) packet.drop() # 丢弃拦截的数据包 # 处理队列中的数据包 def handle_packet_queue(): global queue_length while True: if not packets_queue.empty(): scapy_packet = packets_queue.get() # 在这里可以对 scapy_packet 进行进一步的处理 # 检查 TCP 标志 if scapy_packet.haslayer(TCP): tcp_flags = scapy_packet[TCP].flags if tcp_flags & 0x02: # SYN 标志为 1 logging.debug("SYN 标志为 1,正常发送数据包") send(scapy_packet, verbose=False) elif tcp_flags & 0x01: # FIN 标志为 1 logging.debug("FIN 标志为 1,正常发送数据包") send(scapy_packet, verbose=False) else: # 将数据包存入线程安全的队列 packet_send_queue.put(scapy_packet) # 如果队列已满队列长度阈值个数据包,则发送 if packet_send_queue.qsize() >= queue_length: send_packets() else: send(scapy_packet, verbose=False) # 按 TCP 序列号正序发送数据包 def send_packets(): logging.debug("开始发送数据包队列中的数据包") try: # 从队列中获取所有数据包 packets = [] while not packet_send_queue.empty(): packets.append(packet_send_queue.get()) # 按 TCP 序列号排序 packets.sort(key=lambda pkt: pkt[TCP].seq) # 依次发送数据包 for packet in packets: send(packet, verbose=False) except Exception as e: logging.error(f"Error sending packets: {e}") # 设置 iptables 规则 def setup_iptables(port, queue_num): logging.debug(f"设置 iptables 规则,将端口 {port} 的数据包转发到队列 {queue_num}...") try: subprocess.run([ "sudo", "iptables", "-I", "OUTPUT", "-p", "tcp", "--sport", str(port), "-j", "NFQUEUE", "--queue-num", str(queue_num) ], check=True) except subprocess.CalledProcessError as e: logging.error(f"Error setting iptables rules: {e}") # 清理 iptables 规则 def cleanup_iptables(): logging.debug("清理 iptables 规则...") try: subprocess.run(["sudo", "iptables", "-F"], check=True) except subprocess.CalledProcessError as e: logging.error(f"Error cleaning up iptables rules: {e}") # 主函数 def main(): port = 8080 # 监听的端口 queue_num = 0 # NetfilterQueue 队列编号 # 设置默认接口 conf.iface = "ens33" # 设置 iptables 规则 setup_iptables(port, queue_num) # 显式启动处理线程 threading.Thread(target=handle_packet_queue, daemon=True).start() # 创建 NetfilterQueue 对象并绑定到队列编号 nfqueue = NetfilterQueue() nfqueue.bind(queue_num, process_packet) logging.debug(f"开始监听端口 {port} 的数据包...") # 启动线程池处理队列中的数据包 executor.submit(handle_packet_queue) try: nfqueue.run() except KeyboardInterrupt: logging.debug("停止监听...") except Exception as e: logging.error(f"Error in NetfilterQueue: {e}") finally: nfqueue.unbind() cleanup_iptables() if __name__ == "__main__": main()
04-03
<think>嗯,用户给了一段Python代码,看起来是关于网络数据包处理的,用到了NetfilterQueue和Scapy库。我需要先理解这段代码的功能,然后按用户的要求进行介绍。首先,用户可能想知道这段代码的作用,以及各个部分是如何工作的。 首先,代码导入了几个重要的库:NetfilterQueue用于处理iptables队列,Scapy用来解析和发送数据包,还有threading和concurrent.futures用于多线程处理。接下来,定义了几个队列,packets_queue和packet_send_queue,可能是用来缓冲数据包的。线程池executor用来管理并发任务。 然后,process_packet函数接收数据包,转换为Scapy的IP对象,放入队列并丢弃原包。这里用户可能想实现某种流量控制或者修改数据包。handle_packet_queue函数处理队列中的数据包,检查TCP标志,如果是SYN或FIN就立即发送,其他情况则存入另一个队列,当队列达到阈值时批量发送并按序列号排序。这可能是在重新排序或延迟发送数据包,比如实现流量整形或防止某种攻击。 setup_iptables和cleanup_iptables函数用来添加和删除iptables规则,将指定端口的流量重定向到Netfilter队列。主函数main设置端口和队列号,启动处理线程,绑定NetfilterQueue并运行。遇到中断时清理iptables规则。 用户可能想了解这段代码的具体功能,比如是否是一个网络流量控制工具,或者用于数据包分析、修改。需要指出代码的结构,各模块的作用,比如多线程处理、队列管理、iptables配置。同时,代码中可能存在潜在问题,比如线程安全、异常处理、资源释放等。例如,使用全局变量queue_length可能会有并发问题,虽然用了线程安全队列,但其他变量的同步需要注意。此外,异常处理是否完善,比如send失败是否会影响程序运行。 另外,代码中handle_packet_queue被提交到线程池,同时又显式启动了一个线程,可能导致重复处理。需要指出这一点可能的问题。还有,按TCP序列号排序发送是否正确,是否会影响TCP连接的可靠性,比如乱序可能导致接收端问题。 最后,总结代码用途,可能用于流量监控、数据包延迟发送、测试网络应用在高延迟或乱序情况下的表现,或者实现某种防火墙功能。同时提醒用户注意权限问题,因为涉及iptables和NetfilterQueue需要sudo权限,以及可能的网络配置问题,比如接口名称是否正确。</think>以下是对这段代码的逐步解析和功能介绍: ### 一、代码功能概述 这是一个基于`NetfilterQueue`实现的TCP流量控制工具,主要功能: 1. 拦截指定端口(8080)的OUTPUT流量 2. 根据TCP标志进行差异化处理 3. 实现数据包的队列缓存和有序发送 4. 使用多线程架构提升处理效率 ### 二、核心组件解析 #### 1. 网络层控制 ```python from netfilterqueue import NetfilterQueue # 核心流量拦截库 from scapy.all import IP, TCP, send, conf # 数据包解析/构造库 import subprocess # 用于执行iptables命令 ``` - `NetfilterQueue`:Linux内核级数据包处理接口 - `Scapy`:提供灵活的数据包解析/构造能力 - `iptables`规则设置实现流量重定向 #### 2. 多线程架构 ```python from queue import Queue from concurrent.futures import ThreadPoolExecutor ``` - 生产者-消费者模式:`process_packet`为生产者,`handle_packet_queue`为消费者 - 双队列设计:`packets_queue`用于接收,`packet_send_queue`用于发送缓冲 - 线程池(10 worker)提升并发处理能力 #### 3. 流量处理逻辑 ```python def process_packet(packet): scapy_packet = IP(packet.get_payload()) # 原始数据包转换 packets_queue.put(scapy_packet) # 入队 packet.drop() # 丢弃原始包 ``` - 关键决策点: ```python if tcp_flags & 0x02: # SYN包立即发送 elif tcp_flags & 0x01: # FIN包立即发送 else: # 其他数据包进入发送队列 ``` - 发送队列达到阈值(5个包)后触发有序发送: ```python packets.sort(key=lambda pkt: pkt[TCP].seq) # 按TCP序列号排序 ``` ### 三、潜在问题与改进建议 #### 1. 线程安全问题 - 全局变量`queue_length`未使用线程安全保护 - 建议:使用`threading.Lock`或改为类属性封装 #### 2. 异常处理 - `send()`操作缺乏重试机制 - 建议:添加指数退避重试逻辑 #### 3. 性能优化 - 当前队列长度阈值固定为5 - 建议:实现动态调整机制(如基于网络延迟自适应) #### 4. TCP可靠性 - 强制排序可能破坏TCP协议时序 - 建议:添加序列号连续性检查 ### 四、典型应用场景 1. **网络流量分析**:实时监控特定端口的通信特征 2. **QoS控制**:实现自定义的流量整形策略 3. **安全防护**:检测异常TCP标志组合 4. **协议测试**:模拟网络延迟/乱序环境 ### 五、使用注意事项 1. 需要root权限运行(因涉及iptables和内核队列) 2. 需确保网卡名称`conf.iface = "ens33"`与实际环境一致 3. FIN包处理可能影响正常连接关闭过程 4. 发送队列积压可能导致内存压力 ### 六、扩展方向建议 1. 添加payload内容分析功能 2. 集成流量统计与可视化 3. 实现与DPI(深度包检测)的结合 4. 支持动态规则配置(如热更新过滤规则) 该代码展示了一个基于Linux内核特性的高性能网络处理框架,通过合理扩展可以发展为功能强大的网络中间件系统。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值