1. 为什么要在本地折腾一个英雄联盟自动化工具打英雄联盟的人多少都动过“让电脑帮我干点啥”的念头。比如秒选英雄、自动接受对局、一键查队友战绩、对局结束后自动点赞甚至把每局的详细数据拉下来做自己的胜率分析。这些需求听起来零散但背后其实指向同一个东西本地客户端接口的自动化调用。League Akari 就是围绕这个思路做出来的一套工具它不碰游戏本体也不修改内存而是通过客户端本身暴露的本地接口来读取状态、发送指令从而实现一系列自动化操作。我第一次接触这类工具的时候最直观的感受是“原来客户端自己就留了这么多口子”。英雄联盟客户端在运行时会启动一个本地 HTTP 服务通常被称为LCU APILeague Client Update API。这个服务监听在本机的一个随机端口上通过一个包含认证信息的锁文件来鉴权。任何能读到这个锁文件、拿到端口和令牌的程序都可以像客户端自己的界面一样去调用接口。League Akari 干的事情本质上就是把这套流程封装成了一个开箱即用的工具让你不用自己去解析锁文件、拼请求、处理各种状态同步。这篇文章适合几类人看。第一类是纯玩家想用现成工具提升一点操作效率比如自动接受对局、自动 ban/pick、对局后自动处理。第二类是有一定编程基础、想自己写脚本的人你需要理解 LCU API 的鉴权机制、WebSocket 事件订阅、请求构造方式。第三类是做数据记录和分析的人想把对局数据本地化留存做自己的战绩库。不管你是哪一类核心逻辑是相通的先拿到本地接口的访问权再围绕状态变化做自动化响应。需要提前说清楚的是这类工具的使用边界完全取决于你自己的判断。它读取的是客户端公开给本机的接口不涉及任何游戏内数据的篡改但自动化操作本身是否被允许取决于游戏官方的规则。我的建议是把它当成一个学习和效率工具用在合理的场景里比如自动接受对局、对局数据记录、客户端状态管理这些不直接影响竞技公平性的地方。2. League Akari 的整体设计与核心思路拆解2.1 为什么选择本地接口而不是其他方案做英雄联盟自动化市面上大致有几条路。第一条是图像识别加模拟点击靠截屏找按钮位置然后移动鼠标点击。这条路的问题是脆弱分辨率一变、界面一改、动画一卡识别就失效而且响应速度受限于截屏频率。第二条是内存读取或注入直接读游戏进程的内存数据这条路信息最全但风险也最高容易被反作弊盯上。第三条就是 League Akari 走的路线调用客户端本地接口。本地接口方案的优势很明显。首先它稳定接口是客户端自己提供的只要客户端版本不大改接口路径和返回结构基本不变。其次它信息丰富客户端界面能显示的东西接口基本都能拿到包括召唤师信息、对局状态、英雄选择、聊天消息、好友列表等等。第三是响应快通过 WebSocket 订阅事件状态一变就能收到推送不用轮询。第四是相对安全因为你没有碰游戏进程只是在和客户端自己的服务通信行为模式和客户端界面本身没有本质区别。当然它也有局限。本地接口能做的事情受限于客户端暴露了什么游戏内的实时数据比如敌方位置、技能冷却这些是拿不到的那些属于游戏进程内部的信息。所以 League Akari 这类工具的定位很清晰做客户端层面的自动化不做游戏内的辅助。理解这个边界你才不会对它有不切实际的期待。2.2 锁文件鉴权机制是怎么回事客户端启动后会在安装目录下生成一个lockfile文件。这个文件里存着四段信息用冒号分隔进程名、进程 ID、监听端口、认证令牌。格式大概是这样LeagueClient:12345:54321:abcdefghijklmnop端口是随机的每次启动都可能不同令牌也是每次启动重新生成的。所以任何工具要做的第一件事就是找到这个文件、读出来、解析出端口和令牌。拿到之后所有请求都要在 HTTP 头里带上 Basic 认证用户名固定是riot密码就是那个令牌。拼起来大概是Authorization: Basic cmlvdDphYmNkZWZnaGlqa2xtbm9w其中cmlvdDphYmNkZWZnaGlqa2xtbm9w是riot:abcdefghijklmnop的 Base64 编码。这个机制的设计意图是保证只有本机、有权限读到锁文件的程序才能调用接口外部网络是访问不到的因为服务只监听本地回环地址。League Akari 在启动时会自动定位客户端安装路径读取锁文件建立连接。如果客户端还没启动它会等待或者提示你先开客户端。这个流程看起来简单但实际做的时候有几个坑锁文件在客户端启动过程中会短暂存在但内容不完整需要重试客户端退出后锁文件可能残留需要判断进程是否真的在运行不同安装方式比如不同盘符、不同启动器路径不一样需要做路径探测。这些细节后面会展开讲。2.3 事件驱动还是轮询这是个关键选择早期很多脚本用的是轮询每隔一秒调一次接口看状态有没有变。这种方式实现简单但问题很多。一是浪费资源大部分请求都是无意义的重复。二是延迟高状态变化到被发现中间可能隔了将近一秒。三是请求量大容易触发客户端接口的频率限制。League Akari 用的是WebSocket 事件订阅。客户端本地服务提供了一个 WebSocket 端点你可以订阅各种事件主题比如对局状态变化、英雄选择阶段变化、聊天消息、好友状态等等。一旦有变化服务会主动推送消息过来。这种方式延迟低、资源占用小、逻辑也更清晰。具体来说连接 WebSocket 需要先通过 HTTPS 拿到一个订阅授权然后用返回的信息去连 WebSocket。订阅的时候要指定事件类型比如OnJsonApiEvent可以收到所有 JSON API 的变化事件也可以细化到具体路径。收到事件后根据事件类型分发处理比如收到英雄选择阶段的事件就触发自动 pick 逻辑收到对局结束事件就触发数据记录逻辑。这个设计的好处是整个工具的核心变成了一个事件处理器而不是一个定时任务。你只需要关心“当某个状态发生时我要做什么”不用关心“我怎么知道状态变了”。这也是为什么 League Akari 的响应能做得比较及时。3. 核心功能模块与实操要点解析3.1 自动接受对局最基础也最容易踩坑的功能自动接受对局是很多人用这类工具的第一个需求。逻辑听起来很简单监听对局接受事件收到就调接受接口。但实际操作里有几个细节要注意。首先是接受时机的选择。接口调用太快有时候反而会失败因为客户端界面可能还没完全准备好。实测下来收到事件后延迟 200 到 500 毫秒再调接受接口成功率最高。这个延迟不是随便定的是因为客户端在推送事件和界面就绪之间有一个短暂的时间差。其次是重复接受的处理。有时候事件会推送多次或者你手动也点了接受这时候再调接口会返回错误。所以代码里要做状态判断已经接受过了就跳过。League Akari 内部维护了一个对局状态机只有在“等待接受”状态下才会触发接受动作。第三是拒绝场景的配置。有些人希望自动接受但遇到特定情况比如秒退局、特定模式时不想接受。这就需要做条件判断比如判断对局模式、判断队友或对手信息。League Akari 提供了配置项让你决定哪些情况下自动接受、哪些情况下不动作。注意自动接受对局这个功能建议只在你自己确实会接受的场景下开启。如果开了自动接受又经常秒退反而会影响其他玩家的体验也可能触发系统的行为检测。3.2 自动 ban/pick状态机是核心英雄选择阶段的自动化比自动接受复杂得多因为它涉及多个阶段的状态流转。整个选人流程大致分为进入选人、ban 阶段、pick 阶段、交换阶段、最终确认。每个阶段客户端都会推送不同的状态你需要根据当前阶段和自己是几楼来决定做什么。League Akari 的做法是维护一个选人状态机。它订阅选人相关的所有事件每次事件到来就更新内部状态然后根据配置的优先级列表决定当前该 ban 哪个、pick 哪个。这里的关键点有几个。第一是楼层判断。你是几楼决定了你什么时候能操作。一楼先 ban 先 pick五楼最后。如果搞错了楼层可能在还不能操作的时候就去调接口导致失败。状态机里要记录自己的位置并且根据位置决定动作时机。第二是英雄优先级列表。你需要配置一个想玩的英雄列表按优先级排序。系统会依次检查首选还在不在、有没有被 ban、有没有被对面抢。如果首选没了就看次选以此类推。这个列表的配置直接决定了自动化体验的好坏。第三是预选和沟通。有些工具会自动预选英雄让队友知道你想玩什么。这个功能本身不复杂就是调预选接口但要注意预选和最终 pick 是两回事预选只是表达意向最终还是要根据实际情况 pick。第四是交换处理。选人阶段经常有人发起英雄交换如果你开了自动交换需要判断交换是否对你有利。这个逻辑因人而异有人喜欢换到高优先级英雄有人不喜欢换。League Akari 把交换做成了可配置项你可以选择自动接受、自动拒绝或者手动处理。// 选人状态处理的简化逻辑示意 function onChampSelectUpdate(state) { const myCell state.myTeam.find(p p.cellId state.localPlayerCellId); const currentAction state.actions.flat().find(a a.isInProgress); if (!currentAction) return; // 判断是否轮到我操作 if (currentAction.actorCellId ! state.localPlayerCellId) return; if (currentAction.type ban) { const banTarget pickFromPriorityList(state, myBanList); if (banTarget) banChampion(banTarget); } else if (currentAction.type pick) { const pickTarget pickFromPriorityList(state, myPickList); if (pickTarget) pickChampion(pickTarget); } }这段逻辑看起来简单但实际要处理的情况很多比如当前 action 是队友的、比如 ban 和 pick 同时存在、比如对方已经锁了你想玩的英雄。状态机要能正确处理这些边界情况。3.3 对局数据记录把每局数据本地化留存对局数据记录是另一个很实用的功能。每局打完客户端会提供本局的详细数据包括双方阵容、KDA、经济、伤害、视野等等。这些数据默认只在客户端里看过一段时间就查不到了。如果你想做长期的胜率分析、英雄池统计就需要把数据拉下来存到本地。League Akari 的做法是在对局结束时触发数据抓取把本局数据存成 JSON 或者写入本地数据库。这里的关键点在于抓取时机。对局刚结束时数据可能还没完全同步到客户端需要等几秒再抓。另外不同对局模式的数据结构可能略有差异需要做兼容处理。数据存下来之后你可以做很多事情。比如统计自己每个英雄的胜率、分析不同出装的胜率差异、记录每局的详细时间线。这些数据完全在本地不依赖任何外部服务隐私性也更好。如果你有数据分析的基础可以基于这些数据做自己的仪表盘。提示数据抓取建议做成幂等的也就是同一局不要重复记录。可以用对局 ID 作为唯一键存之前先查一下有没有存过。3.4 客户端状态管理与快捷操作除了对局相关的功能League Akari 还提供了一些客户端状态管理的功能。比如自动设置在线状态、自动回复特定消息、快速切换账号、一键整理好友列表等等。这些功能单个看起来不起眼但组合起来能省不少事。以自动回复为例你可以配置当收到特定关键词的消息时自动回复预设内容。这个功能在挂机或者忙碌的时候比较有用但要注意不要设置得太机械否则容易让人觉得你在敷衍。我的建议是只对明确的关键词做回复比如“在吗”“一起吗”这种回复内容也尽量自然。状态管理方面比较实用的是自动设置在线状态。比如你希望启动客户端后自动设为“在线”而不是“离开”或者在对局中自动设为“游戏中”。这些都可以通过接口实现逻辑不复杂但需要处理好状态切换的时机避免频繁切换。4. 从零搭建的实操过程与关键环节4.1 环境准备与依赖安装如果你打算自己实现一套类似 League Akari 的工具或者想基于它的思路做二次开发第一步是准备好开发环境。我以 Node.js 为例因为它的异步特性和 WebSocket 支持比较适合这类场景。首先确认你装了 Node.js版本建议 16 以上。然后初始化项目安装几个核心依赖npm init -y npm install axios wsaxios用来发 HTTP 请求ws用来连 WebSocket。如果你需要处理 HTTPS 的自签名证书问题可能还需要配置忽略证书验证因为客户端本地服务用的是自签名证书。const axios require(axios); const https require(https); const client axios.create({ httpsAgent: new https.Agent({ rejectUnauthorized: false }), timeout: 5000 });这里rejectUnauthorized: false是必须的因为客户端本地服务的证书不是受信任 CA 签发的。这个设置只对本地回环地址生效不会有安全问题。4.2 定位客户端与读取锁文件客户端安装路径的探测是第一个实操难点。常见的路径包括默认安装目录、WeGame 安装目录、不同盘符等。一个比较稳妥的做法是先从进程列表里找客户端进程拿到进程的可执行文件路径然后从那个路径推导出锁文件位置。在 Windows 上可以用tasklist或者wmic查进程但更可靠的方式是用 Node.js 的child_process调系统命令或者用专门的进程查询库。拿到进程路径后锁文件通常在同级的lockfile文件里。const fs require(fs); const path require(path); function readLockfile(clientPath) { const lockfilePath path.join(clientPath, lockfile); if (!fs.existsSync(lockfilePath)) return null; const content fs.readFileSync(lockfilePath, utf-8); const [processName, pid, port, token] content.split(:); return { processName, pid: parseInt(pid), port: parseInt(port), token, auth: Buffer.from(riot:${token}).toString(base64) }; }读锁文件的时候要注意客户端刚启动时文件可能还在写入内容不完整。所以要做重试隔几百毫秒读一次直到解析成功。另外客户端退出后锁文件可能还在需要判断进程是否真的存活避免连到一个已经关闭的端口。4.3 建立 WebSocket 连接与事件订阅拿到端口和令牌后先测试一下 HTTP 接口能不能通。调一个简单的接口比如查当前召唤师async function getCurrentSummoner(lock) { const res await client.get( https://127.0.0.1:${lock.port}/lol-summoner/v1/current-summoner, { headers: { Authorization: Basic ${lock.auth} } } ); return res.data; }如果这个能返回数据说明鉴权没问题。接下来建立 WebSocket 连接。WebSocket 的地址是wss://127.0.0.1:${port}/连接时同样要带上认证头。连接成功后发送订阅消息const WebSocket require(ws); function connectWebSocket(lock, onEvent) { const ws new WebSocket(wss://127.0.0.1:${lock.port}/, { headers: { Authorization: Basic ${lock.auth} }, rejectUnauthorized: false }); ws.on(open, () { // 订阅所有 JSON API 事件 ws.send(JSON.stringify([5, OnJsonApiEvent])); }); ws.on(message, (data) { const [opcode, eventName, payload] JSON.parse(data); if (opcode 8 eventName OnJsonApiEvent) { onEvent(payload); } }); return ws; }这里的[5, OnJsonApiEvent]是订阅消息的格式5 是操作码表示订阅。收到的事件里包含事件类型、路径、数据。你可以根据路径来分发处理比如路径包含champ-select就交给选人逻辑处理。4.4 核心自动化逻辑的串联把上面的部分串起来整个工具的骨架就出来了。启动流程是定位客户端、读锁文件、测试连接、建立 WebSocket、订阅事件。然后事件到来时分发到各个处理器选人事件交给选人状态机、对局事件交给对局处理器、聊天事件交给消息处理器。这里有一个实操中容易忽略的点断线重连。客户端可能会重启WebSocket 会断开锁文件会变化。所以工具要能检测到断开并重新走一遍连接流程。我的做法是监听 WebSocket 的 close 事件触发重连逻辑重连时重新读锁文件因为端口和令牌可能已经变了。另一个点是错误处理。接口调用可能因为各种原因失败比如状态不对、频率限制、客户端忙。失败后不要直接崩溃要记录日志并做适当的重试。但重试也要有上限避免无限循环。async function safeRequest(fn, retries 3) { for (let i 0; i retries; i) { try { return await fn(); } catch (err) { if (i retries - 1) throw err; await new Promise(r setTimeout(r, 500 * (i 1))); } } }这个重试逻辑在实际使用中能解决大部分偶发失败尤其是客户端刚启动或者状态切换的瞬间。5. 常见问题与排查技巧实录5.1 连接类问题排查连接类问题是最常见的表现是工具启动后连不上客户端或者连上了但很快断开。排查思路可以按下面的顺序来。现象可能原因排查方法找不到锁文件客户端未启动或路径探测错误确认客户端在运行手动检查安装目录下是否有 lockfile锁文件解析失败文件内容不完整或格式异常打印文件内容确认是否为四段冒号分隔接口返回 401令牌错误或过期重新读锁文件确认令牌是最新的接口返回 404接口路径错误或客户端版本不匹配确认接口路径拼写检查客户端版本WebSocket 连不上认证头缺失或证书问题确认带了 Authorization 头确认忽略了证书验证连接后频繁断开客户端重启或网络代理干扰检查客户端是否稳定运行检查系统代理设置这里特别说一下代理的问题。如果系统开了代理本地回环地址的请求有时候会被代理拦截导致连接失败。解决办法是在代理设置里把127.0.0.1和localhost加入例外或者直接在代码里指定不走代理。5.2 功能类问题排查功能类问题是指连接正常但某个功能不工作。比如自动接受不触发、自动 pick 不执行、数据记录不完整。自动接受不触发首先要确认事件有没有收到。可以在事件处理里打日志看对局接受事件有没有推送过来。如果事件收到了但没动作检查状态判断逻辑是不是太严格比如要求的状态和实际状态不匹配。如果事件都没收到检查订阅是否成功有时候订阅消息发早了WebSocket 还没完全就绪。自动 pick 不执行最常见的原因是楼层判断错误或者优先级列表为空。先确认当前是不是轮到你操作再看优先级列表里的英雄是不是都被 ban 了或者被抢了。还有一个容易忽略的点是选人阶段的操作有超时限制如果逻辑处理太慢可能还没调接口操作时间就过了。数据记录不完整通常是因为抓取时机太早数据还没同步完。可以延迟几秒再抓或者监听特定的对局结束事件等事件到了再抓。另外要注意不同模式的数据结构差异做好字段兼容。5.3 稳定性与性能优化工具跑久了可能会遇到内存增长、响应变慢的问题。这通常是因为事件监听没有正确清理或者日志无限增长。我的做法是给日志加滚动只保留最近若干条事件监听器在不需要的时候及时移除定期检查 WebSocket 状态不健康就重连。性能方面主要是避免不必要的接口调用。比如状态没变就不要重复请求事件里已经带了数据就不要再去调接口查一遍。另外多个功能模块之间要共享状态避免各自维护一份导致不一致。实操心得我习惯在工具里加一个调试面板实时显示当前连接状态、最近收到的事件、最近调用的接口。出问题的时候看一眼面板基本就能定位比翻日志快得多。5.4 版本兼容性注意事项客户端会不定期更新接口可能会有变化。虽然大部分核心接口比较稳定但偶尔也会有路径调整或者字段增减。应对的办法是不要硬编码太多接口细节把接口路径和字段访问做成配置或者封装关注客户端的更新公告出问题先确认是不是版本更新导致的。另外不同服务器区域的客户端版本可能有差异接口行为也可能略有不同。如果你做的工具要给不同区域的用户用需要做兼容测试。这一点在开发初期就要考虑不然后期改起来很麻烦。6. 一些实际使用中的经验与建议用这类工具时间长了会慢慢形成自己的一套使用习惯。我自己的体会是自动化要适度不要什么都交给工具。比如自动接受对局确实方便但如果你经常需要根据情况决定接不接受那自动接受反而添乱。自动 pick 也是如果你英雄池很深、喜欢根据阵容灵活选那固定优先级列表就不太适合你。数据记录这块我建议从一开始就做好数据规范。比如统一用对局 ID 作为主键、统一时间格式、统一字段命名。这样后期做分析的时候不用再清洗数据。存的时候可以用 SQLite轻量又方便查询比纯 JSON 文件好用。还有一点是关于配置管理。工具用久了配置会越来越多建议把配置集中管理支持导入导出。这样换电脑或者重装的时候不用重新配一遍。配置里涉及个人偏好的部分比如英雄优先级、自动回复内容可以单独存一份方便分享给朋友。最后说一个容易被忽略的点日志。很多人不重视日志出了问题才后悔没记。我的建议是从一开始就把关键操作都记下来包括连接状态变化、接口调用、事件处理、错误信息。日志不用太详细但关键节点要有。这样出问题的时候能快速回溯也能帮你发现一些平时注意不到的模式比如某个功能经常失败、某个接口经常超时。这套东西说到底就是一个本地客户端接口的封装和自动化调度技术难度不算高但细节很多。把连接稳定性、状态机逻辑、错误处理这几块做扎实基本就能稳定运行了。剩下的就是根据自己的需求慢慢加功能用得越久越顺手。
企业数字化 ERP 产品动态
相关推荐
用模板体系驯服Claude Code:从上下文混乱到团队规范化 写模板这事,得从一次特别狼狈的经历说起。那时候我刚把一个中型项目塞给 Claude Code 做重构,结果发现每天早上一开工,光是把项目背景、技术栈约束、目录结构、编码偏好这些上下文重新交代一遍,就得花掉十几分钟。更要命的是&… · 2026/9/26 13:53:20
Claude Code Plan模式详解:先规划再执行,让AI编程更可靠 带过的几个项目里,AI 编程助手换了一轮又一轮,最后留在工作流里的只有 Claud Code。不是因为它写代码快,而是因为它终于把"复杂任务"这件事处理得像个人了。尤其是它的Plan 模式,英文叫 Plan Mode,翻译过来就… · 2026/9/26 13:53:14
基于C语言与MySQL的超市管理系统数据库课程设计全流程实战 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/26 15:34:27
董事会关键绩效指标体系设计与战略目标实现路径分析 在现代企业治理中,董事会的绩效考核指标(KPI)是评估战略执行和管理效果的重要工具。这些指标不仅能够帮助董事会衡量公司运营的健康状况,还为未来的战略决策提供重要依据。通过合理的KPI设置,企业可以精准地评估财务表现、战略目标实现度以及董事会的工作效率。
这篇文章… · 2026/9/26 15:34:15
总经办关键绩效指标构建与企业运营管理效能提升实践 在现代企业中,确保各项工作高效且按时完成是提高运营效率的关键。为了有效评估和优化管理流程,许多公司通过设定和衡量一系列关键绩效指标(KPI)来确保各项任务按计划进行。
本文将深入分析一些典型的KPI指标,并结合数据分析和机器学习技术,展示如何通过对部门工作计划、… · 2026/9/26 15:34:15
总经理绩效考核量表设计与全面经营能力提升策略 在当今竞争激烈的商业环境中,财务健康是衡量企业成功与否的关键因素之一。净资产回报率、主营业务收入、利润额等财务类指标,能够全面反映企业的经营状况和未来发展潜力。为了帮助企业领导层进行更有效的决策,理解这些关键指标背后的含义至关重要。
在本文中将对各类财务指… · 2026/9/26 15:34:15
图片众包标注平台实战:数据库设计、质量聚合与动态定价 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/26 15:34:09
数据库课后习题答案别硬背:当测试用例集刷,效率翻倍 简介:万常选版《数据库原理与设计》课后习题答案资源,覆盖第2至6章及第9章,适合正在学习关系模型、数据库建模、关系数据理论与模式求精的本科生、自学者作为复习与自测材料。压缩包共7个文件,含3个doc参考答案、2个sql示例脚本、… · 2026/9/26 0:00:21
OpenClaw 替代品?Hermes Agent 踩坑实录:macOS 飞书接入 TaoToken 配置 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/26 0:00:40
向下兼容与向上兼容:接口设计中的兼容性策略与工程实践 一次版本升级事故,是很多团队绕不过去的坎。线上环境里,服务端明明已经上线了新版接口,老的移动端还在照着旧文档传参数。请求一到网关,校验直接拒绝,用户操作失败,客服群炸了锅,开发群里开始互… · 2026/9/26 0:00:46